From 0914f3b5e3af857147c6c98ff2990f8d7ff716d7 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 2 Nov 2021 12:52:10 +0100 Subject: [PATCH] Fix IsServiceTransaction by allowing all 0 gas price transactions to be service transactions when processing and validator transactions to be service transactions when producing block --- .../InitializeBlockchainAuRa.cs | 3 +- .../StartBlockProducerAuRa.cs | 3 +- .../TxAuRaFilterBuilders.cs | 12 +++-- .../Transactions/LocalTxFilter.cs | 43 +++++++++++++++ .../Transactions/ServiceTxFilter.cs | 44 ++++++++++++++++ .../Transactions/TransactionExtensions.cs | 41 +++++++++++++++ .../Transactions/TxCertifierFilter.cs | 52 ++++++++----------- 7 files changed, 162 insertions(+), 36 deletions(-) create mode 100644 src/Nethermind/Nethermind.Consensus.AuRa/Transactions/LocalTxFilter.cs create mode 100644 src/Nethermind/Nethermind.Consensus.AuRa/Transactions/ServiceTxFilter.cs create mode 100644 src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs index 708d58ceea0..1bc852dc789 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs @@ -74,7 +74,8 @@ protected override BlockProcessor CreateBlockProcessor() ITxFilter auRaTxFilter = TxAuRaFilterBuilders.CreateAuRaTxFilter( _api, txPermissionFilterOnlyTxProcessorSource, - _api.SpecProvider); + _api.SpecProvider, + new ServiceTxFilter(_api.SpecProvider)); var processor = new AuRaBlockProcessor( _api.SpecProvider, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs index 8b7fa6047b1..b8b1b35b3bc 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs @@ -130,7 +130,8 @@ private BlockProcessor CreateBlockProcessor(ReadOnlyTxProcessingEnv changeableTx ITxFilter auRaTxFilter = TxAuRaFilterBuilders.CreateAuRaTxFilter( _api, constantContractTxProcessingEnv, - _api.SpecProvider); + _api.SpecProvider, + new LocalTxFilter(_api.EngineSigner)); _validator = new AuRaValidatorFactory(_api.AbiEncoder, changeableTxProcessingEnv.StateProvider, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs index ea242270b58..2d2f91f4b99 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs @@ -57,17 +57,18 @@ private static ITxFilter CreateBaseAuRaTxFilter( private static ITxFilter CreateBaseAuRaTxFilter( AuRaNethermindApi api, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, - ISpecProvider specProvider) + ISpecProvider specProvider, + ITxFilter baseTxFilter) { Address? registrar = api.ChainSpec?.Parameters.Registrar; if (registrar != null) { RegisterContract registerContract = new(api.AbiEncoder, registrar, readOnlyTxProcessorSource); CertifierContract certifierContract = new(api.AbiEncoder, registerContract, readOnlyTxProcessorSource); - return new TxCertifierFilter(certifierContract, NullTxFilter.Instance, specProvider, api.LogManager); + return new TxCertifierFilter(certifierContract, baseTxFilter, specProvider, api.LogManager); } - return NullTxFilter.Instance; + return baseTxFilter; } @@ -114,9 +115,10 @@ public static ITxFilter CreateAuRaTxFilterForProducer( public static ITxFilter CreateAuRaTxFilter( AuRaNethermindApi api, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, - ISpecProvider specProvider) + ISpecProvider specProvider, + ITxFilter baseTxFilter) { - ITxFilter baseAuRaTxFilter = CreateBaseAuRaTxFilter(api, readOnlyTxProcessorSource, specProvider); + ITxFilter baseAuRaTxFilter = CreateBaseAuRaTxFilter(api, readOnlyTxProcessorSource, specProvider, baseTxFilter); ITxFilter? txPermissionFilter = CreateTxPermissionFilter(api, readOnlyTxProcessorSource); return txPermissionFilter != null ? new CompositeTxFilter(baseAuRaTxFilter, txPermissionFilter) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/LocalTxFilter.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/LocalTxFilter.cs new file mode 100644 index 00000000000..665f00fb9aa --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/LocalTxFilter.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +using System; +using Nethermind.Consensus.Transactions; +using Nethermind.Core; + +namespace Nethermind.Consensus.AuRa.Transactions +{ + public class LocalTxFilter : ITxFilter + { + private readonly ISigner _signer; + + public LocalTxFilter(ISigner signer) + { + _signer = signer; + } + + public (bool Allowed, string Reason) IsAllowed(Transaction tx, BlockHeader parentHeader) + { + if (tx.SenderAddress == _signer.Address) + { + tx.IsServiceTransaction = true; + } + + return (true, string.Empty); + } + } +} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/ServiceTxFilter.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/ServiceTxFilter.cs new file mode 100644 index 00000000000..e1e517bed49 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/ServiceTxFilter.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +using System; +using Nethermind.Consensus.Transactions; +using Nethermind.Core; +using Nethermind.Core.Specs; + +namespace Nethermind.Consensus.AuRa.Transactions +{ + public class ServiceTxFilter : ITxFilter + { + private readonly ISpecProvider _specProvider; + + public ServiceTxFilter(ISpecProvider specProvider) + { + _specProvider = specProvider; + } + + public (bool Allowed, string Reason) IsAllowed(Transaction tx, BlockHeader parentHeader) + { + if (tx.IsZeroGasPrice(parentHeader, _specProvider)) + { + tx.IsServiceTransaction = true; + } + + return (true, string.Empty); + } + } +} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs new file mode 100644 index 00000000000..01a29164e57 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +using Nethermind.Core; +using Nethermind.Core.Specs; + +namespace Nethermind.Consensus.AuRa.Transactions +{ + public static class TransactionExtensions + { + public static bool IsZeroGasPrice(this Transaction tx, BlockHeader parentHeader, ISpecProvider specProvider) + { + bool isEip1559Enabled = specProvider.GetSpec(parentHeader.Number + 1).IsEip1559Enabled; + bool checkByFeeCap = isEip1559Enabled && tx.IsEip1559; + if (checkByFeeCap && !tx.MaxFeePerGas.IsZero) // only 0 gas price transactions are system transactions and can be whitelisted + { + return false; + } + else if (!tx.GasPrice.IsZero && !checkByFeeCap) + { + return false; + } + + return true; + } + } +} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxCertifierFilter.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxCertifierFilter.cs index eda944bb4e7..3a71ea2adf7 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxCertifierFilter.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxCertifierFilter.cs @@ -52,38 +52,32 @@ public TxCertifierFilter(ICertifierContract certifierContract, ITxFilter notCert private bool IsCertified(Transaction tx, BlockHeader parentHeader) { - bool isEip1559Enabled = _specProvider.GetSpec(parentHeader.Number + 1).IsEip1559Enabled; - bool checkByFeeCap = isEip1559Enabled && tx.IsEip1559; - if (checkByFeeCap && !tx.MaxFeePerGas.IsZero) // only 0 gas price transactions are system transactions and can be whitelissted + if (tx.IsZeroGasPrice(parentHeader, _specProvider)) { - return false; - } - else if (!tx.GasPrice.IsZero && !checkByFeeCap) - { - return false; - } - - Address sender = tx.SenderAddress; - if (_logger.IsTrace) _logger.Trace($"Checking service transaction checker contract from {sender}."); - IDictionary cache = GetCache(parentHeader.Hash); - - if (cache.TryGetValue(sender, out bool isCertified)) - { - tx.IsServiceTransaction = isCertified; - return isCertified; - } + Address sender = tx.SenderAddress; + if (_logger.IsTrace) _logger.Trace($"Checking service transaction checker contract from {sender}."); + IDictionary cache = GetCache(parentHeader.Hash); - try - { - bool isCertifiedByContract = _certifierContract.Certified(parentHeader, sender); - tx.IsServiceTransaction = isCertifiedByContract; - return cache[sender] = isCertifiedByContract; - } - catch (AbiException e) - { - if (_logger.IsError) _logger.Error($"Call to certifier contract failed on block {parentHeader.ToString(BlockHeader.Format.FullHashAndNumber)}.", e); - return false; + if (cache.TryGetValue(sender, out bool isCertified)) + { + tx.IsServiceTransaction = isCertified; + return isCertified; + } + + try + { + bool isCertifiedByContract = _certifierContract.Certified(parentHeader, sender); + tx.IsServiceTransaction = isCertifiedByContract; + return cache[sender] = isCertifiedByContract; + } + catch (AbiException e) + { + if (_logger.IsError) _logger.Error($"Call to certifier contract failed on block {parentHeader.ToString(BlockHeader.Format.FullHashAndNumber)}.", e); + return false; + } } + + return false; } private IDictionary GetCache(Keccak blockHash)