From 9545daea6e3aa2fc32198ade7d42a559e4d8dd8a Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 16:24:00 +0100 Subject: [PATCH 01/18] Allow to set filter status on address blocklist --- miner/currency_blocklist.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/miner/currency_blocklist.go b/miner/currency_blocklist.go index 4081a2eb81..f92b5a841d 100644 --- a/miner/currency_blocklist.go +++ b/miner/currency_blocklist.go @@ -2,6 +2,7 @@ package miner import ( "sync" + "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -18,14 +19,30 @@ type AddressBlocklist struct { // will get evicted when evict() is called headerEvictionTimeoutSeconds uint64 oldestHeader *types.Header + + enactFilterEnabled *atomic.Int32 } func NewAddressBlocklist() *AddressBlocklist { - return &AddressBlocklist{ + + bl := &AddressBlocklist{ mux: &sync.RWMutex{}, currencies: map[common.Address]*types.Header{}, headerEvictionTimeoutSeconds: EvictionTimeoutSeconds, oldestHeader: nil, + enactFilterEnabled: &atomic.Int32{}, + } + bl.enactFilterEnabled.Store(1) + return bl +} + +// This only activates / deactivates wether the +// allowlist is filtered by the blocklist or not. +func (b *AddressBlocklist) SetEnableFilterStatus(enabled bool) { + if enabled { + b.enactFilterEnabled.Store(1) + } else { + b.enactFilterEnabled.Store(0) } } @@ -33,6 +50,10 @@ func (b *AddressBlocklist) FilterAllowlist(allowlist common.AddressSet, latest * b.mux.RLock() defer b.mux.RUnlock() + if b.enactFilterEnabled.Load() == 0 { + return allowlist + } + filtered := common.AddressSet{} for a := range allowlist { if !b.isBlocked(a, latest) { From 16276fc6a9cec22f0f7ee210936569b05046fbd2 Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:57:31 +0100 Subject: [PATCH 02/18] Add setter for currency blocklist filter status --- miner/miner.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/miner/miner.go b/miner/miner.go index 080000a530..3630f1f2f0 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -231,6 +231,12 @@ func (miner *Miner) getPending() *newPayloadResult { return ret } +func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { + if miner.feeCurrencyBlocklist != nil { + miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) + } +} + func (miner *Miner) Close() { miner.lifeCtxCancel() } From 1143d87815fec2c625aa9217a2d55947a587980d Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 14:34:49 +0000 Subject: [PATCH 03/18] Add rpc call to enable/disable the fee currency blocklist --- eth/api_admin.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/eth/api_admin.go b/eth/api_admin.go index 4a3ccb84e8..905738a239 100644 --- a/eth/api_admin.go +++ b/eth/api_admin.go @@ -141,3 +141,8 @@ func (api *AdminAPI) ImportChain(file string) (bool, error) { } return true, nil } + +// ImportChain imports a blockchain from a local file. +func (api *AdminAPI) SetfeeCurrencyBlocklistStatus(enabled bool) { + api.eth.Miner().SetFeeCurrencyBlocklistStatus(enabled) +} From c20186a8acf776ee58dd29c638d8269323c38113 Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 16:28:21 +0100 Subject: [PATCH 04/18] Fix camelcase in admin api method --- eth/api_admin.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eth/api_admin.go b/eth/api_admin.go index 905738a239..893b93621e 100644 --- a/eth/api_admin.go +++ b/eth/api_admin.go @@ -142,7 +142,6 @@ func (api *AdminAPI) ImportChain(file string) (bool, error) { return true, nil } -// ImportChain imports a blockchain from a local file. -func (api *AdminAPI) SetfeeCurrencyBlocklistStatus(enabled bool) { +func (api *AdminAPI) SetFeeCurrencyBlocklistStatus(enabled bool) { api.eth.Miner().SetFeeCurrencyBlocklistStatus(enabled) } From 750cf728d4905776bb555734bbf2a27f5cc740b0 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 15:31:22 +0000 Subject: [PATCH 05/18] Add tx ringbuffer --- miner/tx_ringbuffer.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 miner/tx_ringbuffer.go diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go new file mode 100644 index 0000000000..4bfdc2a052 --- /dev/null +++ b/miner/tx_ringbuffer.go @@ -0,0 +1,42 @@ +package miner + +import "github.com/ethereum/go-ethereum/common" + +// TxRingBuffer is a ring buffer of transaction hashes, it has one method to add +// transaction hashes and another method to check if a transaction hash is in the buffer. +type TxRingBuffer struct { + ring []common.Hash + m map[common.Hash]struct{} + index int +} + +// NewTxRingBuffer creates a new transaction ring buffer with the given size. +func NewTxRingBuffer(size int) *TxRingBuffer { + return &TxRingBuffer{ + ring: make([]common.Hash, size), + m: make(map[common.Hash]struct{}), + } +} + +// Add adds a new transaction hash to the ring buffer, if the buffer is +// at capacity, the oldest transaction hash is overwritten. +func (b *TxRingBuffer) Add(tx common.Hash) { + // Clean up old transaction hash from map + oldHash := b.ring[b.index] + delete(b.m, oldHash) + + // Add new transaction hash to ring and map + b.ring[b.index] = tx + b.m[tx] = struct{}{} + + // Increment the index + b.index++ + if b.index == len(b.ring) { + b.index = 0 + } +} + +func (b *TxRingBuffer) Has(tx common.Hash) bool { + _, exists := b.m[tx] + return exists +} From 8227088b5cf8556497df9f07f76d4f66536274fd Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:12:55 +0100 Subject: [PATCH 06/18] Fix invalidating currency gas-pool when blocking disabled --- miner/currency_blocklist.go | 5 ++++- miner/worker.go | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/miner/currency_blocklist.go b/miner/currency_blocklist.go index f92b5a841d..06a035681a 100644 --- a/miner/currency_blocklist.go +++ b/miner/currency_blocklist.go @@ -24,7 +24,6 @@ type AddressBlocklist struct { } func NewAddressBlocklist() *AddressBlocklist { - bl := &AddressBlocklist{ mux: &sync.RWMutex{}, currencies: map[common.Address]*types.Header{}, @@ -36,6 +35,10 @@ func NewAddressBlocklist() *AddressBlocklist { return bl } +func (b *AddressBlocklist) GetEnableFilterStatus() bool { + return b.enactFilterEnabled.Load() == 1 +} + // This only activates / deactivates wether the // allowlist is filtered by the blocklist or not. func (b *AddressBlocklist) SetEnableFilterStatus(enabled bool) { diff --git a/miner/worker.go b/miner/worker.go index 2515c99c1a..90a4dec139 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -87,6 +87,7 @@ type environment struct { // Celo specific multiGasPool *core.MultiGasPool // available per-fee-currency gas used to pack transactions feeCurrencyAllowlist common.AddressSet + blockingAllowed bool feeCurrencyContext *common.FeeCurrencyContext } @@ -345,6 +346,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir common.CurrencyAllowlist(env.feeCurrencyContext.ExchangeRates), header, ) + env.blockingAllowed = miner.feeCurrencyBlocklist.GetEnableFilterStatus() if header.ParentBeaconRoot != nil { core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, env.evm) @@ -838,8 +840,10 @@ func (miner *Miner) blockFeeCurrency(env *environment, feeCurrency common.Addres // the fee-currency is still in the allowlist of this environment, // so set the fee-currency block gas limit to 0 to prevent other // transactions. - pool := env.multiGasPool.PoolFor(&feeCurrency) - pool.SetGas(0) + if env.blockingAllowed { + pool := env.multiGasPool.PoolFor(&feeCurrency) + pool.SetGas(0) + } // also add the fee-currency to a worker-wide blocklist, // so that they are not allowlisted in the following blocks // (only locally in the txpool, not consensus-critical) From 08aa267aac4f5ade9c275a64229bac7ea34c25b7 Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:23:52 +0100 Subject: [PATCH 07/18] Add RW mutex to tx-ringbuffer --- miner/tx_ringbuffer.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index 4bfdc2a052..eb02662d20 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -1,6 +1,10 @@ package miner -import "github.com/ethereum/go-ethereum/common" +import ( + "sync" + + "github.com/ethereum/go-ethereum/common" +) // TxRingBuffer is a ring buffer of transaction hashes, it has one method to add // transaction hashes and another method to check if a transaction hash is in the buffer. @@ -8,6 +12,7 @@ type TxRingBuffer struct { ring []common.Hash m map[common.Hash]struct{} index int + mux *sync.RWMutex } // NewTxRingBuffer creates a new transaction ring buffer with the given size. @@ -15,12 +20,16 @@ func NewTxRingBuffer(size int) *TxRingBuffer { return &TxRingBuffer{ ring: make([]common.Hash, size), m: make(map[common.Hash]struct{}), + mux: &sync.RWMutex{}, } } // Add adds a new transaction hash to the ring buffer, if the buffer is // at capacity, the oldest transaction hash is overwritten. func (b *TxRingBuffer) Add(tx common.Hash) { + b.mux.Lock() + defer b.mux.Unlock() + // Clean up old transaction hash from map oldHash := b.ring[b.index] delete(b.m, oldHash) @@ -37,6 +46,9 @@ func (b *TxRingBuffer) Add(tx common.Hash) { } func (b *TxRingBuffer) Has(tx common.Hash) bool { + b.mux.RLock() + defer b.mux.RUnlock() + _, exists := b.m[tx] return exists } From 732a5394d6a695aaff00f2dac2d5804ec31a15ab Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:29:14 +0100 Subject: [PATCH 08/18] Fix adding tx to ringbuffer multiple times --- miner/tx_ringbuffer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index eb02662d20..4d7f35c7ed 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -30,6 +30,10 @@ func (b *TxRingBuffer) Add(tx common.Hash) { b.mux.Lock() defer b.mux.Unlock() + if _, exists := b.m[tx]; exists == true { + return + } + // Clean up old transaction hash from map oldHash := b.ring[b.index] delete(b.m, oldHash) From 840824b9f673cf901d2943feba2aa5a65c61a801 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 16:30:35 +0000 Subject: [PATCH 09/18] Connect transaction blocking --- miner/miner.go | 2 ++ miner/worker.go | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/miner/miner.go b/miner/miner.go index 3630f1f2f0..3e301398ab 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -103,6 +103,7 @@ type Miner struct { lifeCtxCancel context.CancelFunc lifeCtx context.Context + blockedTxRingbuffer *TxRingBuffer feeCurrencyBlocklist *AddressBlocklist } @@ -121,6 +122,7 @@ func New(eth Backend, config Config, engine consensus.Engine) *Miner { lifeCtxCancel: cancel, lifeCtx: ctx, + blockedTxRingbuffer: NewTxRingBuffer(100000), feeCurrencyBlocklist: NewAddressBlocklist(), } } diff --git a/miner/worker.go b/miner/worker.go index 90a4dec139..5567ae9520 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -420,13 +420,14 @@ func (miner *Miner) commitTransaction(env *environment, tx *types.Transaction) e receipt, err := miner.applyTransaction(env, tx) if err != nil { if errors.Is(err, contracts.ErrFeeCurrencyEVMCall) { + log.Warn( "fee-currency EVM execution error, temporarily blocking fee-currency in local txpools", "tx-hash", tx.Hash(), "fee-currency", tx.FeeCurrency(), "error", err.Error(), ) - miner.blockFeeCurrency(env, *tx.FeeCurrency(), err) + miner.registerFeeCurrencyTxFailure(env, tx, err) } return err } @@ -598,6 +599,12 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran continue } } + if miner.blockedTxRingbuffer.Has(ltx.Hash) { + log.Trace("Skipping tx execution, tx in blockedTxRingbuffer", "hash", ltx.Hash) + txs.Pop() + continue + } + // If we don't have enough space for the next transaction, skip the account. if env.gasPool.Gas() < ltx.Gas { log.Trace("Not enough gas left for transaction", "hash", ltx.Hash, "left", env.gasPool.Gas(), "needed", ltx.Gas) @@ -836,16 +843,19 @@ func (miner *Miner) validateParams(genParams *generateParams) (time.Duration, er return time.Duration(blockTime) * time.Second, nil } -func (miner *Miner) blockFeeCurrency(env *environment, feeCurrency common.Address, err error) { +func (miner *Miner) registerFeeCurrencyTxFailure(env *environment, tx *types.Transaction, err error) { // the fee-currency is still in the allowlist of this environment, // so set the fee-currency block gas limit to 0 to prevent other // transactions. if env.blockingAllowed { - pool := env.multiGasPool.PoolFor(&feeCurrency) + pool := env.multiGasPool.PoolFor(tx.FeeCurrency()) pool.SetGas(0) } // also add the fee-currency to a worker-wide blocklist, // so that they are not allowlisted in the following blocks // (only locally in the txpool, not consensus-critical) - miner.feeCurrencyBlocklist.Add(feeCurrency, *env.header) + miner.feeCurrencyBlocklist.Add(*tx.FeeCurrency(), *env.header) + + // Add tx to block tx ringbuffer + miner.blockedTxRingbuffer.Add(tx.Hash()) } From 5fc396717c883a693e010688314c50e5db196ad6 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 16:34:42 +0000 Subject: [PATCH 10/18] Add admin methods --- eth/api_admin.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/eth/api_admin.go b/eth/api_admin.go index 893b93621e..49caac5904 100644 --- a/eth/api_admin.go +++ b/eth/api_admin.go @@ -24,6 +24,7 @@ import ( "os" "strings" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" @@ -145,3 +146,11 @@ func (api *AdminAPI) ImportChain(file string) (bool, error) { func (api *AdminAPI) SetFeeCurrencyBlocklistStatus(enabled bool) { api.eth.Miner().SetFeeCurrencyBlocklistStatus(enabled) } + +func (api *AdminAPI) UnblockTransaction(hash common.Hash) { + api.eth.Miner().UnblockTransaction(hash) +} + +func (api *AdminAPI) UnblockFeeCurrency(address common.Address) { + api.eth.Miner().UnblockFeeCurrency(address) +} From 0f1f5ddef2c2d934ced2230d72cd747592fcede6 Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:34:53 +0100 Subject: [PATCH 11/18] Add unblock-fee currency method to miner --- miner/miner.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/miner/miner.go b/miner/miner.go index 3e301398ab..0277b8ddf2 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -238,6 +238,11 @@ func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) } } +func (miner *Miner) UnblockFeeCurrency(address common.Address) { + if miner.feeCurrencyBlocklist != nil { + _ = miner.feeCurrencyBlocklist.Remove(address) + } +} func (miner *Miner) Close() { miner.lifeCtxCancel() From ad2280952216964501f261c34c44fe26dc1af5b3 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 16:37:49 +0000 Subject: [PATCH 12/18] Add unblock transaction --- miner/miner.go | 4 ++++ miner/tx_ringbuffer.go | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/miner/miner.go b/miner/miner.go index 0277b8ddf2..d9de435b95 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -244,6 +244,10 @@ func (miner *Miner) UnblockFeeCurrency(address common.Address) { } } +func (miner *Miner) UnblockTransaction(hash common.Hash) { + miner.blockedTxRingbuffer.Remove(hash) +} + func (miner *Miner) Close() { miner.lifeCtxCancel() } diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index 4d7f35c7ed..5408e66d5a 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -56,3 +56,10 @@ func (b *TxRingBuffer) Has(tx common.Hash) bool { _, exists := b.m[tx] return exists } + +func (b *TxRingBuffer) Remove(tx common.Hash) { + b.mux.RLock() + defer b.mux.RUnlock() + + delete(b.m, tx) +} From 1fcc294029b198ee8b10158a7064c6b48c5b3513 Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:41:40 +0100 Subject: [PATCH 13/18] Remove nil check in fee-currency-blocklist setter We want to be verbose when the API handler fails, since the blocklist is assumed to not be nil --- miner/miner.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/miner/miner.go b/miner/miner.go index d9de435b95..bad1afb60a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -234,14 +234,10 @@ func (miner *Miner) getPending() *newPayloadResult { } func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { - if miner.feeCurrencyBlocklist != nil { - miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) - } + miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) } func (miner *Miner) UnblockFeeCurrency(address common.Address) { - if miner.feeCurrencyBlocklist != nil { - _ = miner.feeCurrencyBlocklist.Remove(address) - } + _ = miner.feeCurrencyBlocklist.Remove(address) } func (miner *Miner) UnblockTransaction(hash common.Hash) { From ed193d8bb974aa2e4ae5c77279eaea1550b866ff Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:45:41 +0100 Subject: [PATCH 14/18] Use atomic.Bool in address-blocklist --- miner/currency_blocklist.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/miner/currency_blocklist.go b/miner/currency_blocklist.go index 06a035681a..fed1ce0af5 100644 --- a/miner/currency_blocklist.go +++ b/miner/currency_blocklist.go @@ -20,7 +20,7 @@ type AddressBlocklist struct { headerEvictionTimeoutSeconds uint64 oldestHeader *types.Header - enactFilterEnabled *atomic.Int32 + enactFilterEnabled *atomic.Bool } func NewAddressBlocklist() *AddressBlocklist { @@ -29,31 +29,27 @@ func NewAddressBlocklist() *AddressBlocklist { currencies: map[common.Address]*types.Header{}, headerEvictionTimeoutSeconds: EvictionTimeoutSeconds, oldestHeader: nil, - enactFilterEnabled: &atomic.Int32{}, + enactFilterEnabled: &atomic.Bool{}, } - bl.enactFilterEnabled.Store(1) + bl.enactFilterEnabled.Store(true) return bl } func (b *AddressBlocklist) GetEnableFilterStatus() bool { - return b.enactFilterEnabled.Load() == 1 + return b.enactFilterEnabled.Load() } // This only activates / deactivates wether the // allowlist is filtered by the blocklist or not. func (b *AddressBlocklist) SetEnableFilterStatus(enabled bool) { - if enabled { - b.enactFilterEnabled.Store(1) - } else { - b.enactFilterEnabled.Store(0) - } + b.enactFilterEnabled.Store(enabled) } func (b *AddressBlocklist) FilterAllowlist(allowlist common.AddressSet, latest *types.Header) common.AddressSet { b.mux.RLock() defer b.mux.RUnlock() - if b.enactFilterEnabled.Load() == 0 { + if !b.enactFilterEnabled.Load() { return allowlist } From f2b577b3b36b2dbb11589e8ff2fbfe4b83838f87 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 16:50:26 +0000 Subject: [PATCH 15/18] Fix ringbuffer remove locking --- miner/tx_ringbuffer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index 5408e66d5a..75233b3e87 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -58,8 +58,8 @@ func (b *TxRingBuffer) Has(tx common.Hash) bool { } func (b *TxRingBuffer) Remove(tx common.Hash) { - b.mux.RLock() - defer b.mux.RUnlock() + b.mux.Lock() + defer b.mux.Unlock() delete(b.m, tx) } From 30da0476e14dcc116f5b27efcf8f096d2c1e7741 Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Thu, 27 Mar 2025 16:53:29 +0000 Subject: [PATCH 16/18] Return bool to indicate whether removal actions had any effect --- eth/api_admin.go | 8 ++++---- miner/miner.go | 8 ++++---- miner/tx_ringbuffer.go | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/eth/api_admin.go b/eth/api_admin.go index 49caac5904..576780bd58 100644 --- a/eth/api_admin.go +++ b/eth/api_admin.go @@ -147,10 +147,10 @@ func (api *AdminAPI) SetFeeCurrencyBlocklistStatus(enabled bool) { api.eth.Miner().SetFeeCurrencyBlocklistStatus(enabled) } -func (api *AdminAPI) UnblockTransaction(hash common.Hash) { - api.eth.Miner().UnblockTransaction(hash) +func (api *AdminAPI) UnblockTransaction(hash common.Hash) bool { + return api.eth.Miner().UnblockTransaction(hash) } -func (api *AdminAPI) UnblockFeeCurrency(address common.Address) { - api.eth.Miner().UnblockFeeCurrency(address) +func (api *AdminAPI) UnblockFeeCurrency(address common.Address) bool { + return api.eth.Miner().UnblockFeeCurrency(address) } diff --git a/miner/miner.go b/miner/miner.go index bad1afb60a..1c11efe8d3 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -236,12 +236,12 @@ func (miner *Miner) getPending() *newPayloadResult { func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) } -func (miner *Miner) UnblockFeeCurrency(address common.Address) { - _ = miner.feeCurrencyBlocklist.Remove(address) +func (miner *Miner) UnblockFeeCurrency(address common.Address) bool { + return miner.feeCurrencyBlocklist.Remove(address) } -func (miner *Miner) UnblockTransaction(hash common.Hash) { - miner.blockedTxRingbuffer.Remove(hash) +func (miner *Miner) UnblockTransaction(hash common.Hash) bool { + return miner.blockedTxRingbuffer.Remove(hash) } func (miner *Miner) Close() { diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index 75233b3e87..4184ee406a 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -57,9 +57,13 @@ func (b *TxRingBuffer) Has(tx common.Hash) bool { return exists } -func (b *TxRingBuffer) Remove(tx common.Hash) { +func (b *TxRingBuffer) Remove(tx common.Hash) bool { b.mux.Lock() defer b.mux.Unlock() + if _, exists := b.m[tx]; !exists { + return false + } delete(b.m, tx) + return true } From 431589cbf1e1aef1903e71feb50604fcabfcd6f3 Mon Sep 17 00:00:00 2001 From: piersy Date: Fri, 28 Mar 2025 11:50:16 +0000 Subject: [PATCH 17/18] Update miner/miner.go Co-authored-by: Seola Oh --- miner/miner.go | 1 + 1 file changed, 1 insertion(+) diff --git a/miner/miner.go b/miner/miner.go index 1c11efe8d3..2ff7396554 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -236,6 +236,7 @@ func (miner *Miner) getPending() *newPayloadResult { func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { miner.feeCurrencyBlocklist.SetEnableFilterStatus(enabled) } + func (miner *Miner) UnblockFeeCurrency(address common.Address) bool { return miner.feeCurrencyBlocklist.Remove(address) } From 4e2425a2f28a6650e7a78c300a9d4f568ec438ea Mon Sep 17 00:00:00 2001 From: Maximilian Langenfeld <15726643+ezdac@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:33:53 +0200 Subject: [PATCH 18/18] Add metrics-counter to blocklists --- miner/currency_blocklist.go | 4 +++- miner/miner.go | 12 ++++++++++-- miner/tx_ringbuffer.go | 7 ++++--- miner/worker.go | 12 ++++++++++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/miner/currency_blocklist.go b/miner/currency_blocklist.go index fed1ce0af5..9f0b57e279 100644 --- a/miner/currency_blocklist.go +++ b/miner/currency_blocklist.go @@ -84,14 +84,16 @@ func (b *AddressBlocklist) Remove(currency common.Address) bool { return ok } -func (b *AddressBlocklist) Add(currency common.Address, head types.Header) { +func (b *AddressBlocklist) Add(currency common.Address, head types.Header) bool { b.mux.Lock() defer b.mux.Unlock() + _, existed := b.currencies[currency] if b.oldestHeader == nil || b.oldestHeader.Time > head.Time { b.oldestHeader = &head } b.currencies[currency] = &head + return !existed } func (b *AddressBlocklist) Evict(latest *types.Header) []common.Address { diff --git a/miner/miner.go b/miner/miner.go index 2ff7396554..c88ae78de8 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -238,11 +238,19 @@ func (miner *Miner) SetFeeCurrencyBlocklistStatus(enabled bool) { } func (miner *Miner) UnblockFeeCurrency(address common.Address) bool { - return miner.feeCurrencyBlocklist.Remove(address) + removed := miner.feeCurrencyBlocklist.Remove(address) + if removed { + feeCurrenciesInBlocklistCounter.Dec(1) + } + return removed } func (miner *Miner) UnblockTransaction(hash common.Hash) bool { - return miner.blockedTxRingbuffer.Remove(hash) + removed := miner.blockedTxRingbuffer.Remove(hash) + if removed { + transactionsInBlocklistCounter.Dec(1) + } + return removed } func (miner *Miner) Close() { diff --git a/miner/tx_ringbuffer.go b/miner/tx_ringbuffer.go index 4184ee406a..06d47df2c7 100644 --- a/miner/tx_ringbuffer.go +++ b/miner/tx_ringbuffer.go @@ -26,12 +26,12 @@ func NewTxRingBuffer(size int) *TxRingBuffer { // Add adds a new transaction hash to the ring buffer, if the buffer is // at capacity, the oldest transaction hash is overwritten. -func (b *TxRingBuffer) Add(tx common.Hash) { +func (b *TxRingBuffer) Add(tx common.Hash) bool { b.mux.Lock() defer b.mux.Unlock() - if _, exists := b.m[tx]; exists == true { - return + if _, exists := b.m[tx]; exists { + return false } // Clean up old transaction hash from map @@ -47,6 +47,7 @@ func (b *TxRingBuffer) Add(tx common.Hash) { if b.index == len(b.ring) { b.index = 0 } + return true } func (b *TxRingBuffer) Has(tx common.Hash) bool { diff --git a/miner/worker.go b/miner/worker.go index 5567ae9520..da8b2bbd36 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -61,6 +61,9 @@ var ( txConditionalMinedTimer = metrics.NewRegisteredTimer("miner/transactionConditional/elapsedtime", nil) txInteropRejectedCounter = metrics.NewRegisteredCounter("miner/transactionInterop/rejected", nil) + + feeCurrenciesInBlocklistCounter = metrics.NewRegisteredCounter("miner/blocklist/feeCurrency/blocked", nil) + transactionsInBlocklistCounter = metrics.NewRegisteredCounter("miner/blocklist/transactions/blocked", nil) ) // environment is the worker's current environment and holds all @@ -341,6 +344,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir "evicted-fee-currencies", evicted, "eviction-timeout-seconds", EvictionTimeoutSeconds, ) + feeCurrenciesInBlocklistCounter.Dec(int64(len(evicted))) } env.feeCurrencyAllowlist = miner.feeCurrencyBlocklist.FilterAllowlist( common.CurrencyAllowlist(env.feeCurrencyContext.ExchangeRates), @@ -854,8 +858,12 @@ func (miner *Miner) registerFeeCurrencyTxFailure(env *environment, tx *types.Tra // also add the fee-currency to a worker-wide blocklist, // so that they are not allowlisted in the following blocks // (only locally in the txpool, not consensus-critical) - miner.feeCurrencyBlocklist.Add(*tx.FeeCurrency(), *env.header) + if miner.feeCurrencyBlocklist.Add(*tx.FeeCurrency(), *env.header) { + feeCurrenciesInBlocklistCounter.Inc(1) + } // Add tx to block tx ringbuffer - miner.blockedTxRingbuffer.Add(tx.Hash()) + if miner.blockedTxRingbuffer.Add(tx.Hash()) { + transactionsInBlocklistCounter.Inc(1) + } }