diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index 9cbb8e54947..9943a961241 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -129,14 +129,14 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) BlobGasUsed = (ulong)test.ParentBlobGasUsed, ExcessBlobGas = (ulong)test.ParentExcessBlobGas, }; - header.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec); + header.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec, header); } ValidationResult txIsValid = _txValidator.IsWellFormed(test.Transaction, spec); if (txIsValid) { - transactionProcessor.Execute(test.Transaction, new BlockExecutionContext(header), txTracer); + transactionProcessor.Execute(test.Transaction, new BlockExecutionContext(header, spec), txTracer); } else { diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs index 079f507fe05..d07a2242f5e 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs @@ -90,7 +90,8 @@ protected override BlockProcessor CreateBlockProcessor() blockGasLimitContractTransition.Key, new ReadOnlyTxProcessingEnv( WorldStateManager, - BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance)); + BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance), + SpecProvider); GasLimitOverrideCache = new AuRaContractGasLimitOverride.Cache(); GasLimitCalculator = new AuRaContractGasLimitOverride(new[] { gasLimitContract }, GasLimitOverrideCache, false, new FollowOtherMiners(SpecProvider), LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/ReportingValidatorContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/ReportingValidatorContractTests.cs index b24804531f2..4ace626cfec 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/ReportingValidatorContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/ReportingValidatorContractTests.cs @@ -7,6 +7,7 @@ using Nethermind.Consensus.AuRa.Contracts; using Nethermind.Core; using Nethermind.Core.Extensions; +using Nethermind.Specs; using NSubstitute; using NUnit.Framework; @@ -17,7 +18,7 @@ public class ReportingValidatorContractTests [Test] public void Should_generate_malicious_transaction() { - ReportingValidatorContract contract = new(AbiEncoder.Instance, new Address("0x1000000000000000000000000000000000000001"), Substitute.For()); + ReportingValidatorContract contract = new(AbiEncoder.Instance, new Address("0x1000000000000000000000000000000000000001"), Substitute.For(), TestSpecProvider.Instance); Transaction transaction = contract.ReportMalicious(new Address("0x75df42383afe6bf5194aa8fa0e9b3d5f9e869441"), 10, new byte[0]); transaction.Data.AsArray().ToHexString().Should().Be("c476dd4000000000000000000000000075df42383afe6bf5194aa8fa0e9b3d5f9e869441000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"); } @@ -25,7 +26,7 @@ public void Should_generate_malicious_transaction() [Test] public void Should_generate_benign_transaction() { - ReportingValidatorContract contract = new(AbiEncoder.Instance, new Address("0x1000000000000000000000000000000000000001"), Substitute.For()); + ReportingValidatorContract contract = new(AbiEncoder.Instance, new Address("0x1000000000000000000000000000000000000001"), Substitute.For(), TestSpecProvider.Instance); Transaction transaction = contract.ReportBenign(new Address("0x75df42383afe6bf5194aa8fa0e9b3d5f9e869441"), 10); transaction.Data.AsArray().ToHexString().Should().Be("d69f13bb00000000000000000000000075df42383afe6bf5194aa8fa0e9b3d5f9e869441000000000000000000000000000000000000000000000000000000000000000a"); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 4e230c977c2..138718ef053 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -254,7 +254,7 @@ protected override TxPoolTxSource CreateTxPoolTxSource() TxPoolTxSource txPoolTxSource = base.CreateTxPoolTxSource(); TxPriorityContract = new TxPriorityContract(AbiEncoder.Instance, TestItem.AddressA, - new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance)); + new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance), SpecProvider); Priorities = new DictionaryContractDataStore( new TxPriorityContract.DestinationSortedListContractDataStoreCollection(), diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs index ae1a5040a4f..7b6b345fcaa 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs @@ -16,6 +16,7 @@ using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; +using Nethermind.Specs; using Nethermind.State; using NSubstitute; using NUnit.Framework; @@ -52,7 +53,8 @@ public void constructor_throws_ArgumentNullException_on_null_contractAddress() null, _stateProvider, _readOnlyTxProcessorSource, - new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance)); + new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance), + TestSpecProvider.Instance); action.Should().Throw(); } @@ -78,7 +80,8 @@ public void finalize_change_should_call_correct_transaction() _contractAddress, _stateProvider, _readOnlyTxProcessorSource, - new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance)); + new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance), + TestSpecProvider.Instance); contract.FinalizeChange(_block.Header); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs index c83e8d09827..b1341c74ba1 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs @@ -21,6 +21,7 @@ using NSubstitute; using NUnit.Framework; using Nethermind.Evm; +using Nethermind.Specs; namespace Nethermind.AuRa.Test.Reward { @@ -61,21 +62,21 @@ public void SetUp() [Test] public void constructor_throws_ArgumentNullException_on_null_auraParameters() { - Action action = () => new AuRaRewardCalculator(null, _abiEncoder, _transactionProcessor); + Action action = () => new AuRaRewardCalculator(null, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); action.Should().Throw(); } [Test] public void constructor_throws_ArgumentNullException_on_null_encoder() { - Action action = () => new AuRaRewardCalculator(_auraParameters, null, _transactionProcessor); + Action action = () => new AuRaRewardCalculator(_auraParameters, null, _transactionProcessor, TestSpecProvider.Instance); action.Should().Throw(); } [Test] public void constructor_throws_ArgumentNullException_on_null_transactionProcessor() { - Action action = () => new AuRaRewardCalculator(_auraParameters, _abiEncoder, null); + Action action = () => new AuRaRewardCalculator(_auraParameters, _abiEncoder, null, TestSpecProvider.Instance); action.Should().Throw(); } @@ -87,7 +88,7 @@ public void constructor_throws_ArgumentException_on_BlockRewardContractTransitio {2, Address.FromNumber(2)} }; - Action action = () => new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor); + Action action = () => new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); action.Should().Throw(); } @@ -97,7 +98,7 @@ public void constructor_throws_ArgumentException_on_BlockRewardContractTransitio public void calculates_rewards_correctly_before_contract_transition(long blockNumber, ulong expectedReward) { _block.Header.Number = blockNumber; - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEquivalentTo(new BlockReward(_block.Beneficiary, expectedReward)); } @@ -106,7 +107,7 @@ public void calculates_rewards_correctly_before_contract_transition(long blockNu public void calculates_rewards_correctly_for_genesis() { _block.Header.Number = 0; - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEmpty(); } @@ -118,7 +119,7 @@ public void calculates_rewards_correctly_after_contract_transition(long blockNum _block.Header.Number = blockNumber; BlockReward expected = new(_block.Beneficiary, expectedReward, BlockRewardType.External); SetupBlockRewards(new Dictionary() { { _address10, new[] { expected } } }); - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEquivalentTo(expected); } @@ -144,7 +145,7 @@ public void calculates_rewards_correctly_after_subsequent_contract_transitions(l _block.Header.Number = blockNumber; BlockReward expected = new(_block.Beneficiary, expectedReward, BlockRewardType.External); SetupBlockRewards(new Dictionary() { { address, new[] { expected } } }); - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEquivalentTo(expected); } @@ -167,7 +168,7 @@ public void calculates_rewards_correctly_for_uncles(long blockNumber, ulong expe }; SetupBlockRewards(new Dictionary() { { _address10, expected } }); - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEquivalentTo(expected); } @@ -190,7 +191,7 @@ public void calculates_rewards_correctly_for_external_addresses() }; SetupBlockRewards(new Dictionary() { { _address10, expected } }); - AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); + AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor, TestSpecProvider.Instance); BlockReward[] result = calculator.CalculateRewards(_block); result.Should().BeEquivalentTo(expected); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs index cda399944da..879c76b5a58 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs @@ -124,7 +124,7 @@ public async Task registry_contract_returns_not_found_when_key_doesnt_exist() public async Task registry_contract_returns_not_found_when_contract_doesnt_exist() { using TestTxPermissionsBlockchain chain = await TestContractBlockchain.ForTest(); - RegisterContract contract = new(AbiEncoder.Instance, Address.FromNumber(1000), chain.ReadOnlyTransactionProcessorSource); + RegisterContract contract = new(AbiEncoder.Instance, Address.FromNumber(1000), chain.ReadOnlyTransactionProcessorSource, _specProvider); contract.TryGetAddress(chain.BlockTree.Head.Header, CertifierContract.ServiceTransactionContractRegistryName, out Address _).Should().BeFalse(); } @@ -141,11 +141,12 @@ protected override BlockProcessor CreateBlockProcessor() WorldStateManager, BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance); - RegisterContract = new RegisterContract(abiEncoder, ChainSpec.Parameters.Registrar, ReadOnlyTransactionProcessorSource); + RegisterContract = new RegisterContract(abiEncoder, ChainSpec.Parameters.Registrar, ReadOnlyTransactionProcessorSource, Substitute.For()); CertifierContract = new CertifierContract( abiEncoder, RegisterContract, - ReadOnlyTransactionProcessorSource); + ReadOnlyTransactionProcessorSource, + Substitute.For()); return new AuRaBlockProcessor( SpecProvider, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs index 6448452b0a3..e8d0a80184d 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs @@ -90,7 +90,7 @@ public void SetUp() .Encode(AbiEncodingStyle.IncludeSignature, Arg.Is(s => s.Name == "finalizeChange"), Arg.Any()) .Returns(_finalizeChangeData.TransactionData); - _validatorContract = new ValidatorContract(_transactionProcessor, _abiEncoder, _contractAddress, _stateProvider, _readOnlyTxProcessorSource, new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance)); + _validatorContract = new ValidatorContract(_transactionProcessor, _abiEncoder, _contractAddress, _stateProvider, _readOnlyTxProcessorSource, new Signer(0, TestItem.PrivateKeyD, LimboLogs.Instance), TestSpecProvider.Instance); } [TearDown] diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TestEip4844Config.cs b/src/Nethermind/Nethermind.Blockchain.Test/TestEip4844Config.cs index 5a71b47deaf..340b163c004 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TestEip4844Config.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TestEip4844Config.cs @@ -16,5 +16,5 @@ public TestEip4844Config(ulong? maxBlobGasPerBlock = null) public ulong GasPerBlob => Eip4844Constants.GasPerBlob; - public int GetMaxBlobsPerBlock() => (int)(MaxBlobGasPerBlock / GasPerBlob); + public ulong GetMaxBlobsPerBlock() => MaxBlobGasPerBlock / GasPerBlob; } diff --git a/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs b/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs index e54c14c0c2b..222a85d74d0 100644 --- a/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs +++ b/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs @@ -5,6 +5,7 @@ using Nethermind.Core.Eip2930; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; @@ -62,7 +63,7 @@ public void StoreBeaconRoot(Block block, IReleaseSpec spec, ITxTracer tracer) transaction.Hash = transaction.CalculateHash(); - processor.Execute(transaction, header, tracer); + processor.Execute(transaction, new BlockExecutionContext(header, spec), tracer); } } } diff --git a/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs b/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs index 3c90e3dc736..90a356fdf4b 100644 --- a/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs @@ -59,7 +59,8 @@ private void OnHeadChanged(object? sender, BlockReplacementEventArgs e) BlockGasLimit = e.Block!.GasLimit; CurrentBaseFee = e.Block.Header.BaseFeePerGas; CurrentFeePerBlobGas = - BlobGasCalculator.TryCalculateFeePerBlobGas(e.Block.Header, out UInt256 currentFeePerBlobGas) + BlobGasCalculator.TryCalculateFeePerBlobGas(e.Block.Header, out UInt256 currentFeePerBlobGas, + SpecProvider.GetSpec(e.Block.Header)) ? currentFeePerBlobGas : UInt256.Zero; HeadChanged?.Invoke(sender, e); diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs index 54ddaf92945..52aefe6f9ff 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Abi; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm; using Nethermind.Evm.Tracing; @@ -24,7 +25,8 @@ public abstract class CallableContract : Contract /// Transaction processor on which all should be run on. /// Binary interface encoder/decoder. /// Address where contract is deployed. - protected CallableContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) : base(abiEncoder, contractAddress) + /// Address where contract is deployed. + protected CallableContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, ISpecProvider specProvider) : base(specProvider, abiEncoder, contractAddress) { _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor)); } @@ -66,7 +68,7 @@ private bool TryCall(BlockHeader header, Transaction transaction, out byte[] res try { - _transactionProcessor.Execute(transaction, new BlockExecutionContext(header), tracer); + _transactionProcessor.Execute(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), tracer); result = tracer.ReturnValue; return tracer.StatusCode == StatusCode.Success; } @@ -87,7 +89,7 @@ private bool TryCall(BlockHeader header, Transaction transaction, out byte[] res /// Arguments to the function. /// true if function was otherwise false. protected bool TryCall(BlockHeader header, string functionName, Address sender, out object[] result, params object[] arguments) => - TryCall(header, functionName, sender, DefaultContractGasLimit, out result, arguments); + TryCall(header, functionName, sender, DefaultContractGasLimit, out result); /// /// Same as but returns false instead of throwing . diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs index 3b4eec49104..134aa2f6f35 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain.Contracts.Json; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Int256; using Nethermind.Evm; @@ -36,18 +37,21 @@ public abstract partial class Contract protected IAbiEncoder AbiEncoder { get; } public AbiDefinition AbiDefinition { get; } public Address? ContractAddress { get; protected set; } + protected ISpecProvider SpecProvider { get; set; } /// /// Creates contract /// + /// Binary interface encoder/decoder. /// Binary interface encoder/decoder. /// Address where contract is deployed. /// Binary definition of contract. - protected Contract(IAbiEncoder? abiEncoder = null, Address? contractAddress = null, AbiDefinition? abiDefinition = null) + protected Contract(ISpecProvider specProvider, IAbiEncoder? abiEncoder = null, Address? contractAddress = null, AbiDefinition? abiDefinition = null) { AbiEncoder = abiEncoder ?? Abi.AbiEncoder.Instance; ContractAddress = contractAddress; AbiDefinition = abiDefinition ?? new AbiDefinitionParser().Parse(GetType()); + SpecProvider = specProvider; } protected virtual Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address sender, long gasLimit = DefaultContractGasLimit, BlockHeader header = null) @@ -178,11 +182,11 @@ protected byte[] CallCore(ITransactionProcessor transactionProcessor, BlockHeade { if (callAndRestore) { - transactionProcessor.CallAndRestore(transaction, new BlockExecutionContext(header), tracer); + transactionProcessor.CallAndRestore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), tracer); } else { - transactionProcessor.Execute(transaction, new BlockExecutionContext(header), tracer); + transactionProcessor.Execute(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), tracer); } failure = tracer.StatusCode != StatusCode.Success; diff --git a/src/Nethermind/Nethermind.Blockchain/GenesisLoader.cs b/src/Nethermind/Nethermind.Blockchain/GenesisLoader.cs index 2c94e4d7c6d..6479fe07cb7 100644 --- a/src/Nethermind/Nethermind.Blockchain/GenesisLoader.cs +++ b/src/Nethermind/Nethermind.Blockchain/GenesisLoader.cs @@ -80,7 +80,7 @@ private void Preallocate(Block genesis) }; CallOutputTracer outputTracer = new(); - _transactionProcessor.Execute(constructorTransaction, new BlockExecutionContext(genesis.Header), outputTracer); + _transactionProcessor.Execute(constructorTransaction, new BlockExecutionContext(genesis.Header, _specProvider.GetSpec(genesis.Header)), outputTracer); if (outputTracer.StatusCode != StatusCode.Success) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs index 00db5435a80..49dc8e24689 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs @@ -80,8 +80,8 @@ public AuRaValidatorFactory(IAbiEncoder abiEncoder, public IAuRaValidator CreateValidatorProcessor(AuRaParameters.Validator validator, BlockHeader parentHeader = null, long? startBlock = null) { - IValidatorContract GetValidatorContract() => new ValidatorContract(_transactionProcessor, _abiEncoder, validator.GetContractAddress(), _stateProvider, _readOnlyTxProcessorSource, _signer); - IReportingValidatorContract GetReportingValidatorContract() => new ReportingValidatorContract(_abiEncoder, validator.GetContractAddress(), _signer); + IValidatorContract GetValidatorContract() => new ValidatorContract(_transactionProcessor, _abiEncoder, validator.GetContractAddress(), _stateProvider, _readOnlyTxProcessorSource, _signer, _specProvider); + IReportingValidatorContract GetReportingValidatorContract() => new ReportingValidatorContract(_abiEncoder, validator.GetContractAddress(), _signer, _specProvider); var validSealerStrategy = new ValidSealerStrategy(); long startBlockNumber = startBlock ?? AuRaValidatorBase.DefaultStartBlockNumber; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs index 37954b6ca9a..b04304e16e3 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -24,8 +25,9 @@ public BlockGasLimitContract( IAbiEncoder abiEncoder, Address contractAddress, long transitionBlock, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { Activation = transitionBlock; Constant = GetConstant(readOnlyTxProcessorSource); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/CertifierContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/CertifierContract.cs index a5aa60a0c6c..40fac04475c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/CertifierContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/CertifierContract.cs @@ -3,6 +3,7 @@ using Nethermind.Abi; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; namespace Nethermind.Consensus.AuRa.Contracts @@ -22,8 +23,9 @@ public class CertifierContract : RegisterBasedContract, ICertifierContract public CertifierContract( IAbiEncoder abiEncoder, IRegisterContract registerContract, - IReadOnlyTxProcessorSource readOnlyTransactionProcessorSource) - : base(abiEncoder, registerContract, ServiceTransactionContractRegistryName) + IReadOnlyTxProcessorSource readOnlyTransactionProcessorSource, + ISpecProvider specProvider) + : base(abiEncoder, registerContract, ServiceTransactionContractRegistryName, specProvider) { Constant = GetConstant(readOnlyTransactionProcessorSource); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs index 18ada055792..51d086e2c29 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -81,8 +82,9 @@ public RandomContract( Address contractAddress, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, long transitionBlock, - ISigner signer) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + ISigner signer, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { _signer = signer; Activation = transitionBlock; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs index 572563fb64a..70ac339bbaa 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs @@ -5,6 +5,7 @@ using Nethermind.Blockchain.Contracts; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; namespace Nethermind.Consensus.AuRa.Contracts { @@ -18,8 +19,9 @@ public RegisterBasedContract( IAbiEncoder abiEncoder, IRegisterContract registerContract, string registryKey, + ISpecProvider specProvider, AbiDefinition? abiDefinition = null) - : base(abiEncoder, abiDefinition: abiDefinition) + : base(specProvider, abiEncoder, abiDefinition: abiDefinition) { _registerContract = registerContract; _registryKey = registryKey; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterContract.cs index 6d7d3e67960..3e1c9cb02be 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterContract.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain.Contracts; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; namespace Nethermind.Consensus.AuRa.Contracts @@ -33,8 +34,9 @@ public class RegisterContract : Contract, IRegisterContract public RegisterContract( IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { Constant = GetConstant(readOnlyTxProcessorSource); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ReportingValidatorContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ReportingValidatorContract.cs index 75041e9b453..9f41a42a970 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ReportingValidatorContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ReportingValidatorContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Consensus.AuRa.Contracts @@ -47,8 +48,9 @@ public sealed class ReportingValidatorContract : Contract, IReportingValidatorCo public ReportingValidatorContract( IAbiEncoder abiEncoder, Address contractAddress, - ISigner signer) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + ISigner signer, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { _signer = signer ?? throw new ArgumentNullException(nameof(signer)); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs index e78314f8d97..93440e4f84c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -34,8 +35,8 @@ public sealed class RewardContract : CallableContract, IRewardContract { public long Activation { get; } - public RewardContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, long transitionBlock) - : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + public RewardContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, long transitionBlock, ISpecProvider specProvider) + : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), specProvider) { Activation = transitionBlock; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContract.cs index 28f57bded5d..9c276860eaa 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -97,8 +98,9 @@ protected virtual (ITransactionPermissionContract.TxPermissions, bool) CallAllow protected TransactionPermissionContract( IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress) { Constant = new PermissionConstantContract(this, readOnlyTxProcessorSource); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV1.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV1.cs index 7509c8a2f6b..8cbb6fcc09a 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV1.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV1.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Abi; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -14,14 +15,16 @@ public sealed class TransactionPermissionContractV1 : TransactionPermissionContr public TransactionPermissionContractV1( IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource, specProvider) { } protected override object[] GetAllowedTxTypesParameters(Transaction tx, BlockHeader parentHeader) => new object[] { tx.SenderAddress }; - protected override (ITransactionPermissionContract.TxPermissions, bool) CallAllowedTxTypes(PermissionConstantContract.PermissionCallInfo callInfo) => + protected override (ITransactionPermissionContract.TxPermissions, bool) CallAllowedTxTypes( + PermissionConstantContract.PermissionCallInfo callInfo) => (Constant.Call(callInfo), true); public override UInt256 Version => UInt256.One; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV2.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV2.cs index d5bbfa9299a..8fc239ae454 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV2.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV2.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Abi; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Evm.TransactionProcessing; @@ -16,8 +17,9 @@ public sealed class TransactionPermissionContractV2 : TransactionPermissionContr public TransactionPermissionContractV2( IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource, specProvider) { } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs index dd9afdcb38a..a960d469f4c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs @@ -21,7 +21,7 @@ public TransactionPermissionContractV3( Address contractAddress, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, ISpecProvider specProvider) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource) + : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource, specProvider) { _specProvider = specProvider; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV4.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV4.cs index 77ba9466d3d..00102d69d4b 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV4.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV4.cs @@ -22,7 +22,7 @@ public TransactionPermissionContractV4( Address contractAddress, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, ISpecProvider specProvider) - : base(abiEncoder, contractAddress, readOnlyTxProcessorSource) + : base(abiEncoder, contractAddress, readOnlyTxProcessorSource, specProvider) { _specProvider = specProvider; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.cs index 2f6b9bd5c8d..8d097fb6961 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.cs @@ -7,6 +7,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Int256; @@ -28,8 +29,9 @@ public partial class TxPriorityContract : Contract public TxPriorityContract( IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) - : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) + : base(specProvider, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { Constant = GetConstant(readOnlyTxProcessorSource); SendersWhitelist = new DataContract
(GetSendersWhitelist, SendersWhitelistSet); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs index 7483dc283db..f84b082c8cd 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs @@ -5,6 +5,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.State; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; @@ -60,8 +61,9 @@ public ValidatorContract( Address contractAddress, IWorldState stateProvider, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, - ISigner signer) - : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) + ISigner signer, + ISpecProvider specProvider) + : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), specProvider) { _stateProvider = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider)); _signer = signer ?? throw new ArgumentNullException(nameof(signer)); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs index ad6b86eb354..03a1125af71 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs @@ -35,22 +35,26 @@ public VersionedTransactionPermissionContract(IAbiEncoder abiEncoder, private static TransactionPermissionContractV1 CreateV1(IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) { return new( abiEncoder, contractAddress, - readOnlyTxProcessorSource); + readOnlyTxProcessorSource, + specProvider); } private static TransactionPermissionContractV2 CreateV2(IAbiEncoder abiEncoder, Address contractAddress, - IReadOnlyTxProcessorSource readOnlyTxProcessorSource) + IReadOnlyTxProcessorSource readOnlyTxProcessorSource, + ISpecProvider specProvider) { return new( abiEncoder, contractAddress, - readOnlyTxProcessorSource); + readOnlyTxProcessorSource, + specProvider); } private static TransactionPermissionContractV3 CreateV3(IAbiEncoder abiEncoder, @@ -89,13 +93,15 @@ private static Dictionary CreateAllVers UInt256.One, CreateV1(abiEncoder, contractAddress, - readOnlyTxProcessorSource) + readOnlyTxProcessorSource, + specProvider) }, { 2, CreateV2(abiEncoder, contractAddress, - readOnlyTxProcessorSource) + readOnlyTxProcessorSource, + specProvider) }, { 3, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs index cdf3c499336..d30be4fa5db 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs @@ -182,7 +182,8 @@ protected IAuRaValidator CreateAuRaValidator() _api.AbiEncoder, blockGasLimitContractTransition.Value, blockGasLimitContractTransition.Key, - _api.CreateReadOnlyTransactionProcessorSource())) + _api.CreateReadOnlyTransactionProcessorSource(), + _api.SpecProvider!)) .ToArray(), _api.GasLimitCalculatorCache, _auraConfig.Minimum2MlnGasPerBlockWhenUsingBlockGasLimitContract, @@ -205,7 +206,7 @@ protected override void InitSealEngine() ValidSealerStrategy validSealerStrategy = new ValidSealerStrategy(); _api.SealValidator = _sealValidator = new AuRaSealValidator(_parameters, _auRaStepCalculator, _api.BlockTree, _api.ValidatorStore, validSealerStrategy, _api.EthereumEcdsa, _api.LogManager); - _api.RewardCalculatorSource = new AuRaRewardCalculator.AuRaRewardCalculatorSource(_parameters, _api.AbiEncoder); + _api.RewardCalculatorSource = new AuRaRewardCalculator.AuRaRewardCalculatorSource(_parameters, _api.AbiEncoder, _api.SpecProvider!); _api.Sealer = new AuRaSealer(_api.BlockTree, _api.ValidatorStore, _auRaStepCalculator, _api.EngineSigner, validSealerStrategy, _api.LogManager); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs index 39faddc8c85..09f0326886f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs @@ -299,7 +299,8 @@ IList GetRandomContracts( kvp.Value, txProcessorSource, kvp.Key, - signerLocal)) + signerLocal, + _api.SpecProvider!)) .ToArray(); if (randomnessContractAddress?.Any() == true) @@ -368,7 +369,8 @@ private static IGasLimitCalculator CreateGasLimitCalculator(AuRaNethermindApi ap api.AbiEncoder, blockGasLimitContractTransition.Value, blockGasLimitContractTransition.Key, - api.CreateReadOnlyTransactionProcessorSource())) + api.CreateReadOnlyTransactionProcessorSource(), + api.SpecProvider!)) .ToArray(), api.GasLimitCalculatorCache, api.Config().Minimum2MlnGasPerBlockWhenUsingBlockGasLimitContract == true, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs index 6f3cfb20156..010c91cc910 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/TxAuRaFilterBuilders.cs @@ -48,8 +48,8 @@ private static ITxFilter CreateBaseAuRaTxFilter( Address? registrar = api.ChainSpec?.Parameters.Registrar; if (registrar is not null) { - RegisterContract registerContract = new(api.AbiEncoder, registrar, api.CreateReadOnlyTransactionProcessorSource()); - CertifierContract certifierContract = new(api.AbiEncoder, registerContract, api.CreateReadOnlyTransactionProcessorSource()); + RegisterContract registerContract = new(api.AbiEncoder, registrar, api.CreateReadOnlyTransactionProcessorSource(), specProvider); + CertifierContract certifierContract = new(api.AbiEncoder, registerContract, api.CreateReadOnlyTransactionProcessorSource(), specProvider); return CreateFilter(new TxCertifierFilter(certifierContract, gasPriceTxFilter, specProvider, api.LogManager), gasPriceTxFilter); } @@ -63,8 +63,8 @@ private static ITxFilter CreateBaseAuRaTxFilter( Address? registrar = api.ChainSpec?.Parameters.Registrar; if (registrar is not null) { - RegisterContract registerContract = new(api.AbiEncoder, registrar, api.CreateReadOnlyTransactionProcessorSource()); - CertifierContract certifierContract = new(api.AbiEncoder, registerContract, api.CreateReadOnlyTransactionProcessorSource()); + RegisterContract registerContract = new(api.AbiEncoder, registrar, api.CreateReadOnlyTransactionProcessorSource(), api.SpecProvider!); + CertifierContract certifierContract = new(api.AbiEncoder, registerContract, api.CreateReadOnlyTransactionProcessorSource(), api.SpecProvider!); return CreateFilter(new TxCertifierFilter(certifierContract, baseTxFilter, api.SpecProvider, api.LogManager)); } @@ -125,7 +125,7 @@ public static ITxFilter CreateAuRaTxFilter(AuRaNethermindApi api, ITxFilter base TxPriorityContract? txPriorityContract = null; if (usesTxPriorityContract) { - txPriorityContract = new TxPriorityContract(api.AbiEncoder, txPriorityContractAddress, api.CreateReadOnlyTransactionProcessorSource()); + txPriorityContract = new TxPriorityContract(api.AbiEncoder, txPriorityContractAddress, api.CreateReadOnlyTransactionProcessorSource(), api.SpecProvider!); } return txPriorityContract; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs index 4241943283f..7b92c71326f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs @@ -9,6 +9,7 @@ using Nethermind.Consensus.AuRa.Contracts; using Nethermind.Consensus.Rewards; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Specs.ChainSpecStyle; @@ -19,7 +20,7 @@ public class AuRaRewardCalculator : IRewardCalculator private readonly StaticRewardCalculator _blockRewardCalculator; private readonly IList _contracts; - public AuRaRewardCalculator(AuRaChainSpecEngineParameters auRaParameters, IAbiEncoder abiEncoder, ITransactionProcessor transactionProcessor) + public AuRaRewardCalculator(AuRaChainSpecEngineParameters auRaParameters, IAbiEncoder abiEncoder, ITransactionProcessor transactionProcessor, ISpecProvider specProvider) { ArgumentNullException.ThrowIfNull(auRaParameters); ArgumentNullException.ThrowIfNull(abiEncoder); @@ -31,7 +32,7 @@ IList BuildTransitions() if (auRaParameters.BlockRewardContractTransitions is not null) { - contracts.AddRange(auRaParameters.BlockRewardContractTransitions.Select(t => new RewardContract(transactionProcessor, abiEncoder, t.Value, t.Key))); + contracts.AddRange(auRaParameters.BlockRewardContractTransitions.Select(t => new RewardContract(transactionProcessor, abiEncoder, t.Value, t.Key, specProvider))); contracts.Sort((a, b) => a.Activation.CompareTo(b.Activation)); } @@ -43,7 +44,7 @@ IList BuildTransitions() throw new ArgumentException($"{nameof(auRaParameters.BlockRewardContractTransition)} provided for {nameof(auRaParameters.BlockRewardContractAddress)} is higher than first {nameof(auRaParameters.BlockRewardContractTransitions)}."); } - contracts.Insert(0, new RewardContract(transactionProcessor, abiEncoder, auRaParameters.BlockRewardContractAddress, contractTransition)); + contracts.Insert(0, new RewardContract(transactionProcessor, abiEncoder, auRaParameters.BlockRewardContractAddress, contractTransition, specProvider)); } return contracts; @@ -109,14 +110,16 @@ public class AuRaRewardCalculatorSource : IRewardCalculatorSource { private readonly AuRaChainSpecEngineParameters _auRaParameters; private readonly IAbiEncoder _abiEncoder; + private readonly ISpecProvider _specProvider; - public AuRaRewardCalculatorSource(AuRaChainSpecEngineParameters auRaParameters, IAbiEncoder abiEncoder) + public AuRaRewardCalculatorSource(AuRaChainSpecEngineParameters auRaParameters, IAbiEncoder abiEncoder, ISpecProvider specProvider) { _auRaParameters = auRaParameters; _abiEncoder = abiEncoder; + _specProvider = specProvider; } - public IRewardCalculator Get(ITransactionProcessor processor) => new AuRaRewardCalculator(_auRaParameters, _abiEncoder, processor); + public IRewardCalculator Get(ITransactionProcessor processor) => new AuRaRewardCalculator(_auRaParameters, _abiEncoder, processor, _specProvider); } public static class BenefactorKind diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockCachePreWarmer.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockCachePreWarmer.cs index ec2984d07e3..ffff4265fa8 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockCachePreWarmer.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockCachePreWarmer.cs @@ -169,7 +169,7 @@ private void WarmupTransactions(ParallelOptions parallelOptions, IReleaseSpec sp { scope.WorldState.WarmUp(tx.AccessList); // eip-2930 } - TransactionResult result = scope.TransactionProcessor.Warmup(systemTransaction, new BlockExecutionContext(block.Header.Clone()), NullTxTracer.Instance); + TransactionResult result = scope.TransactionProcessor.Warmup(systemTransaction, new BlockExecutionContext(block.Header.Clone(), spec), NullTxTracer.Instance); if (_logger.IsTrace) _logger.Trace($"Finished pre-warming cache for tx[{i}] {tx.Hash} with {result}"); } catch (Exception ex) when (ex is EvmException or OverflowException) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs index 9b9d1f49cba..8bdce8fce04 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs @@ -109,7 +109,7 @@ private static bool HasEnoughFounds(Transaction transaction, in UInt256 senderBa } if (transaction.SupportsBlobs && ( - !BlobGasCalculator.TryCalculateBlobBaseFee(block.Header, transaction, out UInt256 blobBaseFee) || + !BlobGasCalculator.TryCalculateBlobBaseFee(block.Header, transaction, out UInt256 blobBaseFee, releaseSpec) || senderBalance < (maxFee += blobBaseFee))) { e.Set(TxAction.Skip, $"{maxFee} is higher than sender balance ({senderBalance}), MaxFeePerGas: ({transaction.MaxFeePerGas}), GasLimit {transaction.GasLimit}, BlobBaseFee: {blobBaseFee}"); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs index 9725e29b7fd..cce2e733d59 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs @@ -70,7 +70,7 @@ public virtual TxReceipt[] ProcessTransactions(Block block, ProcessingOptions pr int i = 0; LinkedHashSet transactionsInBlock = new(ByHashTxComparer.Instance); - BlockExecutionContext blkCtx = new(block.Header); + BlockExecutionContext blkCtx = new(block.Header, spec); foreach (Transaction currentTx in transactions) { TxAction action = ProcessTransaction(block, in blkCtx, currentTx, i++, receiptsTracer, processingOptions, transactionsInBlock); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs index 6d2299ef920..cc300a1b520 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs @@ -33,7 +33,7 @@ public BlockValidationTransactionsExecutor(ITransactionProcessor transactionProc public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, BlockReceiptsTracer receiptsTracer, IReleaseSpec spec) { Metrics.ResetBlockStats(); - BlockExecutionContext blkCtx = CreateBlockExecutionContext(block); + BlockExecutionContext blkCtx = CreateBlockExecutionContext(block, spec); for (int i = 0; i < block.Transactions.Length; i++) { block.TransactionProcessed = i; @@ -43,7 +43,7 @@ public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processing return receiptsTracer.TxReceipts.ToArray(); } - protected virtual BlockExecutionContext CreateBlockExecutionContext(Block block) => new(block.Header); + protected virtual BlockExecutionContext CreateBlockExecutionContext(Block block, IReleaseSpec spec) => new(block.Header, spec); protected virtual void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index 8f6e94f4f01..6a17f2f8066 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -391,7 +391,8 @@ private Block PrepareBlockForProcessing(Block suggestedBlock) WithdrawalsRoot = bh.WithdrawalsRoot, RequestsRoot = bh.RequestsRoot, IsPostMerge = bh.IsPostMerge, - ParentBeaconBlockRoot = bh.ParentBeaconBlockRoot + ParentBeaconBlockRoot = bh.ParentBeaconBlockRoot, + TargetBlobCount = bh.TargetBlobCount, }; if (!ShouldComputeStateRoot(bh)) diff --git a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs index d11d0190576..86368663053 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs @@ -232,7 +232,8 @@ protected virtual BlockHeader PrepareBlockHeader(BlockHeader parent, { Author = blockAuthor, MixHash = payloadAttributes?.PrevRandao, - ParentBeaconBlockRoot = payloadAttributes?.ParentBeaconBlockRoot + ParentBeaconBlockRoot = payloadAttributes?.ParentBeaconBlockRoot, + TargetBlobCount = payloadAttributes?.TargetBlobCount, }; UInt256 difficulty = _difficultyCalculator.Calculate(header, parent); diff --git a/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs b/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs index e04cb6b46b9..4888f407058 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs @@ -26,6 +26,10 @@ public class PayloadAttributes public Hash256? ParentBeaconBlockRoot { get; set; } + public ulong? TargetBlobCount { get; set; } + + public ulong? MaxBlobCount { get; set; } + public virtual long? GetGasLimit() => null; public override string ToString() => ToString(string.Empty); @@ -47,6 +51,16 @@ public string ToString(string indentation) sb.Append($", {nameof(ParentBeaconBlockRoot)} : {ParentBeaconBlockRoot}"); } + if (TargetBlobCount is not null) + { + sb.Append($", {nameof(TargetBlobCount)} : {TargetBlobCount}"); + } + + if (MaxBlobCount is not null) + { + sb.Append($", {nameof(MaxBlobCount)} : {MaxBlobCount}"); + } + sb.Append('}'); return sb.ToString(); @@ -71,7 +85,9 @@ protected virtual int ComputePayloadIdMembersSize() => + Keccak.Size // prev randao + Address.Size // suggested fee recipient + (Withdrawals is null ? 0 : Keccak.Size) // withdrawals root hash - + (ParentBeaconBlockRoot is null ? 0 : Keccak.Size); // parent beacon block root + + (ParentBeaconBlockRoot is null ? 0 : Keccak.Size) // parent beacon block root + + (TargetBlobCount is null ? 0 : sizeof(ulong)) // target blob count + + (MaxBlobCount is null ? 0 : sizeof(ulong)); // max blob count protected static string ComputePayloadId(Span inputSpan) { @@ -110,6 +126,18 @@ protected virtual int WritePayloadIdMembers(BlockHeader parentHeader, Span position += Keccak.Size; } + if (TargetBlobCount.HasValue) + { + BinaryPrimitives.WriteUInt64BigEndian(inputSpan.Slice(position, sizeof(ulong)), TargetBlobCount.Value); + position += sizeof(ulong); + } + + if (MaxBlobCount.HasValue) + { + BinaryPrimitives.WriteUInt64BigEndian(inputSpan.Slice(position, sizeof(ulong)), MaxBlobCount.Value); + position += sizeof(ulong); + } + return position; } @@ -166,6 +194,7 @@ public static class PayloadAttributesExtensions public static int GetVersion(this PayloadAttributes executionPayload) => executionPayload switch { + { MaxBlobCount: not null, TargetBlobCount: not null } => EngineApiVersions.Prague, { ParentBeaconBlockRoot: not null, Withdrawals: not null } => EngineApiVersions.Cancun, { Withdrawals: not null } => EngineApiVersions.Shanghai, _ => EngineApiVersions.Paris @@ -174,6 +203,7 @@ public static int GetVersion(this PayloadAttributes executionPayload) => public static int ExpectedPayloadAttributesVersion(this IReleaseSpec spec) => spec switch { + { IsEip7742Enabled: true } => EngineApiVersions.Prague, { IsEip4844Enabled: true } => EngineApiVersions.Cancun, { WithdrawalsEnabled: true } => EngineApiVersions.Shanghai, _ => EngineApiVersions.Paris diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 70793885fd3..233b44315c2 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -62,7 +62,7 @@ public IEnumerable GetTransactions(BlockHeader parent, long gasLimi int checkedTransactions = 0; int selectedTransactions = 0; - using ArrayPoolList selectedBlobTxs = new(_eip4844Config.GetMaxBlobsPerBlock()); + using ArrayPoolList selectedBlobTxs = new((int)(payloadAttributes?.MaxBlobCount ?? Eip4844Constants.GetMaxBlobsPerBlock())); SelectBlobTransactions(blobTransactions, parent, spec, selectedBlobTxs); @@ -128,7 +128,7 @@ private void SelectBlobTransactions(IEnumerable blobTransactions, B foreach (Transaction blobTx in blobTransactions) { - if (blobGasCounter >= _eip4844Config.MaxBlobGasPerBlock) + if (!spec.IsEip7742Enabled && blobGasCounter >= _eip4844Config.MaxBlobGasPerBlock) { if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, no more blob space. Block already have {blobGasCounter} blob gas which is max value allowed."); break; @@ -137,7 +137,8 @@ private void SelectBlobTransactions(IEnumerable blobTransactions, B checkedBlobTransactions++; ulong txBlobGas = (ulong)(blobTx.BlobVersionedHashes?.Length ?? 0) * _eip4844Config.GasPerBlob; - if (txBlobGas > _eip4844Config.MaxBlobGasPerBlock - blobGasCounter) + // no validation is needed when eip7742 is activated + if (!spec.IsEip7742Enabled && txBlobGas > _eip4844Config.MaxBlobGasPerBlock - blobGasCounter) { if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space."); continue; @@ -188,7 +189,7 @@ private bool TryGetFullBlobTx(Transaction blobTx, [NotNullWhen(true)] out Transa private bool TryUpdateFeePerBlobGas(Transaction lightBlobTx, BlockHeader parent, IReleaseSpec spec, out UInt256 feePerBlobGas) { - ulong? excessDataGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec); + ulong? excessDataGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec, parent); if (excessDataGas is null) { if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, the specification is not configured to handle shard blob transactions."); @@ -196,7 +197,7 @@ private bool TryUpdateFeePerBlobGas(Transaction lightBlobTx, BlockHeader parent, return false; } - if (!BlobGasCalculator.TryCalculateFeePerBlobGas(excessDataGas.Value, out feePerBlobGas)) + if (!BlobGasCalculator.TryCalculateFeePerBlobGas(excessDataGas.Value, out feePerBlobGas, parent.TargetBlobCount, spec)) { if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, failed to calculate data gas price."); feePerBlobGas = UInt256.Zero; diff --git a/src/Nethermind/Nethermind.Consensus/Requests/RequestProcessor.cs b/src/Nethermind/Nethermind.Consensus/Requests/RequestProcessor.cs index c9c40c8dcd1..20e12760c45 100644 --- a/src/Nethermind/Nethermind.Consensus/Requests/RequestProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Requests/RequestProcessor.cs @@ -40,7 +40,7 @@ public IEnumerable ReadRequests(Block block, IWorldState state, IReleaseSpec }; transaction.Hash = transaction.CalculateHash(); - transactionProcessor.Execute(transaction, new BlockExecutionContext(block.Header), tracer); + transactionProcessor.Execute(transaction, new BlockExecutionContext(block.Header, spec), tracer); var result = tracer.ReturnValue; if (result == null || result.Length == 0) return Enumerable.Empty(); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 8c1edb4db43..2a7fd053029 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -385,7 +385,7 @@ protected virtual bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out if (feePerBlobGas.IsZero) { - if (!BlobGasCalculator.TryCalculateFeePerBlobGas(block.Header, out feePerBlobGas)) + if (!BlobGasCalculator.TryCalculateFeePerBlobGas(block.Header, out feePerBlobGas, spec)) { error = BlockErrorMessages.BlobGasPriceOverflow; if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} {error}."); @@ -405,7 +405,8 @@ protected virtual bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out ulong blobGasUsed = BlobGasCalculator.CalculateBlobGas(blobsInBlock); - if (blobGasUsed > Eip4844Constants.MaxBlobGasPerBlock) + // no validation is needed when eip7742 is activated + if (!spec.IsEip7742Enabled && blobGasUsed > Eip4844Constants.MaxBlobGasPerBlock) { error = BlockErrorMessages.BlobGasUsedAboveBlockLimit; if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} {error}."); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index 2605b291631..f60ab05a705 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -329,7 +329,7 @@ protected virtual bool ValidateBlobGasFields(BlockHeader header, BlockHeader par return false; } - ulong? expectedExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parentHeader, spec); + ulong? expectedExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parentHeader, spec, header); if (header.ExcessBlobGas != expectedExcessBlobGas) { if (_logger.IsWarn) _logger.Warn($"ExcessBlobGas field is incorrect: {header.ExcessBlobGas}, should be {expectedExcessBlobGas}."); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs index b5db9fd9eef..c8a13551277 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs @@ -189,15 +189,19 @@ public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec relea { To: null } => TxErrorMessages.TxMissingTo, { MaxFeePerBlobGas: null } => TxErrorMessages.BlobTxMissingMaxFeePerBlobGas, { BlobVersionedHashes: null } => TxErrorMessages.BlobTxMissingBlobVersionedHashes, - _ => ValidateBlobFields(transaction) + _ => ValidateBlobFields(transaction, releaseSpec) }; - private ValidationResult ValidateBlobFields(Transaction transaction) + private ValidationResult ValidateBlobFields(Transaction transaction, IReleaseSpec releaseSpec) { int blobCount = transaction.BlobVersionedHashes!.Length; - ulong totalDataGas = BlobGasCalculator.CalculateBlobGas(blobCount); - return totalDataGas > Eip4844Constants.MaxBlobGasPerTransaction ? TxErrorMessages.BlobTxGasLimitExceeded - : blobCount < Eip4844Constants.MinBlobsPerTransaction ? TxErrorMessages.BlobTxMissingBlobs + if (!releaseSpec.IsEip7742Enabled + && BlobGasCalculator.CalculateBlobGas(blobCount) > Eip4844Constants.MaxBlobGasPerTransaction) + { + return TxErrorMessages.BlobTxGasLimitExceeded; + } + + return blobCount < Eip4844Constants.MinBlobsPerTransaction ? TxErrorMessages.BlobTxMissingBlobs : ValidateBlobVersionedHashes(); ValidationResult ValidateBlobVersionedHashes() diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs index 4b5e591949b..36940cd9783 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs @@ -303,5 +303,11 @@ public BlockBuilder WithParentBeaconBlockRoot(Hash256? parentBeaconBlockRoot) TestObjectInternal.Header.ParentBeaconBlockRoot = parentBeaconBlockRoot; return this; } + + public BlockBuilder WithTargetBlobCount(ulong? targetBlobCount) + { + TestObjectInternal.Header.TargetBlobCount = targetBlobCount; + return this; + } } } diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs index 81d12c7a463..bfce32f74b2 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs @@ -201,4 +201,10 @@ public BlockHeaderBuilder WithRequestsRoot(Hash256? requestsRoot) TestObjectInternal.RequestsRoot = requestsRoot; return this; } + + public BlockHeaderBuilder WithTargetBlobCount(ulong? targetBlobCount) + { + TestObjectInternal.TargetBlobCount = targetBlobCount; + return this; + } } diff --git a/src/Nethermind/Nethermind.Core/Block.cs b/src/Nethermind/Nethermind.Core/Block.cs index c863555ecd2..bf6916281fa 100644 --- a/src/Nethermind/Nethermind.Core/Block.cs +++ b/src/Nethermind/Nethermind.Core/Block.cs @@ -121,6 +121,8 @@ public Transaction[] Transactions public Hash256? RequestsRoot => Header.RequestsRoot; // do not add setter here + public ulong? TargetBlobCount => Header.TargetBlobCount; // do not add setter here + [JsonIgnore] public ArrayPoolList? AccountChanges { get; set; } [JsonIgnore] diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index 1ddd19503b9..08060a5907a 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -84,6 +84,7 @@ public BlockHeader( public string SealEngineType { get; set; } = Core.SealEngineType.Ethash; public bool IsPostMerge { get; set; } + public ulong? TargetBlobCount { get; set; } public string ToString(string indent) { diff --git a/src/Nethermind/Nethermind.Core/Eip4844Constants.cs b/src/Nethermind/Nethermind.Core/Eip4844Constants.cs index e71de4ce77c..41f85186528 100644 --- a/src/Nethermind/Nethermind.Core/Eip4844Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip4844Constants.cs @@ -69,5 +69,5 @@ public static void OverrideIfAny( TargetBlobGasPerBlock = targetBlobGasPerBlock.Value; } - public static int GetMaxBlobsPerBlock() => (int)(MaxBlobGasPerBlock / GasPerBlob); + public static ulong GetMaxBlobsPerBlock() => MaxBlobGasPerBlock / GasPerBlob; } diff --git a/src/Nethermind/Nethermind.Core/Eip7742Constants.cs b/src/Nethermind/Nethermind.Core/Eip7742Constants.cs new file mode 100644 index 00000000000..e808fcb239d --- /dev/null +++ b/src/Nethermind/Nethermind.Core/Eip7742Constants.cs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Int256; + +namespace Nethermind.Core; + +public class Eip7742Constants +{ + /// + /// Gets the BLOB_GASPRICE_UPDATE_FRACTION parameter. + /// + /// Defaults to 3338477. + public static UInt256 BlobGasPriceUpdateFraction { get; private set; } = 1112825; +} diff --git a/src/Nethermind/Nethermind.Core/IEip4844Config.cs b/src/Nethermind/Nethermind.Core/IEip4844Config.cs index f2c76e77657..08c31abc062 100644 --- a/src/Nethermind/Nethermind.Core/IEip4844Config.cs +++ b/src/Nethermind/Nethermind.Core/IEip4844Config.cs @@ -10,14 +10,14 @@ public interface IEip4844Config { ulong MaxBlobGasPerBlock { get; } ulong GasPerBlob { get; } - int GetMaxBlobsPerBlock(); + ulong GetMaxBlobsPerBlock(); } public class ConstantEip4844Config : IEip4844Config { public ulong MaxBlobGasPerBlock => Eip4844Constants.MaxBlobGasPerBlock; public ulong GasPerBlob => Eip4844Constants.GasPerBlob; - public int GetMaxBlobsPerBlock() => Eip4844Constants.GetMaxBlobsPerBlock(); + public ulong GetMaxBlobsPerBlock() => Eip4844Constants.GetMaxBlobsPerBlock(); static ConstantEip4844Config() => Instance = new ConstantEip4844Config(); private ConstantEip4844Config() { } diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index 6c4f7c550a4..cdb417b55c7 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -323,6 +323,8 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec ///
bool IsRip7212Enabled { get; } + bool IsEip7742Enabled { get; } + /// OP Granite bool IsOpGraniteEnabled { get; } diff --git a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs index ac41ca6978b..8e2758a9ce7 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs @@ -66,6 +66,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual bool IsEip4895Enabled => spec.IsEip4895Enabled; public virtual bool IsEip4844Enabled => spec.IsEip4844Enabled; public virtual bool IsEip4788Enabled => spec.IsEip4788Enabled; + public virtual bool IsEip7742Enabled => spec.IsEip7742Enabled; public virtual Address? Eip4788ContractAddress => spec.Eip4788ContractAddress; public bool IsEip6110Enabled => spec.IsEip6110Enabled; public Address DepositContractAddress => spec.DepositContractAddress; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index b29fcf00088..368fc710537 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -54,7 +54,7 @@ public void GlobalSetup() codeInfo: new CodeInfo(ByteCode), value: 0, transferValue: 0, - txExecutionContext: new TxExecutionContext(_header, Address.Zero, 0, null, codeInfoRepository), + txExecutionContext: new TxExecutionContext(new BlockExecutionContext(_header, _spec), Address.Zero, 0, null, codeInfoRepository), inputData: default ); diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index 97d0d9e6cf8..04a0964cc57 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -87,7 +87,7 @@ public void GlobalSetup() codeInfo: new CodeInfo(_bytecode.Concat(_bytecode).Concat(_bytecode).Concat(_bytecode).ToArray()), value: 0, transferValue: 0, - txExecutionContext: new TxExecutionContext(_header, Address.Zero, 0, null, codeInfoRepository), + txExecutionContext: new TxExecutionContext(new BlockExecutionContext(_header, _spec), Address.Zero, 0, null, codeInfoRepository), inputData: default ); diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index b7b8d39945b..ec3e37c276f 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -98,7 +98,7 @@ public void GlobalSetup() codeInfo: new CodeInfo(Bytecode), value: 0, transferValue: 0, - txExecutionContext: new TxExecutionContext(_header, Address.Zero, 0, null, codeInfoRepository), + txExecutionContext: new TxExecutionContext(new BlockExecutionContext(_header, _spec), Address.Zero, 0, null, codeInfoRepository), inputData: default ); diff --git a/src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs b/src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs index 39302bb37dd..3f011525fef 100644 --- a/src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs @@ -14,31 +14,40 @@ namespace Nethermind.Evm.Test; [TestFixture] public class BlobGasCalculatorTests { + private void TestExcessBlobGas(IReleaseSpec spec, bool areBlobsEnabled, (ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas, ulong? targetBlobCount) testCase) + { + BlockHeader header = Build.A.BlockHeader + .WithTargetBlobCount(testCase.targetBlobCount).TestObject; + + BlockHeader parentHeader = Build.A.BlockHeader + .WithBlobGasUsed(BlobGasCalculator.CalculateBlobGas(testCase.parentBlobsCount)) + .WithExcessBlobGas(testCase.parentExcessBlobGas).TestObject; + + Assert.That(BlobGasCalculator.CalculateExcessBlobGas(parentHeader, spec, header), Is.EqualTo(areBlobsEnabled ? testCase.expectedExcessBlobGas : null)); + } + [TestCaseSource(nameof(ExcessBlobGasTestCaseSource))] - public void Excess_blob_gas_is_calculated_properly((ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas) testCase) + public void Excess_blob_gas_is_calculated_properly((ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas, ulong? targetBlobCount) testCase) + { + TestExcessBlobGas(Homestead.Instance, false, testCase); + TestExcessBlobGas(Frontier.Instance, false, testCase); + TestExcessBlobGas(SpuriousDragon.Instance, false, testCase); + TestExcessBlobGas(TangerineWhistle.Instance, false, testCase); + TestExcessBlobGas(Byzantium.Instance, false, testCase); + TestExcessBlobGas(Constantinople.Instance, false, testCase); + TestExcessBlobGas(ConstantinopleFix.Instance, false, testCase); + TestExcessBlobGas(Istanbul.Instance, false, testCase); + TestExcessBlobGas(MuirGlacier.Instance, false, testCase); + TestExcessBlobGas(Berlin.Instance, false, testCase); + TestExcessBlobGas(GrayGlacier.Instance, false, testCase); + TestExcessBlobGas(Shanghai.Instance, false, testCase); + TestExcessBlobGas(Cancun.Instance, true, testCase); + } + + [TestCaseSource(nameof(ExcessBlobGasTestCaseSourceForEip7742))] + public void Excess_blob_gas_is_calculated_properly_for_eip7742((ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas, ulong? targetBlobCount) testCase) { - void Test(IReleaseSpec spec, bool areBlobsEnabled) - { - BlockHeader parentHeader = Build.A.BlockHeader - .WithBlobGasUsed(BlobGasCalculator.CalculateBlobGas(testCase.parentBlobsCount)) - .WithExcessBlobGas(testCase.parentExcessBlobGas).TestObject; - - Assert.That(BlobGasCalculator.CalculateExcessBlobGas(parentHeader, spec), Is.EqualTo(areBlobsEnabled ? testCase.expectedExcessBlobGas : null)); - } - - Test(Homestead.Instance, false); - Test(Frontier.Instance, false); - Test(SpuriousDragon.Instance, false); - Test(TangerineWhistle.Instance, false); - Test(Byzantium.Instance, false); - Test(Constantinople.Instance, false); - Test(ConstantinopleFix.Instance, false); - Test(Istanbul.Instance, false); - Test(MuirGlacier.Instance, false); - Test(Berlin.Instance, false); - Test(GrayGlacier.Instance, false); - Test(Shanghai.Instance, false); - Test(Cancun.Instance, true); + TestExcessBlobGas(Prague.Instance, true, testCase); } [TestCaseSource(nameof(BlobGasCostTestCaseSource))] @@ -65,28 +74,41 @@ public void Blob_base_fee_may_overflow() Assert.That(blobBaseFee, Is.EqualTo(UInt256.MaxValue)); } - public static IEnumerable<(ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas)> ExcessBlobGasTestCaseSource() + public static IEnumerable<(ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas, ulong? targetBlobCount)> ExcessBlobGasTestCaseSource() { - yield return (0, 0, 0); - yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob) - 1, 0); - yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob), 0); - yield return (100000, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob), 100000); - yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob) + 1, Eip4844Constants.GasPerBlob * 1); - yield return (Eip4844Constants.TargetBlobGasPerBlock, 1, Eip4844Constants.GasPerBlob * 1); - yield return (Eip4844Constants.TargetBlobGasPerBlock, 0, 0); - yield return (Eip4844Constants.TargetBlobGasPerBlock, 2, Eip4844Constants.GasPerBlob * 2); - yield return (Eip4844Constants.MaxBlobGasPerBlock, 1, Eip4844Constants.TargetBlobGasPerBlock + Eip4844Constants.GasPerBlob * 1); + yield return (0, 0, 0, null); + yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob) - 1, 0, null); + yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob), 0, null); + yield return (100000, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob), 100000, null); + yield return (0, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob) + 1, Eip4844Constants.GasPerBlob * 1, null); + yield return (Eip4844Constants.TargetBlobGasPerBlock, 1, Eip4844Constants.GasPerBlob * 1, null); + yield return (Eip4844Constants.TargetBlobGasPerBlock, 0, 0, null); + yield return (Eip4844Constants.TargetBlobGasPerBlock, 2, Eip4844Constants.GasPerBlob * 2, null); + yield return (Eip4844Constants.MaxBlobGasPerBlock, 1, Eip4844Constants.TargetBlobGasPerBlock + Eip4844Constants.GasPerBlob * 1, null); yield return ( Eip4844Constants.MaxBlobGasPerBlock, (int)(Eip4844Constants.TargetBlobGasPerBlock / Eip4844Constants.GasPerBlob), - Eip4844Constants.MaxBlobGasPerBlock); + Eip4844Constants.MaxBlobGasPerBlock, null); yield return ( Eip4844Constants.MaxBlobGasPerBlock, (int)(Eip4844Constants.MaxBlobGasPerBlock / Eip4844Constants.GasPerBlob), - Eip4844Constants.MaxBlobGasPerBlock * 2 - Eip4844Constants.TargetBlobGasPerBlock + Eip4844Constants.MaxBlobGasPerBlock * 2 - Eip4844Constants.TargetBlobGasPerBlock, null ); } + public static IEnumerable<(ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas, ulong? targetBlobCount)> ExcessBlobGasTestCaseSourceForEip7742() + { + yield return ( + Eip4844Constants.MaxBlobGasPerBlock, + 1, + Eip4844Constants.MaxBlobGasPerBlock, 1); + yield return ( + Eip4844Constants.MaxBlobGasPerBlock, + 2, + Eip4844Constants.MaxBlobGasPerBlock + Eip4844Constants.GasPerBlob, 1); + yield return (0, 1, 0, 2); + } + public static IEnumerable<(Transaction tx, ulong excessBlobGas, UInt256 expectedCost)> BlobGasCostTestCaseSource() { yield return (Build.A.Transaction.TestObject, 0, 0); diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index 33c7eb093cc..73124ae837f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -196,7 +196,7 @@ private static string Run(byte[] input) MyTracer tracer = new(); transactionProcessor.Execute( tx, - new BlockExecutionContext(block.Header), + new BlockExecutionContext(block.Header, specProvider.GetSpec(block.Header)), tracer); return tracer.lastmemline; } diff --git a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs index 5b240a865f4..6502db59b7d 100644 --- a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.IO; using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Int256; @@ -29,9 +30,9 @@ public static ulong CalculateBlobGas(Transaction[] transactions) return CalculateBlobGas(blobCount); } - public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction transaction, out UInt256 blobBaseFee) + public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction transaction, out UInt256 blobBaseFee, IReleaseSpec? spec = null) { - if (!TryCalculateFeePerBlobGas(header.ExcessBlobGas.Value, out UInt256 feePerBlobGas)) + if (!TryCalculateFeePerBlobGas(header.ExcessBlobGas, out UInt256 feePerBlobGas, header.TargetBlobCount, spec)) { blobBaseFee = UInt256.MaxValue; return false; @@ -39,14 +40,12 @@ public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction trans return !UInt256.MultiplyOverflow(CalculateBlobGas(transaction), feePerBlobGas, out blobBaseFee); } - public static bool TryCalculateFeePerBlobGas(BlockHeader header, out UInt256 feePerBlobGas) + public static bool TryCalculateFeePerBlobGas(BlockHeader header, out UInt256 feePerBlobGas, IReleaseSpec? spec = null) { - feePerBlobGas = UInt256.MaxValue; - return header.ExcessBlobGas is not null - && TryCalculateFeePerBlobGas(header.ExcessBlobGas.Value, out feePerBlobGas); + return TryCalculateFeePerBlobGas(header.ExcessBlobGas, out feePerBlobGas, header.TargetBlobCount, spec); } - public static bool TryCalculateFeePerBlobGas(ulong excessBlobGas, out UInt256 feePerBlobGas) + public static bool TryCalculateFeePerBlobGas(ulong? excessBlobGas, out UInt256 feePerBlobGas, UInt256? targetBlobCount = null, IReleaseSpec? spec = null) { static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denominator, out UInt256 feePerBlobGas) { @@ -85,10 +84,16 @@ static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denomin return false; } - return !FakeExponentialOverflow(Eip4844Constants.MinBlobGasPrice, excessBlobGas, Eip4844Constants.BlobGasPriceUpdateFraction, out feePerBlobGas); + var denominator = spec?.IsEip7742Enabled ?? false + ? Eip7742Constants.BlobGasPriceUpdateFraction * targetBlobCount + ?? throw new InvalidDataException("header is missing target blob count") + : Eip4844Constants.BlobGasPriceUpdateFraction; + + feePerBlobGas = UInt256.MaxValue; + return excessBlobGas is not null && !FakeExponentialOverflow(Eip4844Constants.MinBlobGasPrice, excessBlobGas.Value, denominator, out feePerBlobGas); } - public static ulong? CalculateExcessBlobGas(BlockHeader? parentBlockHeader, IReleaseSpec releaseSpec) + public static ulong? CalculateExcessBlobGas(BlockHeader? parentBlockHeader, IReleaseSpec releaseSpec, BlockHeader header) { if (!releaseSpec.IsEip4844Enabled) { @@ -102,8 +107,13 @@ static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denomin ulong excessBlobGas = parentBlockHeader.ExcessBlobGas ?? 0; excessBlobGas += parentBlockHeader.BlobGasUsed ?? 0; - return excessBlobGas < Eip4844Constants.TargetBlobGasPerBlock + var targetBlobCount = releaseSpec.IsEip7742Enabled + ? header.TargetBlobCount * Eip4844Constants.GasPerBlob + ?? throw new InvalidDataException("header is missing target blob count") + : Eip4844Constants.TargetBlobGasPerBlock; + + return excessBlobGas < targetBlobCount ? 0 - : (excessBlobGas - Eip4844Constants.TargetBlobGasPerBlock); + : excessBlobGas - targetBlobCount; } } diff --git a/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs b/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs index 2bd0b7456b9..8af467bbb14 100644 --- a/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs +++ b/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Evm; @@ -12,12 +13,12 @@ public readonly struct BlockExecutionContext public BlockHeader Header { get; } public UInt256? BlobBaseFee { get; } - public BlockExecutionContext(BlockHeader blockHeader) + public BlockExecutionContext(BlockHeader blockHeader, IReleaseSpec spec) { Header = blockHeader; if (blockHeader?.ExcessBlobGas is not null) { - if (!BlobGasCalculator.TryCalculateFeePerBlobGas(blockHeader.ExcessBlobGas.Value, out UInt256 feePerBlobGas)) + if (!BlobGasCalculator.TryCalculateFeePerBlobGas(blockHeader, out UInt256 feePerBlobGas, spec)) { throw new OverflowException("Blob gas price calculation led to overflow."); } @@ -31,5 +32,4 @@ public BlockExecutionContext(BlockHeader blockHeader, UInt256 forceBlobBaseFee) BlobBaseFee = forceBlobBaseFee; } - public static implicit operator BlockExecutionContext(BlockHeader header) => new(header); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs index a673ef8b657..e05eeb5234b 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs @@ -114,7 +114,7 @@ private bool TryExecutableTransaction(Transaction transaction, BlockHeader block transaction.GasLimit = gasLimit; - BlockExecutionContext blCtx = new(block); + BlockExecutionContext blCtx = new(block, _specProvider.GetSpec(block)); _transactionProcessor.CallAndRestore(transaction, in blCtx, tracer.WithCancellation(token)); transaction.GasLimit = originalGasLimit; diff --git a/src/Nethermind/Nethermind.Evm/TransactionExtensions.cs b/src/Nethermind/Nethermind.Evm/TransactionExtensions.cs index 0bb04c021fd..f22d02b40c8 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionExtensions.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Evm @@ -14,7 +15,7 @@ public static class TransactionExtensions ? tx.SenderAddress : ContractAddress.From(tx.SenderAddress, nonce > 0 ? nonce - 1 : nonce)); - public static TxGasInfo GetGasInfo(this Transaction tx, bool is1559Enabled, BlockHeader header) + public static TxGasInfo GetGasInfo(this Transaction tx, bool is1559Enabled, BlockHeader header, IReleaseSpec spec) { UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(is1559Enabled, header.BaseFeePerGas); @@ -25,7 +26,7 @@ public static TxGasInfo GetGasInfo(this Transaction tx, bool is1559Enabled, Bloc throw new ArgumentException($"Block that contains Shard Blob Transactions should have {nameof(header.ExcessBlobGas)} set.", nameof(header.ExcessBlobGas)); } - if (!BlobGasCalculator.TryCalculateFeePerBlobGas(header, out UInt256 feePerBlobGas)) + if (!BlobGasCalculator.TryCalculateFeePerBlobGas(header, out UInt256 feePerBlobGas, spec)) { throw new OverflowException("Blob gas price calculation led to overflow."); } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs index e347490cb11..25c0e2c9ac6 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs @@ -34,4 +34,31 @@ public interface ITransactionProcessor /// Will NOT charge gas from sender account /// TransactionResult Warmup(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer); + + /// + /// Execute transaction, commit state + /// + TransactionResult Execute(Transaction transaction, in BlockHeader blockHeader, ITxTracer txTracer); + + /// + /// Call transaction, rollback state + /// + TransactionResult CallAndRestore(Transaction transaction, in BlockHeader blockHeader, ITxTracer txTracer); + + /// + /// Execute transaction, keep the state uncommitted + /// + TransactionResult BuildUp(Transaction transaction, in BlockHeader blockHeader, ITxTracer txTracer); + + /// + /// Call transaction, no validations, commit state + /// Will NOT charge gas from sender account, so stateDiff will miss gas fee + /// + TransactionResult Trace(Transaction transaction, in BlockHeader blockHeader, ITxTracer txTracer); + + /// + /// Call transaction, no validations, don't commit state + /// Will NOT charge gas from sender account + /// + TransactionResult Warmup(Transaction transaction, in BlockHeader blockHeader, ITxTracer txTracer); } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index f914553a832..5b9c745bc39 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -101,9 +101,20 @@ protected TransactionProcessorBase( _logManager = logManager; } + public TransactionResult CallAndRestore(Transaction transaction, in BlockHeader header, ITxTracer txTracer) => + ExecuteCore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), txTracer, ExecutionOptions.CommitAndRestore); + public TransactionResult CallAndRestore(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => ExecuteCore(transaction, in blCtx, txTracer, ExecutionOptions.CommitAndRestore); + public TransactionResult BuildUp(Transaction transaction, in BlockHeader header, ITxTracer txTracer) + { + // we need to treat the result of previous transaction as the original value of next transaction + // when we do not commit + WorldState.TakeSnapshot(true); + return ExecuteCore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), txTracer, ExecutionOptions.None); + } + public TransactionResult BuildUp(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) { // we need to treat the result of previous transaction as the original value of next transaction @@ -112,12 +123,21 @@ public TransactionResult BuildUp(Transaction transaction, in BlockExecutionConte return ExecuteCore(transaction, in blCtx, txTracer, ExecutionOptions.None); } + public TransactionResult Execute(Transaction transaction, in BlockHeader header, ITxTracer txTracer) => + ExecuteCore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), txTracer, ExecutionOptions.Commit); + public TransactionResult Execute(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => ExecuteCore(transaction, in blCtx, txTracer, ExecutionOptions.Commit); + public TransactionResult Trace(Transaction transaction, in BlockHeader header, ITxTracer txTracer) => + ExecuteCore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), txTracer, ExecutionOptions.NoValidation); + public TransactionResult Trace(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => ExecuteCore(transaction, in blCtx, txTracer, ExecutionOptions.NoValidation); + public TransactionResult Warmup(Transaction transaction, in BlockHeader header, ITxTracer txTracer) => + ExecuteCore(transaction, new BlockExecutionContext(header, SpecProvider.GetSpec(header)), txTracer, ExecutionOptions.Warmup); + public TransactionResult Warmup(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => ExecuteCore(transaction, in blCtx, txTracer, ExecutionOptions.Warmup); @@ -126,7 +146,7 @@ private TransactionResult ExecuteCore(Transaction tx, in BlockExecutionContext b if (tx.IsSystem()) { _systemTransactionProcessor ??= new SystemTransactionProcessor(SpecProvider, WorldState, VirtualMachine, _codeInfoRepository, _logManager); - return _systemTransactionProcessor.Execute(tx, blCtx.Header, tracer, opts); + return _systemTransactionProcessor.Execute(tx, new BlockExecutionContext(blCtx.Header, SpecProvider.GetSpec(blCtx.Header)), tracer, opts); } return Execute(tx, in blCtx, tracer, opts); @@ -502,7 +522,7 @@ protected virtual TransactionResult BuyGas(Transaction tx, BlockHeader header, I overflows = UInt256.MultiplyOverflow((UInt256)tx.GasLimit, effectiveGasPrice, out senderReservedGasPayment); if (!overflows && tx.SupportsBlobs) { - overflows = !BlobGasCalculator.TryCalculateBlobBaseFee(header, tx, out blobBaseFee); + overflows = !BlobGasCalculator.TryCalculateBlobBaseFee(header, tx, out blobBaseFee, spec); if (!overflows) { overflows = UInt256.AddOverflow(senderReservedGasPayment, blobBaseFee, out senderReservedGasPayment); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 42e3c884e2f..c4b1b5cc163 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -129,7 +129,7 @@ private bool TryGetCanonicalTransaction( { int logIndexStart = txReceipts.GetBlockLogFirstIndex(txReceipt.Index); bool is1559Enabled = _specProvider.GetSpecFor1559(block.Number).IsEip1559Enabled; - return (txReceipt, tx.GetGasInfo(is1559Enabled, block.Header), logIndexStart); + return (txReceipt, tx.GetGasInfo(is1559Enabled, block.Header, _specProvider.GetSpec(block.Header)), logIndexStart); } return (null, null, 0); @@ -292,13 +292,13 @@ private TransactionResult CallAndRestore( { callHeader.BlobGasUsed = BlobGasCalculator.CalculateBlobGas(transaction); callHeader.ExcessBlobGas = treatBlockHeaderAsParentBlock - ? BlobGasCalculator.CalculateExcessBlobGas(blockHeader, releaseSpec) + ? BlobGasCalculator.CalculateExcessBlobGas(blockHeader, releaseSpec, blockHeader) : blockHeader.ExcessBlobGas; } callHeader.MixHash = blockHeader.MixHash; callHeader.IsPostMerge = blockHeader.Difficulty == 0; transaction.Hash = transaction.CalculateHash(); - return scope.TransactionProcessor.CallAndRestore(transaction, new(callHeader), tracer); + return scope.TransactionProcessor.CallAndRestore(transaction, callHeader, tracer); } public ulong GetChainId() diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridgeContract.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridgeContract.cs index abe697c2540..451a62d40cb 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridgeContract.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridgeContract.cs @@ -6,12 +6,13 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; namespace Nethermind.Facade { public abstract class BlockchainBridgeContract : Contract { - public BlockchainBridgeContract(IAbiEncoder abiEncoder, Address contractAddress, AbiDefinition? abiDefinition = null) : base(abiEncoder, contractAddress, abiDefinition) + public BlockchainBridgeContract(IAbiEncoder abiEncoder, Address contractAddress, ISpecProvider specProvider, AbiDefinition? abiDefinition = null) : base(specProvider, abiEncoder, contractAddress, abiDefinition) { } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 59c97ea3c5c..dcf74e43e01 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -288,6 +288,7 @@ private BlockHeader GetCallHeader(BlockStateCall b MixHash = parent.MixHash, IsPostMerge = parent.Difficulty == 0, }; + result.TargetBlobCount = parent.TargetBlobCount; result.Timestamp = parent.Timestamp + 1; result.BaseFeePerGas = block.BlockOverrides is { BaseFeePerGas: not null } ? block.BlockOverrides.BaseFeePerGas.Value @@ -295,7 +296,7 @@ private BlockHeader GetCallHeader(BlockStateCall b ? 0 : BaseFeeCalculator.Calculate(parent, spec); - result.ExcessBlobGas = spec.IsEip4844Enabled ? BlobGasCalculator.CalculateExcessBlobGas(parent, spec) : (ulong?)0; + result.ExcessBlobGas = spec.IsEip4844Enabled ? BlobGasCalculator.CalculateExcessBlobGas(parent, spec, result) : (ulong?)0; return result; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 151f64efb11..4c62b4de488 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -29,8 +29,8 @@ public class SimulateBlockValidationTransactionsExecutor( UInt256? blobBaseFeeOverride) : BlockValidationTransactionsExecutor(transactionProcessor, stateProvider) { - protected override BlockExecutionContext CreateBlockExecutionContext(Block block) => - blobBaseFeeOverride is not null ? new BlockExecutionContext(block.Header, blobBaseFeeOverride.Value) : base.CreateBlockExecutionContext(block); + protected override BlockExecutionContext CreateBlockExecutionContext(Block block, IReleaseSpec spec) => + blobBaseFeeOverride is not null ? new BlockExecutionContext(block.Header, blobBaseFeeOverride.Value) : base.CreateBlockExecutionContext(block, spec); protected override void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 70f06eeb6b0..5d4dc2b30b6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -112,8 +112,9 @@ public ResultWrapper
eth_coinbase() { return ResultWrapper.Success(UInt256.Zero); } + IReleaseSpec? spec = _blockFinder.Head?.Header is null ? null : specProvider.GetSpec(_blockFinder.Head.Header); if (!BlobGasCalculator.TryCalculateFeePerBlobGas(_blockFinder.Head?.Header?.ExcessBlobGas ?? 0, - out UInt256 feePerBlobGas)) + out UInt256 feePerBlobGas, _blockFinder.Head?.Header.TargetBlobCount, spec)) { return ResultWrapper.Fail("Unable to calculate the current blob base fee"); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs index 28fe3a15d93..703af3eb611 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs @@ -108,14 +108,17 @@ private readonly record struct BlockFeeHistorySearchInfo( { BlockFeeHistorySearchInfo BlockFeeHistorySearchInfoFromBlock(Block b) { - BlobGasCalculator.TryCalculateFeePerBlobGas(b.Header, out UInt256 feePerBlobGas); + BlobGasCalculator.TryCalculateFeePerBlobGas(b.Header, out UInt256 feePerBlobGas, _specProvider.GetSpec(block.Header)); + + var maxBlobGasPerBlock = (double)(block.TargetBlobCount * 2 ?? Eip4844Constants.GetMaxBlobsPerBlock()) * Eip4844Constants.GasPerBlob; + return new( b.Number, b.BaseFeePerGas, BaseFeeCalculator.Calculate(b.Header, _specProvider.GetSpecFor1559(b.Number + 1)), feePerBlobGas == UInt256.MaxValue ? UInt256.Zero : feePerBlobGas, b.GasUsed / (double)b.GasLimit, - (b.BlobGasUsed ?? 0) / (double)Eip4844Constants.MaxBlobGasPerBlock, + (b.BlobGasUsed ?? 0) / maxBlobGasPerBlock, b.ParentHash, b.GasUsed, b.Transactions.Length, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs index 5818849ea3a..2d652ba8001 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs @@ -160,7 +160,7 @@ public ResultWrapper proof_getTransactionReceipt(Hash256 txHas int logIndexStart = _receiptFinder.Get(block).GetBlockLogFirstIndex(receipt.Index); - receiptWithProof.Receipt = new ReceiptForRpc(txHash, receipt, tx?.GetGasInfo(isEip1559Enabled, block.Header) ?? new(), logIndexStart); + receiptWithProof.Receipt = new ReceiptForRpc(txHash, receipt, tx?.GetGasInfo(isEip1559Enabled, block.Header, _specProvider.GetSpec(block.Header)) ?? new(), logIndexStart); receiptWithProof.ReceiptProof = BuildReceiptProofs(block.Header, receipts, receipt.Index); receiptWithProof.TxProof = BuildTxProofs(txs, _specProvider.GetSpec(block.Header), receipt.Index); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs index 7ebf603cfcc..51829e0102f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs @@ -37,7 +37,7 @@ public static ResultWrapper GetBlockReceipts(this IReceiptFinde IEnumerable result = receipts .Zip(block.Transactions, (r, t) => { - return new ReceiptForRpc(t.Hash, r, t.GetGasInfo(isEip1559Enabled, block.Header), receipts.GetBlockLogFirstIndex(r.Index)); + return new ReceiptForRpc(t.Hash, r, t.GetGasInfo(isEip1559Enabled, block.Header, specProvider.GetSpec(block.Header)), receipts.GetBlockLogFirstIndex(r.Index)); }); ReceiptForRpc[] resultAsArray = result.ToArray(); return ResultWrapper.Success(resultAsArray); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index f1e2ace6075..36ee70dae5a 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -63,9 +63,9 @@ int ErrorCode [TestCase( "0xe97d919a17fa5011ff3a08ffb07657ed9e1aaf5ff649888e5d7f605006caf598", - "0xdd9be69fe6ed616f44d53576f430c1c7720ed0e7bff59478539a4a43dbb3bf1f", + "0x97549f9f95d97a519112e5d12dddd9f8a9629b8d14e4ee52fc8425da694c2c68", "0xd75d320c3a98a02ec7fe2abdcb1769bd063fec04d73f1735810f365ac12bc4ba", - "0x3c6a8926870bdeff")] + "0xd4b4088d187939ee")] public override Task Should_process_block_as_expected_V4(string latestValidHash, string blockHash, string stateRoot, string payloadId) => base.Should_process_block_as_expected_V4(latestValidHash, blockHash, stateRoot, payloadId); @@ -141,7 +141,7 @@ protected override IBlockProcessor CreateBlockProcessor() }; WithdrawalContractFactory withdrawalContractFactory = new(_api.ChainSpec!.EngineChainSpecParametersProvider - .GetChainSpecParameters(), _api.AbiEncoder); + .GetChainSpecParameters(), _api.AbiEncoder, _api.SpecProvider); WithdrawalProcessor = new AuraWithdrawalProcessor( withdrawalContractFactory.Create(TxProcessor), LogManager diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs index 9dd11bc4de6..e6016e7d378 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs @@ -70,7 +70,7 @@ protected override BlockProcessor CreateBlockProcessor( { var withdrawalContractFactory = new WithdrawalContractFactory( _auraApi.ChainSpec.EngineChainSpecParametersProvider - .GetChainSpecParameters(), _auraApi.AbiEncoder); + .GetChainSpecParameters(), _auraApi.AbiEncoder, specProvider); return new AuRaMergeBlockProcessor( specProvider, diff --git a/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs b/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs index 4f6b82d7595..3a3007370f5 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs @@ -6,6 +6,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; @@ -23,8 +24,9 @@ public class WithdrawalContract : CallableContract, IWithdrawalContract public WithdrawalContract( ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, - Address contractAddress) - : base(transactionProcessor, abiEncoder, contractAddress) { } + Address contractAddress, + ISpecProvider specProvider) + : base(transactionProcessor, abiEncoder, contractAddress, specProvider) { } public void ExecuteWithdrawals(BlockHeader blockHeader, UInt256 failedMaxCount, IList amounts, IList
addresses) { diff --git a/src/Nethermind/Nethermind.Merge.AuRa/InitializationSteps/InitializeBlockchainAuRaMerge.cs b/src/Nethermind/Nethermind.Merge.AuRa/InitializationSteps/InitializeBlockchainAuRaMerge.cs index 700fb7ccadd..c4fad48cc40 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/InitializationSteps/InitializeBlockchainAuRaMerge.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/InitializationSteps/InitializeBlockchainAuRaMerge.cs @@ -37,7 +37,7 @@ protected override AuRaBlockProcessor NewAuraBlockProcessor(ITxFilter txFilter, IDictionary> rewriteBytecode = _parameters.RewriteBytecode; ContractRewriter? contractRewriter = rewriteBytecode?.Count > 0 ? new ContractRewriter(rewriteBytecode) : null; - WithdrawalContractFactory withdrawalContractFactory = new WithdrawalContractFactory(_parameters, _api.AbiEncoder); + WithdrawalContractFactory withdrawalContractFactory = new WithdrawalContractFactory(_parameters, _api.AbiEncoder, _api.SpecProvider!); IWorldState worldState = _api.WorldState!; ITransactionProcessor transactionProcessor = _api.TransactionProcessor!; diff --git a/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/WithdrawalContractFactory.cs b/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/WithdrawalContractFactory.cs index 1f0711feb9b..ee515f79deb 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/WithdrawalContractFactory.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/WithdrawalContractFactory.cs @@ -5,9 +5,9 @@ using Nethermind.Abi; using Nethermind.Consensus.AuRa.Config; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Merge.AuRa.Contracts; -using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Merge.AuRa.Withdrawals; @@ -15,19 +15,21 @@ public class WithdrawalContractFactory : IWithdrawalContractFactory { private readonly IAbiEncoder _abiEncoder; private readonly Address _contractAddress; + private readonly ISpecProvider _specProvider; - public WithdrawalContractFactory(AuRaChainSpecEngineParameters parameters, IAbiEncoder abiEncoder) + public WithdrawalContractFactory(AuRaChainSpecEngineParameters parameters, IAbiEncoder abiEncoder, ISpecProvider specProvider) { ArgumentNullException.ThrowIfNull(parameters); _abiEncoder = abiEncoder ?? throw new ArgumentNullException(nameof(abiEncoder)); _contractAddress = parameters.WithdrawalContractAddress; + _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); } public IWithdrawalContract Create(ITransactionProcessor processor) { ArgumentNullException.ThrowIfNull(processor); - return new WithdrawalContract(processor, _abiEncoder, _contractAddress); + return new WithdrawalContract(processor, _abiEncoder, _contractAddress, _specProvider); } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V4.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V4.cs index 7918db73e3c..7e48641c9ec 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V4.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V4.cs @@ -28,9 +28,9 @@ public partial class EngineModuleTests { [TestCase( "0x948f67f47376af5d09cc39ec25a84c84774f14b2e80289064c2de73db33cc573", - "0xb8e06e1a99d81358edd0a581fef980aff00cc9c316da8119bec7a13a6e6fa167", + "0x93b5a7c9023dacbec5db5034194dc759e2cff692f0e9d9a5899c190383bf42dc", "0xa272b2f949e4a0e411c9b45542bd5d0ef3c311b5f26c4ed6b7a8d4f605a91154", - "0x96b752d22831ad92")] + "0x3b94afaabd539312")] public virtual async Task Should_process_block_as_expected_V4(string latestValidHash, string blockHash, string stateRoot, string payloadId) { @@ -57,7 +57,9 @@ public virtual async Task Should_process_block_as_expected_V4(string latestValid prevRandao = prevRandao.ToString(), suggestedFeeRecipient = feeRecipient.ToString(), withdrawals, - parentBeaconBLockRoot = Keccak.Zero + parentBeaconBLockRoot = Keccak.Zero, + targetBlobCount = 0, + maxBlobCount = 0, }; string?[] @params = new string?[] { @@ -65,7 +67,7 @@ public virtual async Task Should_process_block_as_expected_V4(string latestValid }; string expectedPayloadId = payloadId; - string response = await RpcTest.TestSerializedRequest(rpc, "engine_forkchoiceUpdatedV3", @params!); + string response = await RpcTest.TestSerializedRequest(rpc, "engine_forkchoiceUpdatedV4", @params!); JsonRpcSuccessResponse? successResponse = chain.JsonSerializer.Deserialize(response); successResponse.Should().NotBeNull(); @@ -107,6 +109,7 @@ public virtual async Task Should_process_block_as_expected_V4(string latestValid ParentBeaconBlockRoot = Keccak.Zero, ReceiptsRoot = chain.BlockTree.Head!.ReceiptsRoot!, StateRoot = new(stateRoot), + TargetBlobCount = 0, }, Array.Empty(), Array.Empty(), @@ -276,7 +279,15 @@ private async Task BuildAndGetPayloadOnBranchV4( ulong timestamp, Hash256 random, Address feeRecipient) { PayloadAttributes payloadAttributes = - new() { Timestamp = timestamp, PrevRandao = random, SuggestedFeeRecipient = feeRecipient, ParentBeaconBlockRoot = Keccak.Zero, Withdrawals = [] }; + new() + { + Timestamp = timestamp, + PrevRandao = random, + SuggestedFeeRecipient = feeRecipient, + ParentBeaconBlockRoot = Keccak.Zero, + Withdrawals = [], + TargetBlobCount = 0, + }; // we're using payloadService directly, because we can't use fcU for branch string payloadId = chain.PayloadPreparationService!.StartPreparingPayload(parentHeader, payloadAttributes)!; @@ -469,9 +480,10 @@ private async Task BuildAndGetPayloadResultV4( SuggestedFeeRecipient = feeRecipient, ParentBeaconBlockRoot = Keccak.Zero, Withdrawals = withdrawals, + TargetBlobCount = 0, }; - ResultWrapper result = rpc.engine_forkchoiceUpdatedV3(forkchoiceState, payloadAttributes).Result; + ResultWrapper result = rpc.engine_forkchoiceUpdatedV4(forkchoiceState, payloadAttributes).Result; string? payloadId = result.Data.PayloadId; if (waitForBlockImprovement) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs index 3004e0c26b9..a7427b31af6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs @@ -101,7 +101,7 @@ protected virtual void AmendHeader(BlockHeader blockHeader, BlockHeader parent, if (spec.IsEip4844Enabled) { blockHeader.BlobGasUsed = 0; - blockHeader.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec); + blockHeader.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec, blockHeader); } } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs index d1c7f7c6554..54614d4b82d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs @@ -117,6 +117,12 @@ public byte[][] Transactions [JsonIgnore] public Hash256? ParentBeaconBlockRoot { get; set; } + /// + /// Gets or sets as defined in + /// EIP-7742. + /// + public virtual ulong? TargetBlobCount { get; set; } + public static ExecutionPayload Create(Block block) => Create(block); protected static TExecutionPayload Create(Block block) where TExecutionPayload : ExecutionPayload, new() diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs index e0d65da1215..1d0643c96aa 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs @@ -26,6 +26,8 @@ public class ExecutionPayloadV4 : ExecutionPayloadV3, IExecutionPayloadFactory(block); ConsensusRequest[]? blockRequests = block.Requests; (executionPayload.DepositRequests, executionPayload.WithdrawalRequests, executionPayload.ConsolidationRequests) = blockRequests?.SplitRequests() ?? ([], [], []); + + executionPayload.TargetBlobCount = block.TargetBlobCount; return executionPayload; } @@ -70,6 +72,8 @@ public override bool TryGetBlock([NotNullWhen(true)] out Block? block, UInt256? block.Header.RequestsRoot = Keccak.EmptyTreeHash; } + block.Header.TargetBlobCount = TargetBlobCount; + return true; } @@ -98,4 +102,11 @@ public override bool ValidateFork(ISpecProvider specProvider) => /// [JsonRequired] public sealed override ConsolidationRequest[]? ConsolidationRequests { get; set; } + + /// + /// Gets or sets as defined in + /// EIP-7742. + /// + [JsonRequired] + public sealed override ulong? TargetBlobCount { get; set; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Prague.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Prague.cs index a787498000e..b1afa00b50e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Prague.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Prague.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Consensus; +using Nethermind.Consensus.Producers; using Nethermind.Core.Crypto; using Nethermind.JsonRpc; using Nethermind.Merge.Plugin.Data; @@ -29,4 +30,7 @@ public Task> engine_newPayloadV4(ExecutionPayload public Task>> engine_getPayloadBodiesByRangeV2(long start, long count) => _executionGetPayloadBodiesByRangeV2Handler.Handle(start, count); + + public Task> engine_forkchoiceUpdatedV4(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes = null) + => ForkchoiceUpdated(forkchoiceState, payloadAttributes, EngineApiVersions.Prague); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs index 37c244ae47f..bfd5851ecfc 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs @@ -17,7 +17,7 @@ public partial class EngineRpcModule : IEngineRpcModule { private readonly IHandler, IEnumerable> _capabilitiesHandler; - private readonly ISpecProvider _specProvider; + protected readonly ISpecProvider _specProvider; protected readonly ILogger _logger; public EngineRpcModule( diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/EngineRpcCapabilitiesProvider.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/EngineRpcCapabilitiesProvider.cs index 57d1ab5f5bd..6dc4cad1805 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/EngineRpcCapabilitiesProvider.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/EngineRpcCapabilitiesProvider.cs @@ -53,13 +53,7 @@ public EngineRpcCapabilitiesProvider(ISpecProvider specProvider) _capabilities[nameof(IEngineRpcModule.engine_newPayloadV4)] = (spec.RequestsEnabled, spec.RequestsEnabled); _capabilities[nameof(IEngineRpcModule.engine_getPayloadBodiesByHashV2)] = (spec.RequestsEnabled, false); _capabilities[nameof(IEngineRpcModule.engine_getPayloadBodiesByRangeV2)] = (spec.RequestsEnabled, false); - #endregion - - #region Prague - _capabilities[nameof(IEngineRpcModule.engine_getPayloadV4)] = (spec.RequestsEnabled, spec.RequestsEnabled); - _capabilities[nameof(IEngineRpcModule.engine_newPayloadV4)] = (spec.RequestsEnabled, spec.RequestsEnabled); - _capabilities[nameof(IEngineRpcModule.engine_getPayloadBodiesByHashV2)] = (spec.RequestsEnabled, false); - _capabilities[nameof(IEngineRpcModule.engine_getPayloadBodiesByRangeV2)] = (spec.RequestsEnabled, false); + _capabilities[nameof(IEngineRpcModule.engine_forkchoiceUpdatedV4)] = (spec.IsEip7742Enabled, spec.IsEip7742Enabled); #endregion } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs index b574f1803f3..5bde22c1fa9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs @@ -315,7 +315,8 @@ private ResultWrapper StartBuildingPayload(Block newH ParentBeaconBlockRoot = newHeadBlock.ParentHash, // it doesn't matter PrevRandao = newHeadBlock.ParentHash ?? Keccak.Zero, // it doesn't matter Withdrawals = Array.Empty(), - SuggestedFeeRecipient = Address.Zero + SuggestedFeeRecipient = Address.Zero, + TargetBlobCount = newHeadBlock.TargetBlobCount, }; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Prague.cs b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Prague.cs index 15f3577ce42..9770130211c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Prague.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Prague.cs @@ -36,4 +36,11 @@ public partial interface IEngineRpcModule : IRpcModule IsSharable = true, IsImplemented = true)] Task>> engine_getPayloadBodiesByRangeV2(long start, long count); + + [JsonRpcMethod( + Description = "Applies fork choice and starts building a new block if payload attributes are present.", + IsSharable = true, + IsImplemented = true)] + public Task> engine_forkchoiceUpdatedV4(ForkchoiceStateV1 forkchoiceState, + PayloadAttributes? payloadAttributes = null); } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index e5933bb58f6..866083b87dd 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -92,14 +92,15 @@ public OptimismEthRpcModule( Block? block = searchResult.Object!; OptimismTxReceipt[] receipts = receiptFinder.Get(block).Cast().ToArray() ?? new OptimismTxReceipt[block.Transactions.Length]; - bool isEip1559Enabled = specProvider.GetSpec(block.Header).IsEip1559Enabled; + IReleaseSpec spec = specProvider.GetSpec(block.Header); + bool isEip1559Enabled = spec.IsEip1559Enabled; L1BlockGasInfo l1BlockGasInfo = new(block, opSpecHelper); OptimismReceiptForRpc[]? result = [.. receipts .Zip(block.Transactions, (r, t) => { - return new OptimismReceiptForRpc(t.Hash!, r, t.GetGasInfo(isEip1559Enabled, block.Header), l1BlockGasInfo.GetTxGasInfo(t), receipts.GetBlockLogFirstIndex(r.Index)); + return new OptimismReceiptForRpc(t.Hash!, r, t.GetGasInfo(isEip1559Enabled, block.Header, spec), l1BlockGasInfo.GetTxGasInfo(t), receipts.GetBlockLogFirstIndex(r.Index)); })]; return ResultWrapper.Success(result); } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index 98dce2b0610..dbeab5c4489 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -94,6 +94,11 @@ public class HeaderDecoder : IRlpValueDecoder, IRlpStreamDecoder= 6 && decoderContext.Position != headerCheck) + { + blockHeader.TargetBlobCount = decoderContext.DecodeULong(); + } } @@ -186,6 +191,11 @@ public class HeaderDecoder : IRlpValueDecoder, IRlpStreamDecoder= 6 && rlpStream.Position != headerCheck) + { + blockHeader.TargetBlobCount = rlpStream.DecodeULong(); + } } if ((rlpBehaviors & RlpBehaviors.AllowExtraBytes) != RlpBehaviors.AllowExtraBytes) @@ -260,6 +270,11 @@ public void Encode(RlpStream rlpStream, BlockHeader? header, RlpBehaviors rlpBeh { rlpStream.Encode(header.RequestsRoot); } + + if (header.TargetBlobCount is not null) + { + rlpStream.Encode(header.TargetBlobCount.GetValueOrDefault()); + } } public Rlp Encode(BlockHeader? item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) @@ -298,11 +313,15 @@ private static int GetContentLength(BlockHeader? item, RlpBehaviors rlpBehaviors + Rlp.LengthOf(item.Timestamp) + Rlp.LengthOf(item.ExtraData) + (item.BaseFeePerGas.IsZero ? 0 : Rlp.LengthOf(item.BaseFeePerGas)) - + (item.WithdrawalsRoot is null && item.BlobGasUsed is null && item.ExcessBlobGas is null ? 0 : Rlp.LengthOfKeccakRlp) + + (item.WithdrawalsRoot is null && item.BlobGasUsed is null && + item.ExcessBlobGas is null + ? 0 + : Rlp.LengthOfKeccakRlp) + (item.ParentBeaconBlockRoot is null ? 0 : Rlp.LengthOfKeccakRlp) + (item.BlobGasUsed is null ? 0 : Rlp.LengthOf(item.BlobGasUsed.Value)) + (item.ExcessBlobGas is null ? 0 : Rlp.LengthOf(item.ExcessBlobGas.Value)) - + (item.RequestsRoot is null ? 0 : Rlp.LengthOf(item.RequestsRoot)); + + (item.RequestsRoot is null ? 0 : Rlp.LengthOf(item.RequestsRoot)) + + (item.TargetBlobCount is null ? 0 : Rlp.LengthOf(item.TargetBlobCount)); if (notForSealing) { diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs index 68616f48c68..33f7f1fca0d 100644 --- a/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs +++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs @@ -121,7 +121,7 @@ protected override void InitP2P(IPAddress _) P2P = Substitute.For(); } - protected override IShutterEon InitEon() + protected override IShutterEon InitEon(ISpecProvider specProvider) { IShutterEon eon = Substitute.For(); eon.GetCurrentEonInfo().Returns(_ => eventSimulator.GetCurrentEonInfo()); diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterEventSimulator.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterEventSimulator.cs index 06460d48b08..5198dd6b357 100644 --- a/src/Nethermind/Nethermind.Shutter.Test/ShutterEventSimulator.cs +++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterEventSimulator.cs @@ -14,7 +14,7 @@ using Nethermind.Serialization.Rlp; using Nethermind.Core.Test.Builders; using Nethermind.Abi; - +using Nethermind.Core.Specs; using G1 = Nethermind.Crypto.Bls.P1; using G2 = Nethermind.Crypto.Bls.P2; using EncryptedMessage = Nethermind.Shutter.ShutterCrypto.EncryptedMessage; @@ -45,7 +45,8 @@ public ShutterEventSimulator( ulong threshold, ulong slot, IAbiEncoder abiEncoder, - Address sequencerContractAddress + Address sequencerContractAddress, + ISpecProvider specProvider ) { _rnd = rnd; @@ -56,7 +57,7 @@ Address sequencerContractAddress _threshold = threshold; _abiEncoder = abiEncoder; _sequencerContractAddress = sequencerContractAddress; - _transactionSubmittedAbi = new SequencerContract(sequencerContractAddress).TransactionSubmittedAbi; + _transactionSubmittedAbi = new SequencerContract(sequencerContractAddress, specProvider).TransactionSubmittedAbi; _defaultMaxKeyCount = (int)Math.Floor((decimal)ShutterTestsCommon.Cfg.EncryptedGasLimit / DefaultGasLimit); _eventSource = EmitEvents(); diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs index 5f0689493b0..f1557c73531 100644 --- a/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs +++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs @@ -78,7 +78,8 @@ public static ShutterEventSimulator InitEventSimulator(Random rnd) Threshold, InitialSlot, AbiEncoder, - new(Cfg.SequencerContractAddress!) + new(Cfg.SequencerContractAddress!), + SpecProvider ); public static Timestamper InitTimestamper(ulong slotTimestamp, ulong offsetMs) diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterTxLoaderTests.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterTxLoaderTests.cs index fa428ea8694..e81cbc8b40f 100644 --- a/src/Nethermind/Nethermind.Shutter.Test/ShutterTxLoaderTests.cs +++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterTxLoaderTests.cs @@ -9,6 +9,7 @@ using Nethermind.Merge.Plugin; using Nethermind.Merge.Plugin.Data; using Nethermind.Abi; +using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Merge.Plugin.Test; @@ -17,27 +18,7 @@ namespace Nethermind.Shutter.Test; [TestFixture] class ShutterTxLoaderTests : EngineModuleTests { - private class ShutterEventSimulatorHalfInvalid(Random rnd, ulong chainId, ulong threshold, ulong slot, IAbiEncoder abiEncoder, Address sequencerContractAddress) : ShutterEventSimulator(rnd, chainId, threshold, slot, abiEncoder, sequencerContractAddress) - { - private readonly Transaction _validTx = Build.A.Transaction.WithChainId(chainId).Signed().TestObject; - private readonly Transaction _invalidTx = Build.A.Transaction.TestObject; - protected override IEnumerable EmitEvents() - { - IEnumerable EmitHalfInvalid() - { - bool valid = false; - while (true) - { - valid = !valid; - yield return valid ? _validTx : _invalidTx; - } - } - - return EmitEvents(EmitDefaultEons(), EmitHalfInvalid()); - } - } - - private class ShutterEventSimulatorHalfNextEon(Random rnd, ulong chainId, ulong threshold, ulong slot, IAbiEncoder abiEncoder, Address sequencerContractAddress) : ShutterEventSimulator(rnd, chainId, threshold, slot, abiEncoder, sequencerContractAddress) + private class ShutterEventSimulatorHalfNextEon(Random rnd, ulong chainId, ulong threshold, ulong slot, IAbiEncoder abiEncoder, Address sequencerContractAddress, ISpecProvider specProvider) : ShutterEventSimulator(rnd, chainId, threshold, slot, abiEncoder, sequencerContractAddress, specProvider) { protected override IEnumerable EmitEvents() { @@ -86,7 +67,8 @@ public async Task Can_load_and_filter_transactions() ShutterTestsCommon.Threshold, ShutterTestsCommon.InitialSlot, ShutterTestsCommon.AbiEncoder, - new(ShutterTestsCommon.Cfg.SequencerContractAddress!) + new(ShutterTestsCommon.Cfg.SequencerContractAddress!), + ShutterTestsCommon.SpecProvider ); using var chain = (ShutterTestBlockchain)await new ShutterTestBlockchain(rnd, null, eventSimulator).Build(ShutterTestsCommon.SpecProvider); @@ -199,7 +181,8 @@ public async Task Can_load_transactions_with_overlapping_eons() ShutterTestsCommon.Threshold, ShutterTestsCommon.InitialSlot, ShutterTestsCommon.AbiEncoder, - new(ShutterTestsCommon.Cfg.SequencerContractAddress!) + new(ShutterTestsCommon.Cfg.SequencerContractAddress!), + ShutterTestsCommon.SpecProvider ); using var chain = (ShutterTestBlockchain)await new ShutterTestBlockchain(rnd, null, eventSimulator).Build(ShutterTestsCommon.SpecProvider); diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterValidatorRegistryTests.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterValidatorRegistryTests.cs index 0a41c7bbd03..e84e68845df 100644 --- a/src/Nethermind/Nethermind.Shutter.Test/ShutterValidatorRegistryTests.cs +++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterValidatorRegistryTests.cs @@ -12,7 +12,7 @@ using Nethermind.Shutter.Config; using Nethermind.Crypto; using Nethermind.Core.Crypto; - +using Nethermind.Core.Specs; using Update = (byte[] Message, byte[] Signature); using G1 = Nethermind.Crypto.Bls.P1; @@ -32,7 +32,8 @@ public void Can_check_if_registered() Address.Zero, LimboLogs.Instance, ShutterTestsCommon.ChainId, - 1); + 1, + Substitute.For()); ShutterValidatorsInfo validatorsInfo = new(); List<(uint, Update)> updates = []; diff --git a/src/Nethermind/Nethermind.Shutter/Contracts/KeyBroadcastContract.cs b/src/Nethermind/Nethermind.Shutter/Contracts/KeyBroadcastContract.cs index b73ff06897e..7cf337d80b2 100644 --- a/src/Nethermind/Nethermind.Shutter/Contracts/KeyBroadcastContract.cs +++ b/src/Nethermind/Nethermind.Shutter/Contracts/KeyBroadcastContract.cs @@ -4,11 +4,12 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; namespace Nethermind.Shutter.Contracts; -public class KeyBroadcastContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) : CallableContract(transactionProcessor, abiEncoder, contractAddress), IKeyBroadcastContract +public class KeyBroadcastContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, ISpecProvider specProvider) : CallableContract(transactionProcessor, abiEncoder, contractAddress, specProvider), IKeyBroadcastContract { public byte[] GetEonKey(BlockHeader blockHeader, in ulong eon) { diff --git a/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetContract.cs b/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetContract.cs index aba64940166..af3f9ba7a35 100644 --- a/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetContract.cs +++ b/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetContract.cs @@ -4,11 +4,12 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; namespace Nethermind.Shutter.Contracts; -public class KeyperSetContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) : CallableContract(transactionProcessor, abiEncoder, contractAddress), IKeyperSetContract +public class KeyperSetContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, ISpecProvider specProvider) : CallableContract(transactionProcessor, abiEncoder, contractAddress, specProvider), IKeyperSetContract { public bool IsFinalized(BlockHeader blockHeader) { diff --git a/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetManagerContract.cs b/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetManagerContract.cs index 8f49d1fc81a..890680a37e7 100644 --- a/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetManagerContract.cs +++ b/src/Nethermind/Nethermind.Shutter/Contracts/KeyperSetManagerContract.cs @@ -4,11 +4,12 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; namespace Nethermind.Shutter.Contracts; -public class KeyperSetManagerContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) : CallableContract(transactionProcessor, abiEncoder, contractAddress), IKeyperSetManagerContract +public class KeyperSetManagerContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, ISpecProvider specProvider) : CallableContract(transactionProcessor, abiEncoder, contractAddress, specProvider), IKeyperSetManagerContract { public Address GetKeyperSetAddress(BlockHeader blockHeader, in ulong index) { diff --git a/src/Nethermind/Nethermind.Shutter/Contracts/SequencerContract.cs b/src/Nethermind/Nethermind.Shutter/Contracts/SequencerContract.cs index 115b27d9b2e..e43e84c1ae7 100644 --- a/src/Nethermind/Nethermind.Shutter/Contracts/SequencerContract.cs +++ b/src/Nethermind/Nethermind.Shutter/Contracts/SequencerContract.cs @@ -4,6 +4,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts; using Nethermind.Core; +using Nethermind.Core.Specs; namespace Nethermind.Shutter.Contracts; @@ -12,8 +13,8 @@ public class SequencerContract : Contract, ISequencerContract public AbiEncodingInfo TransactionSubmittedAbi { get => _transactionSubmittedAbi; } private readonly AbiEncodingInfo _transactionSubmittedAbi; - public SequencerContract(Address address) - : base(null, address) + public SequencerContract(Address address, ISpecProvider specProvider) + : base(specProvider, null, address) { _transactionSubmittedAbi = AbiDefinition.GetEvent(nameof(ISequencerContract.TransactionSubmitted)).GetCallInfo(AbiEncodingStyle.None); } diff --git a/src/Nethermind/Nethermind.Shutter/Contracts/ValidatorRegistryContract.cs b/src/Nethermind/Nethermind.Shutter/Contracts/ValidatorRegistryContract.cs index 1c72f1ea222..33f2fa4ef8e 100644 --- a/src/Nethermind/Nethermind.Shutter/Contracts/ValidatorRegistryContract.cs +++ b/src/Nethermind/Nethermind.Shutter/Contracts/ValidatorRegistryContract.cs @@ -14,7 +14,7 @@ using Nethermind.Crypto; using Nethermind.Shutter.Config; using System.Linq; - +using Nethermind.Core.Specs; using Update = (byte[] Message, byte[] Signature); namespace Nethermind.Shutter.Contracts; @@ -25,8 +25,9 @@ public class ValidatorRegistryContract( Address contractAddress, ILogManager logManager, ulong chainId, - ulong messageVersion) - : CallableContract(transactionProcessor, abiEncoder, contractAddress), IValidatorRegistryContract + ulong messageVersion, + ISpecProvider specProvider) + : CallableContract(transactionProcessor, abiEncoder, contractAddress, specProvider), IValidatorRegistryContract { private readonly ILogger _logger = logManager.GetClassLogger(); diff --git a/src/Nethermind/Nethermind.Shutter/ShutterApi.cs b/src/Nethermind/Nethermind.Shutter/ShutterApi.cs index 72e6968a31b..15d90e5b050 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterApi.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterApi.cs @@ -83,7 +83,7 @@ IPAddress ip Time = InitTime(specProvider, timestamper); TxLoader = new(logFinder, _cfg, Time, specProvider, ecdsa, abiEncoder, logManager); - Eon = InitEon(); + Eon = InitEon(specProvider); BlockHandler = new ShutterBlockHandler( specProvider.ChainId, _cfg, @@ -97,7 +97,8 @@ IPAddress ip Time, logManager, _slotLength, - BlockWaitCutoff); + BlockWaitCutoff, + specProvider); TxSource = new ShutterTxSource(TxLoader, _cfg, Time, logManager); @@ -154,8 +155,8 @@ protected virtual void InitP2P(IPAddress ip) P2P = new ShutterP2P(_cfg, _logManager, _fileSystem, _keyStoreConfig, ip); } - protected virtual IShutterEon InitEon() - => new ShutterEon(_readOnlyBlockTree, _txProcessingEnvFactory, _abiEncoder, _cfg, _logManager); + protected virtual IShutterEon InitEon(ISpecProvider specProvider) + => new ShutterEon(_readOnlyBlockTree, _txProcessingEnvFactory, _abiEncoder, _cfg, _logManager, specProvider); protected virtual ShutterTime InitTime(ISpecProvider specProvider, ITimestamper timestamper) => new(specProvider.BeaconChainGenesisTimestamp!.Value * 1000, timestamper, _slotLength, _blockUpToDateCutoff); diff --git a/src/Nethermind/Nethermind.Shutter/ShutterBlockHandler.cs b/src/Nethermind/Nethermind.Shutter/ShutterBlockHandler.cs index 68f4c7d1e3c..8ffcd5067b1 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterBlockHandler.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterBlockHandler.cs @@ -16,6 +16,7 @@ using Nethermind.Core.Crypto; using Nethermind.Blockchain; using Nethermind.Core.Collections; +using Nethermind.Core.Specs; using Nethermind.Shutter.Config; namespace Nethermind.Shutter; @@ -42,6 +43,7 @@ public class ShutterBlockHandler : IShutterBlockHandler private readonly Dictionary> _blockWaitTasks = []; private readonly LruCache _slotToBlockHash = new(5, "Slot to block hash mapping"); private readonly object _syncObject = new(); + private readonly ISpecProvider _specProvider; public ShutterBlockHandler( ulong chainId, @@ -56,7 +58,8 @@ public ShutterBlockHandler( ShutterTime time, ILogManager logManager, TimeSpan slotLength, - TimeSpan blockWaitCutoff) + TimeSpan blockWaitCutoff, + ISpecProvider specProvider) { _chainId = chainId; _cfg = cfg; @@ -73,6 +76,7 @@ public ShutterBlockHandler( _envFactory = envFactory; _slotLength = slotLength; _blockWaitCutoff = blockWaitCutoff; + _specProvider = specProvider; _blockTree.NewHeadBlock += OnNewHeadBlock; } @@ -200,7 +204,7 @@ private void CheckAllValidatorsRegistered(in BlockHeader parent, in ShutterValid IReadOnlyTxProcessingScope scope = _envFactory.Create().Build(parent.StateRoot!); ITransactionProcessor processor = scope.TransactionProcessor; - ValidatorRegistryContract validatorRegistryContract = new(processor, _abiEncoder, new(_cfg.ValidatorRegistryContractAddress!), _logManager, _chainId, _cfg.ValidatorRegistryMessageVersion!); + ValidatorRegistryContract validatorRegistryContract = new(processor, _abiEncoder, new(_cfg.ValidatorRegistryContractAddress!), _logManager, _chainId, _cfg.ValidatorRegistryMessageVersion!, _specProvider); if (validatorRegistryContract.IsRegistered(parent, validatorsInfo, out HashSet unregistered)) { if (_logger.IsInfo) _logger.Info($"All Shutter validator keys are registered."); diff --git a/src/Nethermind/Nethermind.Shutter/ShutterEon.cs b/src/Nethermind/Nethermind.Shutter/ShutterEon.cs index b330d36be26..60a6d681656 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterEon.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterEon.cs @@ -11,6 +11,7 @@ using Nethermind.Shutter.Config; using Nethermind.Consensus.Processing; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; namespace Nethermind.Shutter; @@ -19,7 +20,8 @@ public class ShutterEon( ReadOnlyTxProcessingEnvFactory envFactory, IAbiEncoder abiEncoder, IShutterConfig shutterConfig, - ILogManager logManager) : IShutterEon + ILogManager logManager, + ISpecProvider specProvider) : IShutterEon { private IShutterEon.Info? _currentInfo; private readonly Address _keyBroadcastContractAddress = new(shutterConfig.KeyBroadcastContractAddress!); @@ -36,20 +38,20 @@ public void Update(BlockHeader header) try { - KeyperSetManagerContract keyperSetManagerContract = new(processor, abiEncoder, _keyperSetManagerContractAddress); + KeyperSetManagerContract keyperSetManagerContract = new(processor, abiEncoder, _keyperSetManagerContractAddress, specProvider); ulong eon = keyperSetManagerContract.GetKeyperSetIndexByBlock(header, (ulong)header.Number + 1); if (_currentInfo is null || _currentInfo.Value.Eon != eon) { Address keyperSetContractAddress = keyperSetManagerContract.GetKeyperSetAddress(header, eon); - KeyperSetContract keyperSetContract = new(processor, abiEncoder, keyperSetContractAddress); + KeyperSetContract keyperSetContract = new(processor, abiEncoder, keyperSetContractAddress, specProvider); if (keyperSetContract.IsFinalized(header)) { ulong threshold = keyperSetContract.GetThreshold(header); Address[] addresses = keyperSetContract.GetMembers(header); - KeyBroadcastContract keyBroadcastContract = new(processor, abiEncoder, _keyBroadcastContractAddress); + KeyBroadcastContract keyBroadcastContract = new(processor, abiEncoder, _keyBroadcastContractAddress, specProvider); byte[] eonKey = keyBroadcastContract.GetEonKey(blockTree.Head!.Header, eon); // update atomically diff --git a/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs b/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs index 0e8d2f814b3..f38ab883b9a 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs @@ -33,7 +33,7 @@ public class ShutterTxLoader( ILogManager logManager) { private readonly ShutterLogScanner _logScanner = new( - new(new Address(cfg.SequencerContractAddress!)), + new(new Address(cfg.SequencerContractAddress!), specProvider), logFinder, logManager, abiEncoder); diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index 49f39bbaf0d..7613bef78e6 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -113,6 +113,7 @@ public OverridableReleaseSpec(IReleaseSpec spec) public bool IsEip3541Enabled => _spec.IsEip3541Enabled; public bool IsEip4844Enabled => _spec.IsEip4844Enabled; public bool IsRip7212Enabled => _spec.IsRip7212Enabled; + public bool IsEip7742Enabled => _spec.IsEip7742Enabled; public bool IsOpGraniteEnabled => _spec.IsOpGraniteEnabled; private bool? _isOntakeEnabled; diff --git a/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs b/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs index 7fd7e8c348d..63bcc2a2101 100644 --- a/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs +++ b/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs @@ -22,6 +22,7 @@ protected Prague() IsEip7251Enabled = true; IsRip7212Enabled = true; Eip2935ContractAddress = Eip2935Constants.BlockHashHistoryAddress; + IsEip7742Enabled = true; } public new static IReleaseSpec Instance => LazyInitializer.EnsureInitialized(ref _instance, () => new Prague()); diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs index dfb34cf9faf..d65486d9238 100644 --- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs @@ -82,6 +82,7 @@ public bool IsEip1559Enabled public bool IsEip4895Enabled { get; set; } public bool IsEip4844Enabled { get; set; } public bool IsRip7212Enabled { get; set; } + public bool IsEip7742Enabled { get; set; } public bool IsOpGraniteEnabled { get; set; } public bool IsEip5656Enabled { get; set; } public bool IsEip6780Enabled { get; set; } diff --git a/src/Nethermind/Nethermind.Taiko/BlockInvalidTxExecutor.cs b/src/Nethermind/Nethermind.Taiko/BlockInvalidTxExecutor.cs index 3577d9a4479..2a49f1bc937 100644 --- a/src/Nethermind/Nethermind.Taiko/BlockInvalidTxExecutor.cs +++ b/src/Nethermind/Nethermind.Taiko/BlockInvalidTxExecutor.cs @@ -32,7 +32,7 @@ public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processing block.Transactions[0].IsAnchorTx = true; - BlockExecutionContext blkCtx = new(block.Header); + BlockExecutionContext blkCtx = new(block.Header, spec); using ArrayPoolList correctTransactions = new(block.Transactions.Length); for (int i = 0; i < block.Transactions.Length; i++) diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs index 32a3e1e8d46..0c784d67b51 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs @@ -162,7 +162,7 @@ void CommitAndDisposeBatch(Batch batch) batch.Dispose(); } - BlockExecutionContext blkCtx = new(blockHeader); + BlockExecutionContext blkCtx = new(blockHeader, _specProvider.GetSpec(blockHeader)); worldState.StateRoot = blockHeader.StateRoot; Batch batch = new(maxBytesPerTxList, txSource.Length, txDecoder); diff --git a/src/Nethermind/Nethermind.TxPool/TxPool.cs b/src/Nethermind/Nethermind.TxPool/TxPool.cs index aea6460a8ff..29ea5e63d80 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPool.cs @@ -302,7 +302,7 @@ private void ReAddReorganisedTransactions(Block? previousBlock) private void RemoveProcessedTransactions(Block block) { Transaction[] blockTransactions = block.Transactions; - using ArrayPoolList blobTxsToSave = new(Eip4844Constants.GetMaxBlobsPerBlock()); + using ArrayPoolList blobTxsToSave = new(blockTransactions.Length); long discoveredForPendingTxs = 0; long discoveredForHashCache = 0; long eip1559Txs = 0; diff --git a/tools/Evm/T8n/T8nExecutor.cs b/tools/Evm/T8n/T8nExecutor.cs index a1ed85939f9..520fad40ed4 100644 --- a/tools/Evm/T8n/T8nExecutor.cs +++ b/tools/Evm/T8n/T8nExecutor.cs @@ -102,7 +102,7 @@ public static T8nResult Execute(T8nCommandArguments arguments) blockReceiptsTracer.StartNewTxTrace(transaction); TransactionResult transactionResult = transactionProcessor - .Execute(transaction, new BlockExecutionContext(block.Header), blockReceiptsTracer); + .Execute(transaction, new BlockExecutionContext(block.Header, test.Spec), blockReceiptsTracer); blockReceiptsTracer.EndTxTrace(); transactionExecutionReport.ValidTransactions.Add(transaction); diff --git a/tools/Evm/T8n/T8nTest.cs b/tools/Evm/T8n/T8nTest.cs index 6d88aae73b4..90d6e287da0 100644 --- a/tools/Evm/T8n/T8nTest.cs +++ b/tools/Evm/T8n/T8nTest.cs @@ -65,7 +65,7 @@ private BlockHeader ConstructBlockHeader() .WithExcessBlobGas((ulong)ParentExcessBlobGas) .WithBlobGasUsed((ulong)ParentBlobGasUsed) .TestObject; - header.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parentHeader, Spec); + header.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parentHeader, Spec, header); } header.BlobGasUsed = BlobGasCalculator.CalculateBlobGas(Transactions); header.IsPostMerge = Spec is Paris;