From fcfae5de2ad2517ce2f626dd02242ea38ed2d876 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Mon, 8 Jun 2026 22:53:10 +0530 Subject: [PATCH 01/60] unify types with Geth --- .../Ethereum.Basic.Test/TransactionTests.cs | 10 +- .../DifficultyTestJson.cs | 10 +- .../DifficultyTests.cs | 4 +- .../Ethereum.Difficulty.Test/TestsBase.cs | 10 +- .../GeneralStateTestBase.cs | 8 +- .../Ethereum.Test.Base/JsonToEthereumTest.cs | 20 +- .../TestBlockhashProvider.cs | 2 +- .../TransactionJsonTest.cs | 2 +- .../TransactionTests.cs | 4 +- src/Nethermind/Nethermind.Api/IInitConfig.cs | 2 +- src/Nethermind/Nethermind.Api/InitConfig.cs | 2 +- ...uRaAdditionalBlockProcessorFactoryTests.cs | 2 +- .../AuRaBlockFinalizationManagerTests.cs | 90 ++--- .../AuRaBlockProducerTests.cs | 10 +- .../AuRaContractGasLimitOverrideTests.cs | 30 +- .../AuRaHealthHintServiceTests.cs | 2 +- .../AuRaSealValidatorTests.cs | 8 +- .../AuRaStepCalculatorTests.cs | 9 +- .../AuraBlockProcessorTests.cs | 4 +- .../AuRaContractGasLimitOverrideTests.cs | 12 +- .../Contract/TxPriorityContractTests.cs | 6 +- .../Reward/AuRaRewardCalculatorTests.cs | 28 +- .../Reward/StaticRewardCalculatorTests.cs | 42 +-- .../GeneratedTxSourceSealerTests.cs | 6 +- .../Transactions/GeneratedTxSourceTests.cs | 2 +- .../Transactions/TxPermissionFilterTest.cs | 6 +- .../Validators/ContractBasedValidatorTests.cs | 63 ++-- .../Validators/MultiValidatorTests.cs | 76 ++-- .../ReportingContractBasedValidatorTests.cs | 29 +- .../Validators/ValidatorStoreTests.cs | 16 +- .../BalRecorderE2ETests.cs | 22 +- .../EraFlatStoreTests.cs | 6 +- .../FakeRecordedBalStore.cs | 8 +- .../RecordedBalStoreTests.cs | 4 +- .../BalRecorderSpecProvider.cs | 4 +- .../IRecordedBalStore.cs | 2 +- .../RecordedBalStore.cs | 4 +- .../Nethermind.BalRecorder/SlotStore.cs | 14 +- .../Evm/MemoryCostBenchmark.cs | 2 +- .../Rlp/RlpDecodeBlockBenchmark.cs | 2 +- .../Rlp/RlpEncodeBlockBenchmark.cs | 2 +- .../Rlp/RlpEncodeHeaderBenchmark.cs | 2 +- .../BackgroundTaskSchedulerBenchmarks.cs | 4 +- .../State/ReadOnlySnapshotBundleBenchmark.cs | 4 +- .../State/WriteBatchBenchmark.cs | 4 +- .../Store/BloomStorageBenchmark.cs | 6 +- .../Store/PatriciaTreeBenchmarks.cs | 2 +- .../BeaconBlockRootHandlerTests.cs | 4 +- .../BlockAccessListStoreTests.cs | 8 +- .../BlockFinderExtensionsTests.cs | 8 +- .../BlockProcessorTests.cs | 34 +- .../BlockTreeTests.cs | 179 +++++----- .../BlockhashCacheTests.cs | 38 +- .../BlockhashProviderTests.cs | 50 +-- .../Bloom/BloomStorageTests.cs | 102 +++--- .../Builders/FilterBuilder.cs | 6 +- .../Consensus/CompositeTxSourceTests.cs | 6 +- .../Consensus/SinglePendingTxSelectorTests.cs | 2 +- .../Eip8037BlockGasIntegrationTests.cs | 60 ++-- .../ExitOnBlocknumberHandlerTests.cs | 10 +- .../Filters/LogIndexFilterVisitorTests.cs | 4 +- .../Find/LogFinderTests.cs | 38 +- .../FullPruning/FullPrunerTests.cs | 4 +- .../FullPruning/FullPruningDiskTest.cs | 2 +- .../BlockProducerBaseTests.BaseFee.cs | 45 +-- .../BlockProducerBaseTests.FeeCollector.cs | 6 +- ...lockProducerBaseTests.IsProducingBlocks.cs | 4 +- .../Proofs/ReceiptTrieTests.cs | 2 +- .../Proofs/TxTrieTests.cs | 2 +- .../ReadOnlyBlockTreeTests.cs | 30 +- .../Receipts/PersistentReceiptStorageTests.cs | 16 +- .../ReorgDepthFinalizedStateProviderTests.cs | 18 +- .../Rewards/RewardCalculatorTests.cs | 10 +- .../SlowHeaderStore.cs | 12 +- .../TransactionComparisonTests.cs | 74 ++-- .../TransactionProcessorEip7702Tests.cs | 53 ++- .../TransactionProcessorTests.cs | 144 ++++---- .../TransactionSelectorTests.cs | 60 ++-- .../TransactionsExecutorTests.cs | 8 +- .../Validators/BlockValidatorTests.cs | 18 +- .../Validators/HeaderValidatorTests.cs | 44 +-- .../Visitors/DbBlocksLoaderTests.cs | 8 +- .../Visitors/StartupTreeFixerTests.cs | 8 +- .../BeaconBlockRoot/BeaconBlockRootHandler.cs | 6 +- .../BlockAccessLists/BlockAccessListStore.cs | 14 +- .../BlockAccessLists/IBlockAccessListStore.cs | 14 +- .../BlockTree.AcceptVisitor.cs | 6 +- .../BlockTree.Healing.cs | 6 +- .../BlockTree.Initializer.cs | 112 +++--- .../Nethermind.Blockchain/BlockTree.cs | 121 +++---- .../BlockTreeExtensions.cs | 8 +- .../Nethermind.Blockchain/BlockTreeOverlay.cs | 44 +-- .../BlockTreeSuggestPacer.cs | 12 +- .../Nethermind.Blockchain/BlockhashCache.cs | 10 +- .../BlockhashProvider.cs | 6 +- .../Blocks/BadBlockStore.cs | 2 +- .../Blocks/BlockStore.cs | 10 +- .../Blocks/BlockhashStore.cs | 7 +- .../Blocks/IBlockStore.cs | 10 +- .../Blocks/IBlockhashStore.cs | 2 +- .../ChainHeadInfoProvider.cs | 4 +- .../Contracts/CallableContract.cs | 8 +- .../Contracts/Contract.ConstantContract.cs | 2 +- .../Contracts/Contract.cs | 18 +- .../ExitOnBlockNumberHandler.cs | 2 +- .../Find/BlockParameter.cs | 18 +- .../Find/IBlockFinder.cs | 24 +- .../FullPruning/FullPruner.cs | 6 +- .../Headers/HeaderStore.cs | 23 +- .../Headers/IHeaderFinder.cs | 2 +- .../Headers/IHeaderStore.cs | 8 +- .../IBlockFinalizationManager.cs | 4 +- .../Nethermind.Blockchain/IBlockTree.cs | 34 +- .../ManualFinalizationManager.cs | 2 +- .../Nethermind.Blockchain/Metrics.cs | 6 +- .../ReadOnlyBlockTree.cs | 54 +-- .../Receipts/FullInfoReceiptFinder.cs | 4 +- .../Receipts/IReceiptFinder.cs | 4 +- .../Receipts/IReceiptStorage.cs | 8 +- .../Receipts/IReceiptsMigration.cs | 2 +- .../Receipts/InMemoryReceiptStorage.cs | 12 +- .../Receipts/NullReceiptStorage.cs | 12 +- .../Receipts/PersistentReceiptStorage.cs | 36 +- .../Receipts/ReceiptsRecovery.cs | 4 +- .../ReorgDepthFinalizedStateProvider.cs | 4 +- .../Spec/ChainHeadSpecProvider.cs | 8 +- .../Synchronization/ISyncConfig.cs | 18 +- .../Synchronization/ISyncPeer.cs | 2 +- .../Synchronization/SyncConfig.cs | 14 +- .../Tracing/AccessTxTracer.cs | 2 +- .../Tracing/AlwaysCancelTxTracer.cs | 16 +- .../Tracing/BlockReceiptsTracer.cs | 36 +- .../Tracing/CallOutputTracer.cs | 4 +- .../Tracing/EstimateGasTracer.cs | 44 +-- .../Tracing/GasEstimator.cs | 54 +-- .../GethStyle/Custom/JavaScript/CallFrame.cs | 4 +- .../GethStyle/Custom/JavaScript/Context.cs | 6 +- .../Custom/JavaScript/FrameResult.cs | 4 +- .../JavaScript/GethLikeJavaScriptTxTracer.cs | 18 +- .../GethStyle/Custom/JavaScript/Log.cs | 8 +- .../Custom/Native/Call/NativeCallTracer.cs | 16 +- .../Native/Call/NativeCallTracerCallFrame.cs | 4 +- .../Native/FourByte/Native4ByteTracer.cs | 4 +- .../Custom/Native/GethLikeNativeTxTracer.cs | 6 +- .../Native/Prestate/NativePrestateTracer.cs | 4 +- .../GethLikeTxDirectStreamingTracer.cs | 8 +- .../Tracing/GethStyle/GethLikeTxFileTracer.cs | 2 +- .../GethStyle/GethLikeTxMemoryTracer.cs | 2 +- .../Tracing/GethStyle/GethLikeTxTrace.cs | 2 +- .../GethStyle/GethLikeTxTraceConverter.cs | 2 +- .../Tracing/GethStyle/GethLikeTxTracer.cs | 4 +- .../Tracing/GethStyle/GethTxTraceEntry.cs | 8 +- .../Tracing/ParityStyle/ParityLikeTxTrace.cs | 4 +- .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 18 +- .../Tracing/ParityStyle/ParityTraceAction.cs | 2 +- .../ParityStyle/ParityTraceActionConverter.cs | 2 +- .../Tracing/ParityStyle/ParityTraceResult.cs | 2 +- .../ParityStyle/ParityTraceResultConverter.cs | 2 +- .../ParityStyle/ParityVmOperationTrace.cs | 4 +- .../StreamingParityLikeTxTracer.cs | 20 +- .../Visitors/DbBlocksLoader.cs | 29 +- .../Visitors/IBlockTreeVisitor.cs | 8 +- .../Visitors/ReceiptsVerificationVisitor.cs | 14 +- .../Visitors/StartupBlockTreeFixer.cs | 34 +- .../CliqueBlockProducerTests.cs | 30 +- .../CliqueSealEngineTests.cs | 10 +- .../Nethermind.Clique.Test/CliqueTests.cs | 4 +- .../SnapshotDecoderTests.cs | 18 +- .../WiggleRandomizerTests.cs | 42 +-- .../AuRaBetterPeerStrategy.cs | 6 +- .../AuRaBlockFinalizationManager.cs | 28 +- .../AuRaBlockProcessor.cs | 2 +- .../AuRaContractGasLimitOverride.cs | 12 +- .../AuRaHeaderValidator.cs | 4 +- .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 2 +- .../Nethermind.Consensus.AuRa/AuRaSealer.cs | 2 +- .../AuRaStepCalculator.cs | 60 ++-- .../AuRaValidatorFactory.cs | 8 +- .../Config/AuRaChainSpecEngineParameters.cs | 46 +-- .../ContractRewriter.cs | 6 +- .../Contracts/BlockGasLimitContract.cs | 4 +- .../Contracts/RandomContract.cs | 4 +- .../Contracts/RegisterBasedContract.cs | 2 +- .../Contracts/RewardContract.cs | 4 +- .../TransactionPermissionContractV3.cs | 2 +- .../TxPriorityContract.Destination.cs | 6 +- .../Contracts/VersionedContract.cs | 4 +- .../VersionedTransactionPermissionContract.cs | 2 +- .../Nethermind.Consensus.AuRa/IActivatedAt.cs | 4 +- .../IAuRaBlockFinalizationManager.cs | 4 +- .../IAuRaValidatorFactory.cs | 2 +- .../AuRaGasLimitOverrideFactory.cs | 2 +- .../StartBlockProducerAuRa.cs | 8 +- .../ListExtensions.cs | 2 +- .../Rewards/AuRaRewardCalculator.cs | 13 +- .../Rewards/StaticRewardCalculator.cs | 12 +- .../Transactions/GeneratedTxSource.cs | 10 +- .../Transactions/RandomContractTxSource.cs | 2 +- .../Transactions/TransactionExtensions.cs | 4 +- .../Transactions/TxGasPriceSender.cs | 4 +- .../Transactions/TxPriorityTxSource.cs | 2 +- .../Validators/AuRaParameters.cs | 2 +- .../Validators/AuRaValidatorBase.cs | 6 +- .../ContractBasedValidator.Posdao.cs | 6 +- .../Validators/ContractBasedValidator.cs | 10 +- .../Validators/IReportingValidator.cs | 4 +- .../Validators/IValidatorStore.cs | 6 +- .../Validators/ListBasedValidator.cs | 2 +- .../Validators/MultiValidator.cs | 38 +- .../Validators/NullReportingValidator.cs | 4 +- .../Validators/PendingValidators.cs | 4 +- .../Validators/PendingValidatorsDecoder.cs | 2 +- .../ReportingContractBasedValidator.Cache.cs | 6 +- ...ontractBasedValidator.PersistentReports.cs | 10 +- .../ReportingContractBasedValidator.cs | 20 +- .../Validators/ValidatorInfo.cs | 6 +- .../Validators/ValidatorInfoDecoder.cs | 4 +- .../Validators/ValidatorStore.cs | 28 +- .../CliqueBlockProducer.cs | 4 +- .../CliqueRpcModule.cs | 10 +- .../CliqueSealValidator.cs | 8 +- .../CliqueSealer.cs | 4 +- .../ICliqueRpcModule.cs | 4 +- .../ISnapshotManager.cs | 6 +- .../Nethermind.Consensus.Clique/Snapshot.cs | 12 +- .../SnapshotDecoder.cs | 20 +- .../SnapshotManager.cs | 36 +- .../Nethermind.Consensus.Clique/Vote.cs | 4 +- .../WiggleRandomizer.cs | 2 +- .../Nethermind.Consensus.Ethash/Ethash.cs | 6 +- .../EthashChainSpecEngineParameters.cs | 33 +- .../EthashDifficultyCalculator.cs | 25 +- .../EthashSealValidator.cs | 4 +- .../EthashSealer.cs | 2 +- .../HintBasedCache.cs | 4 +- .../BlockCachePreWarmerTests.cs | 2 +- .../ExecutionProcessorTests.cs | 2 +- .../ManualGasLimitCalculator.cs | 4 +- .../ProcessingStatsTests.cs | 6 +- .../TargetAdjustedGasLimitCalculatorTests.cs | 28 +- .../Nethermind.Consensus/AlwaysPoS.cs | 2 +- .../BlockPreparationContext.cs | 4 +- .../Comparers/GasPriceTxComparer.cs | 2 +- .../Eip1559GasLimitAdjuster.cs | 7 +- .../ExecutionRequestsProcessor.cs | 10 +- .../Nethermind.Consensus/FollowOtherMiners.cs | 6 +- .../IGasLimitCalculator.cs | 2 +- .../Nethermind.Consensus/IPoSSwitcher.cs | 2 +- .../Nethermind.Consensus/ISealer.cs | 2 +- .../Nethermind.Consensus/NethDevSealEngine.cs | 2 +- src/Nethermind/Nethermind.Consensus/NoPoS.cs | 2 +- .../Nethermind.Consensus/NullSealEngine.cs | 2 +- .../BlockAccessListManager.SystemContracts.cs | 4 +- .../BlockAccessListManager.Validation.cs | 22 +- .../Processing/BlockAccessListManager.cs | 4 +- ...or.BlockAccessListSystemContractHandler.cs | 2 +- ...cessor.BlockProductionTransactionPicker.cs | 4 +- ...llelBlockValidationTransactionsExecutor.cs | 10 +- .../BlockProcessor.SystemContractHandler.cs | 2 +- .../Processing/BlockProcessor.cs | 2 +- .../Processing/BlockchainProcessor.cs | 1 + .../CensorshipDetector/CensorshipDetector.cs | 12 +- .../Processing/CensorshipDetector/Metrics.cs | 4 +- .../Processing/GasValidationResultSlot.cs | 4 +- .../Processing/IBlockAccessListManager.cs | 2 +- .../Processing/NullBlockAccessListManager.cs | 2 +- .../Processing/ProcessingStats.cs | 27 +- .../Producers/PayloadAttributes.cs | 2 +- .../Producers/TxPoolTxSource.cs | 50 +-- .../Nethermind.Consensus/SealEngine.cs | 2 +- .../Stateless/StatelessBlockTree.cs | 50 +-- .../Stateless/WitnessCapturingTrieStore.cs | 2 +- .../WitnessGeneratingHeaderFinder.cs | 8 +- .../Stateless/WitnessGeneratingWorldState.cs | 12 +- .../TargetAdjustedGasLimitCalculator.cs | 17 +- .../Tracing/GethStyleTracer.cs | 4 +- .../Tracing/IGethStyleTracer.cs | 4 +- .../Transactions/CompositeTxSource.cs | 2 +- .../Transactions/EmptyTxSource.cs | 2 +- .../Transactions/FilteredTxSource.cs | 2 +- .../Transactions/ITxSource.cs | 2 +- .../Transactions/OneByOneTxSource.cs | 2 +- .../Transactions/SinglePendingTxSelector.cs | 2 +- .../Validators/BlockValidator.cs | 4 +- .../Validators/HeaderValidator.cs | 55 +-- .../Validators/TxValidator.cs | 10 +- .../Validators/UnclesValidator.cs | 4 +- .../Nethermind.Core.Test/AddressTests.cs | 6 +- .../Nethermind.Core.Test/BlockHeaderTests.cs | 38 +- .../Blockchain/BasicTestBlockchain.cs | 2 +- .../Blockchain/TestBlockchain.cs | 4 +- .../Builders/AccountBuilder.cs | 4 +- .../Builders/BlockBuilder.cs | 6 +- .../Builders/BlockHeaderBuilder.cs | 6 +- .../Builders/BlockTreeBuilder.cs | 22 +- .../Builders/BlockTreeExtensions.cs | 12 +- .../Builders/ReceiptBuilder.cs | 6 +- .../Nethermind.Core.Test/Builders/TestItem.cs | 8 +- .../Builders/TransactionBuilder.cs | 8 +- .../Builders/TrieBuilder.cs | 4 +- .../Eip2935TestConstants.cs | 3 +- .../Eip4788TestConstants.cs | 3 +- .../Eip7002TestConstants.cs | 3 +- .../Eip7251TestConstants.cs | 3 +- .../Encoding/BlockDecoderTests.cs | 4 +- .../Encoding/HeaderDecoderTests.cs | 36 +- ...ixedForkActivationChainHeadSpecProvider.cs | 6 +- .../Nethermind.Core.Test/Int64Tests.cs | 4 +- .../Modules/FlatDbManagerTestCompat.cs | 2 +- .../Nethermind.Core.Test/SyncPeerMock.cs | 14 +- .../TestBlockhashProvider.cs | 4 +- .../TestFinalizedStateProvider.cs | 8 +- .../TestReadOnlyStateProvider.cs | 6 +- .../TestTrieStoreFactory.cs | 2 +- .../TestWorldStateFactory.cs | 6 +- .../TransactionExtensionsTests.cs | 4 +- src/Nethermind/Nethermind.Core/Account.cs | 24 +- .../Authentication/JwtAuthentication.cs | 6 +- .../Nethermind.Core/BaseFeeCalculator.cs | 6 +- src/Nethermind/Nethermind.Core/Block.cs | 6 +- src/Nethermind/Nethermind.Core/BlockHeader.cs | 12 +- src/Nethermind/Nethermind.Core/BlockInfo.cs | 2 +- .../Collections/ListExtensions.cs | 2 +- .../Nethermind.Core/Eip2935Constants.cs | 2 +- .../Nethermind.Core/Eip7825Constants.cs | 6 +- .../Nethermind.Core/Eip8037Constants.cs | 8 +- .../Extensions/Int64Extensions.cs | 6 +- .../Extensions/SizeExtensions.cs | 10 + .../Extensions/SpecProviderExtensions.cs | 4 +- .../Extensions/UInt64Extensions.cs | 17 + src/Nethermind/Nethermind.Core/GasCostOf.cs | 160 ++++----- .../Nethermind.Core/IAccountStateProvider.cs | 2 +- .../KeyValueStoreExtensions.cs | 14 +- .../Messages/BlockErrorMessages.cs | 4 +- .../Messages/TxErrorMessages.cs | 4 +- .../Nethermind.Core/ProgressLogger.cs | 44 ++- src/Nethermind/Nethermind.Core/RefundOf.cs | 22 +- .../Nethermind.Core/Reorganization.cs | 2 +- .../Nethermind.Core/Specs/ForkActivation.cs | 16 +- .../Nethermind.Core/Specs/IEip1559Spec.cs | 4 +- .../Nethermind.Core/Specs/IReleaseSpec.cs | 12 +- .../Nethermind.Core/Specs/ISpecProvider.cs | 6 +- .../Specs/ReleaseSpecDecorator.cs | 14 +- .../Nethermind.Core/Specs/SpecGasCosts.cs | 40 +-- .../Threading/InterlockedEx.cs | 45 +++ src/Nethermind/Nethermind.Core/Transaction.cs | 16 +- .../Nethermind.Core/TransactionExtensions.cs | 8 +- .../Nethermind.Core/TransactionReceipt.cs | 18 +- .../Nethermind.Db.Rocks/Config/DbConfig.cs | 14 +- .../Config/RocksDbConfigFactory.cs | 4 +- .../Nethermind.Db.Rocks/DbOnTheRocks.cs | 12 +- .../Nethermind.Db/Blooms/BloomStorage.cs | 94 ++--- .../Nethermind.Db/Blooms/IBloomEnumeration.cs | 4 +- .../Nethermind.Db/Blooms/IBloomStorage.cs | 12 +- .../Nethermind.Db/Blooms/NullBloomStorage.cs | 18 +- .../Nethermind.Era1.Test/Era1ModuleTests.cs | 28 +- .../Nethermind.Era1.Test/EraExporterTests.cs | 6 +- .../Nethermind.Era1.Test/EraImporterTest.cs | 6 +- .../Nethermind.Era1.Test/EraReaderTests.cs | 8 +- .../Nethermind.Era1.Test/EraStoreTests.cs | 8 +- .../Nethermind.Era1.Test/EraTestModule.cs | 4 +- .../Nethermind.Era1.Test/EraWriterTests.cs | 2 +- .../Nethermind.Era1/AdminEraService.cs | 8 +- .../Nethermind.Era1/E2StoreReader.cs | 36 +- src/Nethermind/Nethermind.Era1/EraConfig.cs | 4 +- src/Nethermind/Nethermind.Era1/EraExporter.cs | 47 ++- src/Nethermind/Nethermind.Era1/EraImporter.cs | 54 +-- src/Nethermind/Nethermind.Era1/EraReader.cs | 24 +- src/Nethermind/Nethermind.Era1/EraStore.cs | 27 +- src/Nethermind/Nethermind.Era1/EraWriter.cs | 2 +- .../Nethermind.Era1/IAdminEraService.cs | 4 +- src/Nethermind/Nethermind.Era1/IEraConfig.cs | 4 +- .../Nethermind.Era1/IEraExporter.cs | 2 +- .../Nethermind.Era1/IEraImporter.cs | 2 +- src/Nethermind/Nethermind.Era1/IEraStore.cs | 8 +- .../JsonRpc/EraAdminRpcModule.cs | 4 +- .../Archive/AccumulatorCalculatorTests.cs | 14 +- .../Archive/EraReaderTests.cs | 20 +- .../Archive/EraWriterTests.cs | 2 +- .../Nethermind.EraE.Test/EraETestModule.cs | 6 +- .../Export/EraExporterTests.cs | 34 +- .../Import/EraImporterTests.cs | 32 +- .../Store/EraStoreTests.cs | 21 +- .../Store/RemoteEraStoreDecoratorTests.cs | 18 +- .../Nethermind.EraE.Test/TestEraFile.cs | 10 +- .../Nethermind.EraE/Admin/AdminEraService.cs | 4 +- .../Nethermind.EraE/Archive/EraReader.cs | 24 +- .../Archive/EraSlimReceiptDecoder.cs | 2 +- .../Nethermind.EraE/Archive/EraWriter.cs | 8 +- .../Nethermind.EraE/E2Store/E2StoreReader.cs | 24 +- .../Nethermind.EraE/EraCliRunner.cs | 4 +- .../Nethermind.EraE/Export/EraExporter.cs | 40 +-- .../Nethermind.EraE/Export/IEraExporter.cs | 2 +- .../Nethermind.EraE/Import/EraImporter.cs | 32 +- .../Nethermind.EraE/Import/IEraImporter.cs | 2 +- .../Proofs/BlocksRootContext.cs | 4 +- .../Nethermind.EraE/Proofs/Validator.cs | 4 +- .../Nethermind.EraE/Store/EraStore.cs | 20 +- .../Nethermind.EraE/Store/IEraStore.cs | 8 +- .../Store/RemoteEraStoreDecorator.cs | 20 +- .../EthStatsIntegrationTests.cs | 32 +- .../EthStatsMessageParserTests.cs | 8 +- .../EthStatsMessageParser.cs | 49 ++- .../Integrations/EthStatsIntegration.cs | 8 +- .../Messages/Models/Block.cs | 10 +- .../Nethermind.Ethash.Test/ChainSpecTest.cs | 24 +- .../DifficultyCalculatorTests.cs | 8 +- .../BlockProcessingBenchmark.cs | 12 +- .../Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 2 +- .../EvmOpcodesBenchmark.cs | 8 +- .../MultipleUnsignedOperations.cs | 2 +- .../StaticCallBenchmarks.cs | 2 +- .../TestBlockhashProvider.cs | 2 +- .../IdentityPrecompile.cs | 2 +- .../ModExpPrecompile.cs | 8 +- .../Ripemd160Precompile.cs | 2 +- .../Sha256Precompile.cs | 2 +- .../Nethermind.Evm.Test/CallDataLoadTests.cs | 2 +- .../Nethermind.Evm.Test/CallTests.cs | 2 +- .../Nethermind.Evm.Test/CmpTests.cs | 6 +- .../Nethermind.Evm.Test/CoinbaseTests.cs | 2 +- .../Nethermind.Evm.Test/DataCopyGasTests.cs | 10 +- .../Nethermind.Evm.Test/Eip1014Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip1052Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip1108Tests.cs | 8 +- .../Nethermind.Evm.Test/Eip1153Tests.cs | 8 +- .../Nethermind.Evm.Test/Eip1283Tests.cs | 38 +- .../Nethermind.Evm.Test/Eip1344Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip145Tests.cs | 6 +- .../Nethermind.Evm.Test/Eip152Tests.cs | 8 +- .../Nethermind.Evm.Test/Eip1884Tests.cs | 8 +- .../Nethermind.Evm.Test/Eip2028Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip2200Tests.cs | 86 ++--- .../Nethermind.Evm.Test/Eip2315Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip2537Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip2929Tests.cs | 12 +- .../Nethermind.Evm.Test/Eip2935Tests.cs | 6 +- .../Eip3198BaseFeeTests.cs | 6 +- .../Nethermind.Evm.Test/Eip3529Tests.cs | 91 +++-- .../Nethermind.Evm.Test/Eip3541Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip3651Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip3855Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip3860Tests.cs | 7 +- .../Nethermind.Evm.Test/Eip4844Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip6780Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip7623Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip7708Tests.cs | 10 +- .../Nethermind.Evm.Test/Eip7778Tests.cs | 36 +- .../Nethermind.Evm.Test/Eip7843Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip7928Tests.cs | 44 +-- .../Nethermind.Evm.Test/Eip7939Tests.cs | 4 +- .../Nethermind.Evm.Test/Eip7954Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip7976Tests.cs | 14 +- .../Nethermind.Evm.Test/Eip7981Tests.cs | 37 +- .../Nethermind.Evm.Test/Eip8024Tests.cs | 8 +- .../Eip8037BlockGasInclusionCheckTests.cs | 108 +++--- .../Eip8037RegressionTests.cs | 46 +-- .../Nethermind.Evm.Test/Eip8037Tests.cs | 98 +++--- .../Nethermind.Evm.Test/EvmMemoryTestsBase.cs | 8 +- .../EvmPooledMemoryTests.cs | 64 ++-- .../Nethermind.Evm.Test/EvmStackTests.cs | 2 +- .../GasPriceExtractorTests.cs | 2 +- .../IntrinsicGasCalculatorTests.cs | 44 +-- .../Nethermind.Evm.Test/InvalidOpcodeTests.cs | 4 +- .../Nethermind.Evm.Test/Keccak256Tests.cs | 2 +- .../Push2JumpFusionTests.cs | 2 +- .../Nethermind.Evm.Test/SimdTests.cs | 6 +- .../StateOverridesTests.cs | 23 +- .../StorageAndSelfDestructTests.cs | 10 +- .../TestAllTracerWithOutput.cs | 4 +- .../Tracing/DebugTracerTests.cs | 4 +- .../Tracing/GasEstimationTests.cs | 258 +++++++------- .../Tracing/ParityLikeTxTracerTests.cs | 2 +- .../TransactionProcessorEip4844Tests.cs | 6 +- .../TransactionProcessorEip7623Tests.cs | 6 +- .../TransactionProcessorTraceTest.cs | 10 +- .../VirtualMachineTests.cs | 10 +- .../VirtualMachineTestsBase.cs | 59 ++-- .../Nethermind.Evm.Test/VmCodeDepositTests.cs | 4 +- .../Nethermind.Evm.Test/VmStateTests.cs | 4 +- .../Nethermind.Evm/AccountOverride.cs | 2 +- .../Nethermind.Evm/BlockExecutionContext.cs | 4 +- .../Nethermind.Evm/BlockOverride.cs | 11 +- .../Nethermind.Evm/BlockOverrideExtensions.cs | 4 +- .../Nethermind.Evm/CodeDepositHandler.cs | 38 +- .../Nethermind.Evm/EvmPooledMemory.cs | 20 +- .../Eip8037BlockGasInclusionCheck.cs | 38 +- .../GasPolicy/EthereumGasPolicy.cs | 156 ++++---- .../Nethermind.Evm/GasPolicy/IGasPolicy.cs | 100 +++--- .../Nethermind.Evm/IBlockhashProvider.cs | 2 +- .../Instructions/EvmCalculations.cs | 39 +- .../Instructions/EvmInstructions.Bitwise.cs | 4 +- .../Instructions/EvmInstructions.Call.cs | 27 +- .../Instructions/EvmInstructions.CodeCopy.cs | 6 +- .../Instructions/EvmInstructions.Create.cs | 19 +- .../Instructions/EvmInstructions.Crypto.cs | 2 +- .../EvmInstructions.Environment.cs | 29 +- .../EvmInstructions.Math1Param.cs | 4 +- .../EvmInstructions.Math2Param.cs | 14 +- .../EvmInstructions.Math3Param.cs | 2 +- .../Instructions/EvmInstructions.Shifts.cs | 2 +- .../Instructions/EvmInstructions.Storage.cs | 24 +- .../Nethermind.Evm/IntrinsicGasCalculator.cs | 12 +- src/Nethermind/Nethermind.Evm/RefundHelper.cs | 8 +- .../Nethermind.Evm/ReleaseSpecExtensions.cs | 4 +- .../Nethermind.Evm/State/IWorldState.cs | 16 +- .../State/IWorldStateScopeProvider.cs | 2 +- .../State/WorldStateExtensions.cs | 4 +- .../StateOverridesExtensions.cs | 8 +- .../Tracing/CancellationTxTracer.cs | 16 +- .../Tracing/CompositeTxTracer.cs | 16 +- .../Tracing/Debugger/DebugTracer.cs | 16 +- .../Nethermind.Evm/Tracing/ITxTracer.cs | 16 +- .../Nethermind.Evm/Tracing/NullTxTracer.cs | 14 +- .../Nethermind.Evm/Tracing/TxTracer.cs | 16 +- .../TransactionProcessing/GasConsumed.cs | 10 +- .../SystemTransactionProcessor.cs | 8 +- .../TransactionProcessor.cs | 243 ++++++------- .../Nethermind.Evm/TransactionSubstate.cs | 4 +- .../Nethermind.Evm/VirtualMachine.cs | 64 ++-- .../Nethermind.Evm/VirtualMachine.warmup.cs | 10 +- src/Nethermind/Nethermind.Evm/VmState.cs | 8 +- .../BlockchainBridgeTests.cs | 10 +- .../Eth/EthSyncingInfoTests.cs | 12 +- .../LogIndexBuilderTests.cs | 8 +- .../Nethermind.Facade/BlockchainBridge.cs | 16 +- .../Nethermind.Facade/CallOutput.cs | 4 +- .../Nethermind.Facade/Eth/BlockForRpc.cs | 6 +- .../Eth/BlockHeaderForRpc.cs | 6 +- .../Nethermind.Facade/Eth/EthSyncingInfo.cs | 4 +- .../Nethermind.Facade/Eth/IFromTransaction.cs | 4 +- .../AccessListTransactionForRpc.cs | 2 +- .../RpcTransaction/BlobTransactionForRpc.cs | 2 +- .../EIP1559TransactionForRpc.cs | 2 +- .../RpcTransaction/LegacyTransactionForRpc.cs | 11 +- .../SetCodeTransactionForRpc.cs | 2 +- .../Eth/RpcTransaction/TransactionForRpc.cs | 6 +- .../Nethermind.Facade/Eth/SyncingResult.cs | 6 +- .../Eth/SyncingResultJsonConverter.cs | 6 +- .../Nethermind.Facade/Filters/FilterLog.cs | 4 +- .../Find/ILogIndexBuilder.cs | 4 +- .../Find/IndexedLogFinder.cs | 12 +- .../Nethermind.Facade/Find/LogFinder.cs | 25 +- .../Nethermind.Facade/Find/LogIndexBuilder.cs | 124 +++++-- .../Nethermind.Facade/Find/LogScanner.cs | 15 +- .../Nethermind.Facade/IBlockchainBridge.cs | 8 +- .../Proxy/Models/BlockModel.cs | 16 +- .../Proxy/Models/TransactionModel.cs | 10 +- .../Simulate/SimulateBlockTracer.cs | 2 +- ...lateBlockValidationTransactionsExecutor.cs | 4 +- .../Simulate/SimulateBlockhashProvider.cs | 6 +- .../Simulate/SimulateBridgeHelper.cs | 15 +- .../Simulate/SimulateDictionaryBlockStore.cs | 12 +- .../Simulate/SimulateDictionaryHeaderStore.cs | 18 +- .../Simulate/SimulateRequestState.cs | 4 +- .../SimulateTransactionProcessorAdapter.cs | 5 +- .../Simulate/SimulateTxTracer.cs | 10 +- .../Nethermind.Flashbots/Data/BidTrace.cs | 8 +- .../Data/BuilderBlockValidationRequest.cs | 4 +- .../Data/RExecutionPayloadV3.cs | 12 +- .../Handlers/ValidateSubmissionHandler.cs | 35 +- .../Modules/Rbuilder/IRbuilderRpcModule.cs | 2 +- .../NodeHealthServiceTests.cs | 4 +- .../HistoryPrunerTests.cs | 28 +- .../Nethermind.History/HistoryPruner.cs | 113 +++--- .../Nethermind.History/IHistoryPruner.cs | 8 +- src/Nethermind/Nethermind.History/Metrics.cs | 8 +- .../Modules/FlatRocksDbConfigAdjuster.cs | 4 +- .../PruningTrieStateFactory.cs | 14 +- .../Steps/Migrations/BloomMigration.cs | 20 +- .../Steps/Migrations/ReceiptFixMigration.cs | 6 +- .../Steps/Migrations/ReceiptMigration.cs | 34 +- .../Migrations/TotalDifficultyFixMigration.cs | 6 +- .../DebugTraceStreamingAllocsBenchmarks.cs | 4 +- .../DebugTraceStreamingBenchmarks.cs | 6 +- .../TraceStreamingAllocsBenchmarks.cs | 4 +- .../TraceStreamingBenchmarks.cs | 6 +- .../ConsensusHelperTests.cs | 2 +- .../Data/BlockParameterConverterTests.cs | 28 +- .../JsonRpcServiceTests.cs | 4 +- .../Modules/DebugModuleTests.cs | 6 +- .../DebugRpcModuleTests.ExecutionWitness.cs | 20 +- .../Modules/DebugRpcModuleTests.TraceBlock.cs | 69 ++-- .../DebugRpcModuleTests.TraceCallMany.cs | 20 +- .../DebugRpcModuleTests.TraceTransaction.cs | 16 +- .../Modules/DebugRpcModuleTests.cs | 10 +- ...DebugSimulateTestsBlocksAndTransactions.cs | 2 +- .../Eth/EthRpcModuleTests.EstimateGas.cs | 62 ++-- .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 12 +- .../Eth/EthRpcModuleTests.FeeHistory.cs | 8 +- .../Modules/Eth/EthRpcModuleTests.GasPrice.cs | 10 +- .../Eth/EthRpcModuleTests.SignTransaction.cs | 10 +- .../Modules/Eth/EthRpcModuleTests.cs | 86 ++--- .../Modules/Eth/EthRpcSimulateTestsBase.cs | 4 +- .../EthSimulateTestsBlocksAndTransactions.cs | 28 +- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 2 +- .../Modules/FeeHistoryOracleTests.cs | 91 ++--- .../Modules/GasPriceOracleTests.cs | 40 +-- .../Modules/ParityRpcModuleTests.cs | 12 +- .../AccessListTransactionForRpcTests.cs | 6 +- .../BlobTransactionForRpcTests.cs | 6 +- .../EIP1559TransactionForRpcTests.cs | 6 +- .../LegacyTransactionForRpcTests.cs | 6 +- .../SetCodeTransactionForRpcTests.cs | 6 +- .../Simulate/TracedSimulateTestsBase.cs | 4 +- .../TransactionReceiptsSubscriptionTests.cs | 22 +- .../Modules/SubscribeModuleTests.cs | 20 +- .../Modules/TestRpcBlockchain.cs | 3 +- .../ParityTxTraceFromReplayConverterTest.cs | 4 +- ...TraceSimulateTestsBlocksAndTransactions.cs | 2 +- .../Modules/TraceRpcModuleTests.cs | 84 ++--- .../DbPersistingBlockTracer.cs | 4 +- .../ITraceStoreConfig.cs | 2 +- .../TraceStoreConfig.cs | 2 +- .../TraceStorePruner.cs | 6 +- .../Nethermind.JsonRpc/Data/LogEntryForRpc.cs | 2 +- .../Nethermind.JsonRpc/Data/ReceiptForRpc.cs | 6 +- .../Nethermind.JsonRpc/IJsonRpcConfig.cs | 2 +- .../Nethermind.JsonRpc/JsonRpcConfig.cs | 2 +- .../Modules/BlockFinderExtensions.cs | 8 +- .../Modules/DebugModule/DebugBridge.cs | 18 +- .../Modules/DebugModule/DebugRpcModule.cs | 22 +- .../GethLikeTxTraceStreamingBundleResult.cs | 6 +- .../Modules/DebugModule/IDebugBridge.cs | 10 +- .../Modules/DebugModule/IDebugRpcModule.cs | 2 +- .../DebugModule/StructLogEnvelopeWriter.cs | 8 +- .../Modules/Eth/ErrorWrapper.cs | 4 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 4 +- .../Modules/Eth/EthRpcModule.cs | 18 +- .../Eth/FeeHistory/FeeHistoryOracle.cs | 40 +-- .../Eth/FeeHistory/IFeeHistoryOracle.cs | 2 +- .../Modules/Eth/FeeHistoryResults.cs | 4 +- .../Modules/Eth/GasPrice/GasPriceOracle.cs | 12 +- .../Modules/Eth/IEthRpcModule.cs | 6 +- .../Modules/Eth/SimulateTxExecutor.cs | 12 +- .../Modules/LogIndex/LogIndexRpcModule.cs | 6 +- .../Modules/LogIndex/LogIndexStatus.cs | 2 +- .../Modules/Parity/ParityTransaction.cs | 2 +- .../Modules/Subscribe/SyncingSubscription.cs | 6 +- .../Modules/Trace/ParityTxTraceFromStore.cs | 4 +- .../AuRaMergeFinalizationManagerTests.cs | 2 +- .../AuRaMergeFinalizationManager.cs | 6 +- .../Contracts/WithdrawalContract.cs | 2 +- .../GetPayloadV3SerializationBenchmarks.cs | 2 +- .../BlockTreeTests.cs | 38 +- ...ChainSpecBasedSpecProviderTestsTheMerge.cs | 4 +- .../EngineModuleTests.PayloadProduction.cs | 2 +- .../EngineModuleTests.RelayBuilder.cs | 6 +- .../EngineModuleTests.Synchronization.cs | 2 +- .../EngineModuleTests.V1.cs | 2 +- .../EngineModuleTests.V2.cs | 6 +- .../EngineModuleTests.V3.cs | 2 +- .../EngineModuleTests.V5.cs | 2 +- .../EngineModuleTests.V6.cs | 4 +- .../ExternalRpcIntegrationTests.cs | 8 +- .../GetPayloadDirectResponseTests.cs | 5 +- .../MergeBetterPeerStrategyTests.cs | 84 ++--- .../MergeFinalizationManagerTests.cs | 2 +- .../MergeFinalizedStateProviderTests.cs | 42 +-- .../MergeRewardCalculatorTests.cs | 4 +- .../PoSSwitcherTests.cs | 5 +- .../ProcessedTransactionsDbCleanerTests.cs | 4 +- .../SszRest/SszCodecTests.cs | 14 +- .../SszRest/SszMiddlewareTests.cs | 23 +- .../SszRest/SszMultiSegmentDecodeTests.cs | 2 +- .../Synchronization/BeaconHeadersSyncTests.cs | 48 ++- .../Synchronization/BeaconPivotTests.cs | 2 +- .../StartingSyncPivotUpdaterTests.cs | 10 +- .../TestingRpcModuleTests.cs | 10 +- .../Boost/BoostPayloadAttributes.cs | 4 +- .../PayloadPreparationService.cs | 4 +- .../Data/ExecutionPayload.cs | 6 +- .../Data/ForkchoiceStateV1.cs | 2 +- .../Data/GetPayloadDirectResponseWriter.cs | 4 +- .../Data/TransitionConfigurationV1.cs | 2 +- .../EngineRpcModule.Amsterdam.cs | 2 +- .../EngineRpcModule.Shanghai.cs | 2 +- ...xchangeTransitionConfigurationV1Handler.cs | 2 +- .../Handlers/ForkchoiceUpdatedHandler.cs | 4 +- .../GetPayloadBodiesByRangeV1Handler.cs | 10 +- .../GetPayloadBodiesByRangeV2Handler.cs | 10 +- .../IGetPayloadBodiesByRangeV1Handler.cs | 2 +- .../IGetPayloadBodiesByRangeV2Handler.cs | 2 +- .../Handlers/MergeSealer.cs | 2 +- .../Handlers/NewPayloadHandler.cs | 8 +- .../IEngineRpcModule.Amsterdam.cs | 2 +- .../IEngineRpcModule.Shanghai.cs | 2 +- .../Nethermind.Merge.Plugin/IMergeConfig.cs | 2 +- .../MergeBetterPeerStrategy.cs | 6 +- .../Nethermind.Merge.Plugin/MergeConfig.cs | 2 +- .../MergeFinalizationManager.cs | 4 +- .../MergeFinalizedStateProvider.cs | 4 +- .../Nethermind.Merge.Plugin/PoSSwitcher.cs | 10 +- .../ProcessedTransactionsDbCleaner.cs | 6 +- .../GetPayloadBodiesByRangeSszHandler.cs | 2 +- .../SszRest/Handlers/SszVersionDescriptors.cs | 6 +- .../SszRest/SszCodec.cs | 17 +- .../SszRest/SszExecutionPayload.cs | 6 +- .../SszRest/SszNumericChecks.cs | 4 +- .../Synchronization/BeaconHeadersSyncFeed.cs | 10 +- .../Synchronization/BeaconPivot.cs | 10 +- .../Synchronization/BeaconSync.cs | 2 +- .../Synchronization/ChainLevelHelper.cs | 14 +- ...stMergeBlocksSyncPeerAllocationStrategy.cs | 4 +- .../StartingSyncPivotUpdater.cs | 24 +- .../UnsafeStartingSyncPivotUpdater.cs | 12 +- .../FollowOtherMinersTests.cs | 24 +- .../GasLimitCalculatorTests.cs | 12 +- .../HintBasedCacheTests.cs | 4 +- .../Nethermind.Network.Test/ForkInfoTests.cs | 332 +++++++++--------- .../Eth/V62/Eth62ProtocolHandlerTests.cs | 4 +- .../NewBlockHashesMessageSerializerTests.cs | 2 +- .../Eth/V65/Eth65ProtocolHandlerTests.cs | 4 +- .../Eth/V68/Eth68ProtocolHandlerTests.cs | 6 +- .../Eth/V69/Eth69ProtocolHandlerTests.cs | 10 +- .../Eth/V70/Eth70ProtocolHandlerTests.cs | 28 +- .../Eth/V71/Eth71ProtocolHandlerTests.cs | 2 +- src/Nethermind/Nethermind.Network/ForkInfo.cs | 7 +- .../Nethermind.Network/IForkInfo.cs | 2 +- .../SyncPeerProtocolHandlerBase.cs | 4 +- .../Eth/V62/Eth62ProtocolHandler.cs | 6 +- .../V62/Messages/GetBlockHeadersMessage.cs | 2 +- .../GetBlockHeadersMessageSerializer.cs | 2 +- .../Eth/V62/Messages/NewBlockHashesMessage.cs | 4 +- .../NewBlockHashesMessageSerializer.cs | 4 +- .../V63/Messages/ReceiptsMessageSerializer.cs | 4 +- .../V69/Messages/BlockRangeUpdateMessage.cs | 4 +- .../BlockRangeUpdateMessageSerializer.cs | 4 +- .../V69/Messages/ReceiptMessageDecoder69.cs | 6 +- .../Eth/V69/Messages/StatusMessage69.cs | 4 +- .../V69/Messages/StatusMessageSerializer69.cs | 4 +- .../Eth/V70/Eth70ProtocolHandler.cs | 65 ++-- .../AsyncFileWriteQueueTests.cs | 2 +- .../Output/CumulativeTraceOutput.cs | 8 +- .../Output/PerBlockTraceOutput.cs | 6 +- .../Output/TraceMetadata.cs | 6 +- .../TraceConfiguration.cs | 34 +- .../Tracing/OpcodeBlockTracer.cs | 2 +- .../Tracing/OpcodeCountingTxTracer.cs | 2 +- .../Tracing/OpcodeTraceRecorder.cs | 28 +- .../Tracing/RealTimeTracer.cs | 18 +- .../Tracing/RetrospectiveExecutionTracer.cs | 12 +- .../Tracing/RetrospectiveTracer.cs | 6 +- .../TracingProgress.cs | 20 +- .../Utilities/BlockRange.cs | 8 +- .../CL/DepositTransactionBuilderTest.cs | 14 +- .../Nethermind.Optimism.Test/ForkInfoTests.cs | 4 +- .../OptimismBaseFeeCalculatorTests.cs | 38 +- .../OptimismHeaderValidatorTests.cs | 22 +- .../Rpc/DepositTransactionForRpcTests.cs | 18 +- .../CL/Decoding/BatchV1.cs | 15 +- .../Derivation/DepositTransactionBuilder.cs | 6 +- .../CL/Derivation/PayloadAttributesDeriver.cs | 2 +- .../Nethermind.Optimism/CL/IL2Api.cs | 2 +- .../CL/L1Bridge/EthereumEthApi.cs | 2 +- .../Nethermind.Optimism/CL/L2Api.cs | 8 +- .../CL/P2P/P2PBlockValidator.cs | 2 +- .../CL/P2P/PayloadDecoder.cs | 6 +- .../CL/Rpc/OptimismOptimismRpcModule.cs | 2 +- .../CL/Rpc/OptimismRollupConfig.cs | 2 +- .../OptimismBaseFeeCalculator.cs | 6 +- .../OptimismBlockReceiptTracer.cs | 4 +- .../OptimismChainSpecEngineParameters.cs | 6 +- .../OptimismCompactReceiptStorageDecoder.cs | 4 +- .../Nethermind.Optimism/OptimismCostHelper.cs | 8 +- .../OptimismGasLimitCalculator.cs | 2 +- .../OptimismHeaderValidator.cs | 2 +- .../OptimismLegacyTxDecoder.cs | 2 +- .../OptimismPayloadTxSource.cs | 2 +- .../OptimismPoSSwitcher.cs | 4 +- .../OptimismReceiptMessageDecoder.cs | 6 +- .../Nethermind.Optimism/OptimismSpecHelper.cs | 2 +- .../OptimismTransactionProcessor.cs | 15 +- .../Nethermind.Optimism/OptimismTxDecoder.cs | 8 +- .../OptimismTxPoolTxSource.cs | 2 +- .../Rpc/DepositTransactionForRpc.cs | 10 +- .../Rpc/OptimismPayloadAttributes.cs | 8 +- src/Nethermind/Nethermind.PerfTest/Program.cs | 10 +- .../ConfigFilesTests.cs | 16 +- .../Steps/Migrations/ReceiptMigrationTests.cs | 40 ++- .../TotalDifficultyFixMigrationTest.cs | 44 ++- .../Nethermind.Runner/Monitoring/DataFeed.cs | 16 +- .../NumericConverterHelper.cs | 4 +- .../ULongConverter.cs | 26 ++ .../AccountDecoder.cs | 4 +- .../CompactReceiptStorageDecoder.cs | 4 +- .../HeaderDecoder.cs | 6 +- .../KeyValueStoreRlpExtensions.cs | 11 +- .../ReceiptMessageDecoder.cs | 6 +- .../ReceiptRecoveryBlock.cs | 2 +- .../ReceiptStorageDecoder.cs | 12 +- .../TxDecoders/BaseTxDecoder.cs | 8 +- .../Nethermind.Shutter/ShutterEon.cs | 2 +- .../Nethermind.Shutter/ShutterTxLoader.cs | 4 +- .../Nethermind.Shutter/ShutterTxSource.cs | 2 +- .../ChainSpecBasedSpecProviderTests.cs | 54 +-- .../ChainSpecStyle/GethGenesisLoaderTests.cs | 2 +- .../CustomSpecProvider.cs | 6 +- .../CustomSpecProviderTests.cs | 2 +- .../ForkScheduleSpecProviderTests.cs | 4 +- .../MainnetSpecProviderTests.cs | 20 +- .../OverridableReleaseSpec.cs | 14 +- .../OverridableSpecProvider.cs | 4 +- .../ChainSpecStyle/ChainParameters.cs | 108 +++--- .../ChainSpecStyle/ChainSpec.cs | 30 +- .../ChainSpecStyle/ChainSpecAllocation.cs | 4 +- .../ChainSpecBasedSpecProvider.cs | 161 +++++---- .../ChainSpecStyle/ChainSpecLoader.cs | 28 +- .../ChainSpecStyle/GethGenesisLoader.cs | 72 ++-- .../ChainSpecStyle/HardforkLabels.cs | 12 +- .../IChainSpecEngineParameters.cs | 4 +- .../Json/BlockRewardConverter.cs | 10 +- .../Json/ChainSpecEthereumSealJson.cs | 3 +- .../Json/ChainSpecGenesisJson.cs | 2 +- .../Json/ChainSpecParamsJson.cs | 110 +++--- .../Json/DifficultyBombDelaysConverter.cs | 64 ++++ .../Json/GethGenesisConfigJson.cs | 46 +-- .../Nethermind.Specs/ForkSchedule.cs | 16 +- .../ForkScheduleSpecProvider.cs | 18 +- src/Nethermind/Nethermind.Specs/ForkSpec.cs | 6 +- .../Nethermind.Specs/Forks/00_Olympic.cs | 4 +- .../Nethermind.Specs/FrontierSpecProvider.cs | 4 +- .../Nethermind.Specs/GnosisSpecProvider.cs | 14 +- .../Nethermind.Specs/MainnetSpecProvider.cs | 28 +- .../Nethermind.Specs/MordenSpecProvider.cs | 4 +- .../Nethermind.Specs/OlympicSpecProvider.cs | 4 +- .../Nethermind.Specs/ReleaseSpec.cs | 14 +- .../Nethermind.Specs/SepoliaSpecProvider.cs | 2 +- .../SingleReleaseSpecProvider.cs | 4 +- .../Nethermind.Specs/TestSpecProvider.cs | 6 +- .../CompactionScheduleTests.cs | 58 +-- .../FlatDbManagerTests.cs | 2 +- .../BloomFilter/BloomFilterTests.cs | 2 +- .../PersistenceManagerTests.cs | 26 +- .../SnapshotCompactorTests.cs | 54 +-- .../SnapshotRepositoryTests.cs | 14 +- .../CompactionSchedule.cs | 68 +++- .../Nethermind.State.Flat/FlatDbManager.cs | 6 +- .../ICompactionSchedule.cs | 4 +- .../ISnapshotRepository.cs | 4 +- .../Persistence/BasePersistence.cs | 6 +- .../PersistenceManager.cs | 51 ++- .../ScopeProvider/FlatReadOnlyTrieStore.cs | 6 +- .../ScopeProvider/FlatWorldStateScope.cs | 3 +- .../SnapshotCompactor.cs | 15 +- .../SnapshotRepository.cs | 10 +- .../Nethermind.State.Flat/StateId.cs | 8 +- .../Sync/FlatFullStateFinder.cs | 6 +- .../BlockchainTestStreamingTracerTests.cs | 6 +- .../BlockAccessListBasedWorldStateTests.cs | 4 +- .../Proofs/AccountProofCollectorTests.cs | 4 +- .../ChainLevelInfoRepositoryTests.cs | 2 +- .../StateProviderTests.cs | 10 +- .../Nethermind.State.Test/StateReaderTests.cs | 4 +- .../StorageProviderTests.cs | 2 +- .../TracedAccessWorldStateTests.cs | 12 +- .../WorldStateManagerTests.cs | 10 +- .../BlockAccessListBasedWorldState.cs | 22 +- .../OverridableEnv/OverridableSpecProvider.cs | 4 +- .../PrewarmerScopeProvider.cs | 2 +- .../Repositories/ChainLevelInfoRepository.cs | 10 +- .../Repositories/IChainLevelInfoRepository.cs | 8 +- .../Nethermind.State/Snap/AccountRange.cs | 4 +- .../Nethermind.State/Snap/StorageRange.cs | 2 +- .../Nethermind.State/StateProvider.cs | 21 +- .../Nethermind.State/StateReaderExtensions.cs | 2 +- .../TracedAccessWorldState.cs | 30 +- .../TrieStoreScopeProvider.cs | 2 +- src/Nethermind/Nethermind.State/WorldState.cs | 16 +- .../WorldStateMetricsScopeProvider.cs | 2 +- .../WorldStateScopeOperationLogger.cs | 2 +- .../Diff/TrieDiffWalkerTests.cs | 17 +- ...positionServiceIncrementalRecoveryTests.cs | 2 +- .../Snapshots/SnapshotRoundTripTests.cs | 4 +- .../Data/ScanMetadata.cs | 2 +- .../Data/StateCompositionReport.cs | 2 +- .../Data/StateCompositionSnapshot.cs | 4 +- .../Data/StateCompositionStats.cs | 2 +- .../Nethermind.StateComposition/Metrics.cs | 4 +- .../Service/StateCompositionService.cs | 4 +- .../Service/StateCompositionStateHolder.cs | 16 +- .../StateCompositionSnapshotDecoder.cs | 10 +- .../StateCompositionSnapshotStore.cs | 18 +- .../Visitors/StateCompositionVisitor.cs | 2 +- .../BlockDownloaderTests.Merge.cs | 66 ++-- .../BlockDownloaderTests.cs | 206 +++++------ .../E2ESyncTests.cs | 55 +-- .../BlockAccessListsSyncFeedTests.cs | 14 +- .../FastBlocks/BodiesSyncFeedTests.cs | 14 +- .../FastBlocks/FastHeadersSyncTests.cs | 72 ++-- .../FastBlocks/ReceiptsSyncFeedTests.cs | 46 +-- .../FastBlocks/SyncStatusListTests.cs | 20 +- .../StateSyncDispatcherTests.cs | 4 +- .../FastSync/StateSyncFeedHealingTests.cs | 6 +- .../FastSync/StateSyncFeedTests.cs | 4 +- .../FastSync/StateSyncFeedTestsBase.cs | 8 +- .../ForwardHeaderProviderTests.Merge.cs | 24 +- .../ForwardHeaderProviderTests.cs | 82 ++--- .../IContainerSynchronizerTestExtensions.cs | 2 +- .../MemorySyncPointers.cs | 6 +- .../ParallelSync/BaseSyncPeerMock.cs | 4 +- .../MultiSyncModeSelectorFastSyncTests.cs | 2 +- ...MultiSyncModeSelectorTestsBase.Scenario.cs | 96 ++--- .../PeerInfoAllocationTests.cs | 4 +- .../ReceiptSyncFeedTests.cs | 2 +- .../SnapSync/StateSyncPivotTest.cs | 14 +- .../SyncPeerPoolTests.cs | 4 +- .../SyncPeersReportTest.cs | 4 +- .../SyncProgressResolverTests.cs | 8 +- .../SyncServerTests.cs | 10 +- .../SynchronizerTests.cs | 8 +- ...lDifficultyBasedBetterPeerStrategyTests.cs | 14 +- .../Trie/HealingTreeTests.cs | 10 +- .../BetterPeerStrategyExtensions.cs | 9 +- .../Blocks/BlockDownloader.cs | 18 +- ...ByTotalDifficultyPeerAllocationStrategy.cs | 12 +- .../Blocks/PowForwardHeaderProvider.cs | 30 +- .../FastBlocks/BarrierSyncFeed.cs | 16 +- .../FastBlocks/BlockAccessListsSyncBatch.cs | 2 +- .../FastBlocks/BlockAccessListsSyncFeed.cs | 25 +- .../FastBlocks/BodiesSyncBatch.cs | 2 +- .../FastBlocks/BodiesSyncFeed.cs | 28 +- .../FastBlocksAllocationStrategy.cs | 4 +- .../FastBlocks/FastBlocksBatch.cs | 2 +- .../FastBlocks/HeadersSyncBatch.cs | 6 +- .../FastBlocks/HeadersSyncFeed.cs | 124 ++++--- .../FastBlocks/ReceiptsSyncBatch.cs | 2 +- .../FastBlocks/ReceiptsSyncFeed.cs | 27 +- .../FastBlocks/SyncStatusList.cs | 24 +- .../FastSync/BranchProgress.cs | 4 +- .../FastSync/IStateSyncPivot.cs | 2 +- .../FastSync/StateSyncPivot.cs | 13 +- .../FastSync/StateSyncRunner.cs | 11 +- .../FastSync/TreeSync.cs | 5 +- .../IBeaconSyncStrategy.cs | 4 +- .../IBetterPeerStrategy.cs | 6 +- .../Nethermind.Synchronization/IPivot.cs | 4 +- .../ISyncPointers.cs | 6 +- .../Nethermind.Synchronization/ISyncServer.cs | 6 +- .../ITotalDifficultyStrategy.cs | 3 +- .../Nethermind.Synchronization/Metrics.cs | 6 +- .../ParallelSync/FullStateFinder.cs | 31 +- .../ParallelSync/IFullStateFinder.cs | 2 +- .../ParallelSync/ISyncProgressResolver.cs | 8 +- .../ParallelSync/MultiSyncModeSelector.cs | 103 +++--- .../ParallelSync/SyncProgressResolver.cs | 21 +- .../Peers/PeerInfo.cs | 2 +- .../Peers/SyncPeerPool.cs | 1 + .../Nethermind.Synchronization/Pivot.cs | 6 +- .../Reporting/SyncReport.cs | 2 +- .../SnapSync/ProgressTracker.cs | 8 +- .../SnapSync/SnapProvider.cs | 2 +- .../SnapSync/SnapProviderHelper.cs | 2 +- .../SyncPointers.cs | 20 +- .../Nethermind.Synchronization/SyncServer.cs | 21 +- .../TotalDifficultyBetterPeerStrategy.cs | 6 +- .../BlockInvalidTxExecutorZkTests.cs | 3 +- .../CertainBatchLookupTests.cs | 4 +- .../SurgeGasPriceOracleTests.cs | 20 +- .../TaikoBeaconSyncTests.cs | 34 +- .../TaikoChainSpecEngineParametersTests.cs | 10 +- .../TaikoEthSyncingInfoTests.cs | 30 +- .../Tdx/TdxRpcModuleTests.cs | 6 +- .../TransactionProcessorTests.cs | 4 +- .../TxPoolContentListsTests.cs | 8 +- .../Nethermind.Taiko/BlockMetadata.cs | 2 +- .../Rpc/SurgeGasPriceOracle.cs | 4 +- .../Rpc/TaikoEngineRpcModule.cs | 10 +- .../Rpc/TaikoForkchoiceUpdatedHandler.cs | 2 +- .../TaikoBeaconHeadAdvancer.cs | 24 +- .../Nethermind.Taiko/TaikoBeaconSync.cs | 13 +- .../Nethermind.Taiko/TaikoBlockValidator.cs | 6 +- .../Nethermind.Taiko/TaikoEthSyncingInfo.cs | 10 +- .../Nethermind.Taiko/TaikoHeaderValidator.cs | 12 +- .../TaikoPayloadAttributes.cs | 2 +- .../TaikoChainSpecBasedSpecProvider.cs | 6 +- .../TaikoChainSpecEngineParameters.cs | 6 +- .../TaikoSyncProgressResolver.cs | 20 +- .../TaikoTransactionProcessor.cs | 4 +- .../Nethermind.Taiko/TaikoVirtualMachine.cs | 4 +- .../Nethermind.Taiko/Tdx/BlockHeaderForRpc.cs | 6 +- .../Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs | 25 +- .../BlockchainTestStreamingTracer.cs | 2 +- .../Nethermind.Test.Runner/StateTestRunner.cs | 2 +- .../StateTestTxTraceEntry.cs | 4 +- .../StateTestTxTraceResult.cs | 2 +- .../StateTestTxTracer.cs | 16 +- .../IFullTrieStoreExtensions.cs | 4 +- .../MaxBlockInCachePruneStrategyTests.cs | 8 +- .../MinBlockInCachePruneStrategyTests.cs | 8 +- .../Pruning/TestPruningStrategy.cs | 2 +- .../Pruning/TreeStoreTests.cs | 86 ++--- .../PruningScenariosTests.cs | 6 +- .../Nethermind.Trie.Test/TrieTests.cs | 14 +- .../Nethermind.Trie.Test/VisitingTests.cs | 4 +- .../Nethermind.Trie/PreCachedTrieStore.cs | 4 +- .../Nethermind.Trie/Pruning/Archive.cs | 2 +- .../Nethermind.Trie/Pruning/BlockCommitSet.cs | 4 +- .../Nethermind.Trie/Pruning/CommitSetQueue.cs | 8 +- .../Pruning/CompositePersistenceStrategy.cs | 2 +- .../Pruning/ConstantInterval.cs | 2 +- .../Pruning/IFinalizedStateProvider.cs | 4 +- .../Pruning/IPersistenceStrategy.cs | 2 +- .../Nethermind.Trie/Pruning/ITrieStore.cs | 4 +- .../Pruning/MaxBlockInCachePruneStrategy.cs | 4 +- .../Nethermind.Trie/Pruning/Metrics.cs | 2 +- .../Pruning/MinBlockInCachePruneStrategy.cs | 4 +- .../Nethermind.Trie/Pruning/NoPersistence.cs | 2 +- .../Pruning/OverlayTrieStore.cs | 2 +- .../Pruning/ReadOnlyTrieStore.cs | 4 +- .../Pruning/ReorgBoundaryReached.cs | 4 +- .../Nethermind.Trie/Pruning/TrieStore.cs | 112 +++--- .../Pruning/TrieStoreDirtyNodesCache.cs | 36 +- .../Nethermind.Trie/Pruning/TrieStoreState.cs | 4 +- .../Nethermind.Trie/RawTrieStore.cs | 2 +- src/Nethermind/Nethermind.Trie/TrieNode.cs | 8 +- .../Nethermind.Trie/VisitorProgressTracker.cs | 2 +- .../BlobTxStorageTests.cs | 4 +- .../DistinctValueSortedPoolTests.cs | 4 +- .../Collections/SortedPoolTests.cs | 8 +- .../DelegatedAccountFilterTest.cs | 9 +- .../NonceManagerTests.cs | 92 ++--- .../Nethermind.TxPool.Test/TestBlockTree.cs | 46 +-- .../TestChainHeadInfoProvider.cs | 4 +- .../TransactionExtensionsTests.cs | 6 +- .../TxBroadcasterTests.cs | 6 +- .../TxPoolInfoProviderTests.cs | 17 +- .../TxPoolTests.Blobs.cs | 72 ++-- .../Nethermind.TxPool.Test/TxPoolTests.cs | 60 ++-- .../Nethermind.TxPool/BlobTxStorage.cs | 8 +- .../Comparison/CompareReplacedTxByFee.cs | 10 +- .../Filters/GapNonceFilter.cs | 6 +- .../Filters/GasLimitTxFilter.cs | 4 +- .../Nethermind.TxPool/IBlobTxStorage.cs | 6 +- .../IChainHeadInfoProvider.cs | 4 +- .../Nethermind.TxPool/INonceManager.cs | 5 +- src/Nethermind/Nethermind.TxPool/ITxPool.cs | 2 +- .../Nethermind.TxPool/ITxPoolConfig.cs | 2 +- .../Nethermind.TxPool/ITxPoolPeer.cs | 2 +- .../Nethermind.TxPool/ITxValidator.cs | 2 +- .../Nethermind.TxPool/LightTransaction.cs | 10 +- .../Nethermind.TxPool/LightTxDecoder.cs | 14 +- .../Nethermind.TxPool/NonceManager.cs | 22 +- .../Nethermind.TxPool/NullBlobTxStorage.cs | 6 +- .../Nethermind.TxPool/NullTxPool.cs | 2 +- .../TransactionExtensions.cs | 14 +- .../Nethermind.TxPool/TxBroadcaster.cs | 2 +- src/Nethermind/Nethermind.TxPool/TxPool.cs | 20 +- .../Nethermind.TxPool/TxPoolConfig.cs | 2 +- .../Nethermind.TxPool/TxPoolInfoProvider.cs | 12 +- .../Nethermind.TxPool/TxPoolSender.cs | 3 +- .../EpochSwitchManagerTests.cs | 124 +++---- .../ForensicsProcessorTests.cs | 2 +- .../Helpers/TestXdcBlockProducer.cs | 2 +- .../TransactionBuilderXdcExtensions.cs | 6 +- .../Helpers/XdcBlockHeaderBuilder.cs | 2 +- .../Helpers/XdcModuleTestOverrides.cs | 4 +- .../Helpers/XdcSubnetBlockHeaderBuilder.cs | 2 +- .../Helpers/XdcTestBlockchain.cs | 16 +- .../Helpers/XdcTestHelper.cs | 2 +- .../ModuleTests/PenaltyTests.cs | 71 ++-- .../ModuleTests/ProposedBlockTests.cs | 23 +- .../ModuleTests/RewardTests.cs | 136 ++++--- .../ModuleTests/SubnetPenaltyTests.cs | 45 ++- .../ModuleTests/VotesManagerTests.cs | 8 +- .../ModuleTests/XdcReorgModuleTests.cs | 2 +- .../ModuleTests/XdcTestBlockchainTests.cs | 8 +- .../QuorumCertificateManagerTest.cs | 12 +- .../SignTransactionFilterTests.cs | 6 +- .../SnapshotManagerTests.cs | 76 ++-- .../SpecialTransactionsTests.cs | 54 +-- .../SubnetEpochSwitchManagerTests.cs | 12 +- .../SubnetMasternodesCalculatorTests.cs | 2 +- .../SubnetSnapshotManagerTests.cs | 22 +- .../TimeoutCertificateManagerTests.cs | 12 +- .../XdcBlockProcessorTests.cs | 16 +- .../XdcBlockProducerTest.cs | 4 +- .../Nethermind.Xdc.Test/XdcBlockTreeTests.cs | 44 +-- .../XdcGasLimitCalculatorTests.cs | 68 ++-- .../XdcHeaderValidatorTests.cs | 2 +- .../Nethermind.Xdc.Test/XdcOpcodesTests.cs | 8 +- .../Nethermind.Xdc.Test/XdcPoolTests.cs | 4 +- .../XdcSealValidatorTests.cs | 6 +- .../XdcStateSyncSnapshotManagerTests.cs | 36 +- .../Nethermind.Xdc.Test/XdcStateSyncTest.cs | 4 +- .../XdcSubnetSealValidatorTests.cs | 12 +- .../XdcTransactionProcessorTests.cs | 8 +- .../Nethermind.Xdc/BaseSnapshotManager.cs | 11 +- .../Contracts/MintedRecordContract.cs | 4 +- .../Nethermind.Xdc/EpochSwitchManager.cs | 46 ++- .../IncomingMessageBlockNotFoundException.cs | 4 +- .../Nethermind.Xdc/ForensicsProcessor.cs | 23 +- .../Nethermind.Xdc/IMasternodesCalculator.cs | 2 +- .../Nethermind.Xdc/IPenaltyHandler.cs | 2 +- .../Nethermind.Xdc/ISigningTxCache.cs | 2 +- .../Nethermind.Xdc/ISnapshotManager.cs | 6 +- .../Nethermind.Xdc/IVotesManager.cs | 2 +- .../Nethermind.Xdc/IXdcHeaderStore.cs | 2 +- .../Nethermind.Xdc/InitializeBlockchainXdc.cs | 18 +- .../Nethermind.Xdc/MasternodesCalculator.cs | 2 +- .../Nethermind.Xdc/PenaltyHandler.cs | 37 +- .../QuorumCertificateManager.cs | 12 +- .../Nethermind.Xdc/RLP/BaseSnapshotDecoder.cs | 4 +- .../RLP/BaseXdcHeaderDecoder.cs | 10 +- .../Nethermind.Xdc/RLP/XdcBlockInfoDecoder.cs | 2 +- .../Nethermind.Xdc/RLP/XdcHeaderDecoder.cs | 4 +- .../RLP/XdcSubnetHeaderDecoder.cs | 4 +- .../Nethermind.Xdc/SignTransactionManager.cs | 4 +- .../Nethermind.Xdc/SigningTxCache.cs | 2 +- .../Spec/XdcChainSpecBasedSpecProvider.cs | 19 +- .../Spec/XdcChainSpecEngineParameters.cs | 39 +- .../Nethermind.Xdc/Spec/XdcReleaseSpec.cs | 62 ++-- .../SubnetEpochSwitchManager.cs | 6 +- .../SubnetMasternodesCalculator.cs | 2 +- .../Nethermind.Xdc/SubnetPenaltyHandler.cs | 12 +- .../TimeoutCertificateManager.cs | 38 +- .../TxPool/SignTransactionFilter.cs | 14 +- .../TxPool/XdcTransactionComparerProvider.cs | 13 +- .../TxPool/XdcTxGossipPolicy.cs | 6 +- .../TxPool/XdcTxPoolTxSourceFactory.cs | 3 +- .../Nethermind.Xdc/Types/BlockRoundInfo.cs | 4 +- .../Nethermind.Xdc/Types/Forensics.cs | 2 +- .../Nethermind.Xdc/Types/Snapshot.cs | 4 +- .../Nethermind.Xdc/Types/SubnetSnapshot.cs | 4 +- src/Nethermind/Nethermind.Xdc/VotesManager.cs | 61 +++- .../Nethermind.Xdc/XdcBeaconSyncStrategy.cs | 2 +- .../Nethermind.Xdc/XdcBlockHeader.cs | 4 +- .../Nethermind.Xdc/XdcBlockProducer.cs | 4 +- src/Nethermind/Nethermind.Xdc/XdcBlockTree.cs | 4 +- .../Nethermind.Xdc/XdcExtensions.cs | 8 +- .../Nethermind.Xdc/XdcGasLimitCalculator.cs | 4 +- src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs | 2 +- .../Nethermind.Xdc/XdcRewardCalculator.cs | 70 ++-- .../Nethermind.Xdc/XdcSealValidator.cs | 2 +- src/Nethermind/Nethermind.Xdc/XdcSealer.cs | 2 +- .../Nethermind.Xdc/XdcStateSyncPivot.cs | 4 +- .../XdcStateSyncSnapshotManager.cs | 2 +- .../Nethermind.Xdc/XdcSubnetBlockHeader.cs | 4 +- .../Nethermind.Xdc/XdcSubnetBlockProducer.cs | 2 +- .../Nethermind.Xdc/XdcTransactionProcessor.cs | 10 +- tools/Evm/T8n/JsonTypes/EnvJson.cs | 10 +- tools/Evm/T8n/JsonTypes/Ommer.cs | 2 +- tools/Evm/T8n/JsonTypes/T8nExecutionResult.cs | 2 +- tools/Evm/T8n/T8nBlockHashProvider.cs | 8 +- tools/Evm/T8n/T8nExecutor.cs | 2 +- tools/Evm/T8n/T8nTest.cs | 16 +- .../CMSketchTests.cs | 4 +- .../Analyzer/Pattern/CMSketch.cs | 4 +- .../Tracer/Call/CallAnalyzerTxTrace.cs | 4 +- .../Tracer/Call/CallStatsAnalyzerTxTracer.cs | 4 +- .../Tracer/IStatsAnalyzerTxTracer.cs | 2 +- .../Tracer/Pattern/PatternAnalyzerTxTrace.cs | 4 +- .../Pattern/PatternStatsAnalyzerTxTracer.cs | 4 +- .../Tracer/StatsAnalyzerFileTracer.cs | 14 +- .../Tracer/StatsAnalyzerTxTracer.cs | 2 +- 1155 files changed, 8939 insertions(+), 8149 deletions(-) create mode 100644 src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs diff --git a/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs b/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs index 0e19b9636234..d82ce42f8ab1 100644 --- a/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs +++ b/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs @@ -73,7 +73,7 @@ private static TransactionTest Convert(TransactionTestJson testJson) Data = Bytes.FromHexString(testJson.Data), GasPrice = (UInt256)testJson.GasPrice, PrivateKey = new PrivateKey(testJson.Key), - Nonce = (UInt256)testJson.Nonce, + Nonce = testJson.Nonce, Signed = new Rlp(Bytes.FromHexString(testJson.Signed)) }; byte[] unsigned = Bytes.FromHexString(testJson.Unsigned); @@ -92,9 +92,9 @@ private static TransactionTest Convert(TransactionTestJson testJson) private class TransactionTestJson { public string Key { get; set; } - public long Nonce { get; set; } + public ulong Nonce { get; set; } public long GasPrice { get; set; } - public long StartGas { get; set; } + public ulong StartGas { get; set; } public string To { get; set; } public long Value { get; set; } public string Data { get; set; } @@ -106,9 +106,9 @@ private class TransactionTestJson public class TransactionTest { public PrivateKey PrivateKey { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public UInt256 GasPrice { get; set; } - public long StartGas { get; set; } + public ulong StartGas { get; set; } public Address To { get; set; } public UInt256 Value { get; set; } public byte[] Data { get; set; } diff --git a/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTestJson.cs b/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTestJson.cs index fa85071ab548..31feb73e961a 100644 --- a/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTestJson.cs +++ b/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTestJson.cs @@ -5,10 +5,10 @@ namespace Ethereum.Difficulty.Test { public class DifficultyTestJson { - public int ParentTimestamp { get; set; } - public int ParentDifficulty { get; set; } - public int CurrentTimestamp { get; set; } - public int CurrentBlockNumber { get; set; } - public int CurrentDifficulty { get; set; } + public ulong ParentTimestamp { get; set; } + public ulong ParentDifficulty { get; set; } + public ulong CurrentTimestamp { get; set; } + public ulong CurrentBlockNumber { get; set; } + public ulong CurrentDifficulty { get; set; } } } diff --git a/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTests.cs b/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTests.cs index 41f48071a635..a6e7584ae3f7 100644 --- a/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTests.cs +++ b/src/Nethermind/Ethereum.Difficulty.Test/DifficultyTests.cs @@ -13,14 +13,14 @@ public class DifficultyTests( ulong parentTimestamp, UInt256 parentDifficulty, ulong currentTimestamp, - long currentBlockNumber, + ulong currentBlockNumber, UInt256 currentDifficulty, bool parentHasUncles) { public ulong ParentTimestamp { get; set; } = parentTimestamp; public UInt256 ParentDifficulty { get; set; } = parentDifficulty; public ulong CurrentTimestamp { get; set; } = currentTimestamp; - public long CurrentBlockNumber { get; set; } = currentBlockNumber; + public ulong CurrentBlockNumber { get; set; } = currentBlockNumber; public bool ParentHasUncles { get; set; } = parentHasUncles; public UInt256 CurrentDifficulty { get; set; } = currentDifficulty; public string Name { get; set; } = name; diff --git a/src/Nethermind/Ethereum.Difficulty.Test/TestsBase.cs b/src/Nethermind/Ethereum.Difficulty.Test/TestsBase.cs index f007de24263d..c281e1563aa8 100644 --- a/src/Nethermind/Ethereum.Difficulty.Test/TestsBase.cs +++ b/src/Nethermind/Ethereum.Difficulty.Test/TestsBase.cs @@ -56,11 +56,11 @@ private static IEnumerable ExtractHexTests(string fileName, Dic private static DifficultyTests ToTest(string fileName, string name, DifficultyTestJson json) => new(fileName, name, - (ulong)json.ParentTimestamp, - (ulong)json.ParentDifficulty, - (ulong)json.CurrentTimestamp, + json.ParentTimestamp, + json.ParentDifficulty, + json.CurrentTimestamp, json.CurrentBlockNumber, - (ulong)json.CurrentDifficulty, + json.CurrentDifficulty, false); private static UInt256 ToUInt256(string hex) => Bytes.FromHexString(hex.Replace("0x", "0")).ToUInt256(); @@ -71,7 +71,7 @@ private static DifficultyTests ToTest(string fileName, string name, DifficultyTe (ulong)ToUInt256(json.ParentTimestamp), ToUInt256(json.ParentDifficulty), (ulong)ToUInt256(json.CurrentTimestamp), - (long)ToUInt256(json.CurrentBlockNumber), + (ulong)ToUInt256(json.CurrentBlockNumber), ToUInt256(json.CurrentDifficulty), HasUncles(json.ParentUncles)); diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs index 78c47f5e632b..8bfb9ba00a03 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs @@ -107,7 +107,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) test.Transaction.ChainId = test.ChainId; } - IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)test.CurrentNumber); + IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)(ulong)test.CurrentNumber); Transaction[] transactions = [test.Transaction]; Withdrawal[]? withdrawals = spec.WithdrawalsEnabled ? [] : null; @@ -116,8 +116,8 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) Keccak.OfAnEmptySequenceRlp, test.CurrentCoinbase, test.CurrentDifficulty, - test.CurrentNumber, - test.CurrentGasLimit, + (ulong)test.CurrentNumber, + (ulong)test.CurrentGasLimit, test.CurrentTimestamp, []) { @@ -209,7 +209,7 @@ public static void InitializeTestState(Dictionary preStat storageItem.Value.WithoutLeadingZeros().ToArray()); } - stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, accountState.Value.Nonce); + stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, (ulong)accountState.Value.Nonce); stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec); } diff --git a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs index 057164d1dcbe..666591872e6f 100644 --- a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs @@ -30,7 +30,7 @@ private static ForkActivation TransitionForkActivation(string transitionInfo) const char kSuffix = 'k'; if (!transitionInfo.StartsWith(timestampPrefix)) { - return new ForkActivation(int.Parse(transitionInfo)); + return new ForkActivation(ulong.Parse(transitionInfo)); } transitionInfo = transitionInfo.Remove(0, timestampPrefix.Length); @@ -55,19 +55,19 @@ public static BlockHeader Convert(TestBlockHeaderJson? headerJson) new Hash256(headerJson.UncleHash), new Address(headerJson.Coinbase), Bytes.FromHexString(headerJson.Difficulty).ToUInt256(), - (long)Bytes.FromHexString(headerJson.Number).ToUInt256(), - (long)Bytes.FromHexString(headerJson.GasLimit).ToUnsignedBigInteger(), + (ulong)Bytes.FromHexString(headerJson.Number).ToUInt256(), + (ulong)Bytes.FromHexString(headerJson.GasLimit).ToUnsignedBigInteger(), (ulong)Bytes.FromHexString(headerJson.Timestamp).ToUnsignedBigInteger(), Bytes.FromHexString(headerJson.ExtraData), - headerJson.BlobGasUsed is null ? null : (ulong)Bytes.FromHexString(headerJson.BlobGasUsed).ToUnsignedBigInteger(), - headerJson.ExcessBlobGas is null ? null : (ulong)Bytes.FromHexString(headerJson.ExcessBlobGas).ToUnsignedBigInteger(), + headerJson.BlobGasUsed is null ? null : (ulong?)Bytes.FromHexString(headerJson.BlobGasUsed).ToUnsignedBigInteger(), + headerJson.ExcessBlobGas is null ? null : (ulong?)Bytes.FromHexString(headerJson.ExcessBlobGas).ToUnsignedBigInteger(), headerJson.ParentBeaconBlockRoot is null ? null : new Hash256(headerJson.ParentBeaconBlockRoot), headerJson.RequestsHash is null ? null : new Hash256(headerJson.RequestsHash), headerJson.SlotNumber is null ? null : (ulong)Bytes.FromHexString(headerJson.SlotNumber).ToUnsignedBigInteger() ) { Bloom = new Bloom(Bytes.FromHexString(headerJson.Bloom)), - GasUsed = (long)Bytes.FromHexString(headerJson.GasUsed).ToUnsignedBigInteger(), + GasUsed = (ulong)Bytes.FromHexString(headerJson.GasUsed).ToUnsignedBigInteger(), Hash = new Hash256(headerJson.Hash), MixHash = new Hash256(headerJson.MixHash), Nonce = (ulong)Bytes.FromHexString(headerJson.Nonce).ToUnsignedBigInteger(), @@ -116,10 +116,10 @@ public static Transaction Convert(PostStateJson postStateJson, TransactionJson t { Type = transactionJson.Type, Value = transactionJson.Value[postStateJson.Indexes.Value], - GasLimit = transactionJson.GasLimit[postStateJson.Indexes.Gas], + GasLimit = (ulong)transactionJson.GasLimit[postStateJson.Indexes.Gas], GasPrice = transactionJson.GasPrice ?? transactionJson.MaxPriorityFeePerGas ?? 0, DecodedMaxFeePerGas = transactionJson.MaxFeePerGas ?? 0, - Nonce = transactionJson.Nonce, + Nonce = (ulong)transactionJson.Nonce, To = transactionJson.To, Data = transactionJson.Data[postStateJson.Indexes.Data], SenderAddress = new PrivateKey(transactionJson.SecretKey).Address, @@ -226,9 +226,9 @@ public static Transaction Convert(LegacyTransactionJson transactionJson) Transaction transaction = new() { Value = transactionJson.Value, - GasLimit = transactionJson.GasLimit, + GasLimit = (ulong)transactionJson.GasLimit, GasPrice = transactionJson.GasPrice, - Nonce = transactionJson.Nonce, + Nonce = (ulong)transactionJson.Nonce, To = transactionJson.To, Data = transactionJson.Data, Signature = new Signature(transactionJson.R, transactionJson.S, transactionJson.V) diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs index 3a5dcf6afc06..2a81bb7f1fb7 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs @@ -12,7 +12,7 @@ namespace Ethereum.Test.Base { public class TestBlockhashProvider : IBlockhashProvider { - public Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec? spec) => + public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec? spec) => number != 0 ? Keccak.Zero : Keccak.Compute(number.ToString()); public Task Prefetch(BlockHeader currentBlock, CancellationToken token) => Task.CompletedTask; diff --git a/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs b/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs index fae540454b4f..c33e4ff6d0dc 100644 --- a/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs +++ b/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs @@ -69,7 +69,7 @@ public void Invalid_pre_berlin_access_list_tx_with_empty_list_preserves_prestate .WithAccessList(AccessList.Empty) .WithGasLimit(100_000) .WithGasPrice(10) - .WithNonce(UInt256.Zero) + .WithNonce(0UL) .To(recipient) .WithValue(0) .SignedAndResolved(TestItem.PrivateKeyA) diff --git a/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs b/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs index 932c1180148f..b60117fad564 100644 --- a/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs +++ b/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs @@ -97,9 +97,9 @@ private static void RunTest(TransactionTest test, IReleaseSpec spec) { Assert.That(transaction.Value, Is.EqualTo(validTest.Value), "value"); Assert.That(transaction.Data.AsArray(), Is.EqualTo(validTest.Data), "data"); - Assert.That(transaction.GasLimit, Is.EqualTo(validTest.GasLimit.ToInt64(null)), "gasLimit"); + Assert.That(transaction.GasLimit, Is.EqualTo((ulong)validTest.GasLimit), "gasLimit"); Assert.That(transaction.GasPrice, Is.EqualTo(validTest.GasPrice), "gasPrice"); - Assert.That(transaction.Nonce, Is.EqualTo(validTest.Nonce), "nonce"); + Assert.That(transaction.Nonce, Is.EqualTo((ulong)validTest.Nonce), "nonce"); Assert.That(transaction.To, Is.EqualTo(validTest.To), "to"); Assert.That(validator.IsWellFormed(transaction, spec), Is.True); diff --git a/src/Nethermind/Nethermind.Api/IInitConfig.cs b/src/Nethermind/Nethermind.Api/IInitConfig.cs index 712538a0c923..f687aab856a5 100644 --- a/src/Nethermind/Nethermind.Api/IInitConfig.cs +++ b/src/Nethermind/Nethermind.Api/IInitConfig.cs @@ -85,7 +85,7 @@ public interface IInitConfig : IConfig INodeStorage.KeyScheme StateDbKeyScheme { get; set; } [ConfigItem(Description = "[TECHNICAL] Exit when block number is reached. Useful for scripting and testing.", DefaultValue = "null", HiddenFromDocs = true)] - long? ExitOnBlockNumber { get; set; } + ulong? ExitOnBlockNumber { get; set; } [ConfigItem(Description = "[TECHNICAL] Exit when invalid block is triggered. Useful for scripting and testing.", DefaultValue = "null", HiddenFromDocs = true)] bool ExitOnInvalidBlock { get; set; } diff --git a/src/Nethermind/Nethermind.Api/InitConfig.cs b/src/Nethermind/Nethermind.Api/InitConfig.cs index 946af2a0f16a..1527f3640a16 100644 --- a/src/Nethermind/Nethermind.Api/InitConfig.cs +++ b/src/Nethermind/Nethermind.Api/InitConfig.cs @@ -35,7 +35,7 @@ public class InitConfig : IInitConfig public bool DisableGcOnNewPayload { get; set; } = true; public bool DisableMallocOpts { get; set; } = false; public INodeStorage.KeyScheme StateDbKeyScheme { get; set; } = INodeStorage.KeyScheme.Current; - public long? ExitOnBlockNumber { get; set; } = null; + public ulong? ExitOnBlockNumber { get; set; } = null; public bool ExitOnInvalidBlock { get; set; } = false; public int BackgroundTaskConcurrency { get; set; } = 2; public int BackgroundTaskMaxNumber { get; set; } = 2048; diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaAdditionalBlockProcessorFactoryTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaAdditionalBlockProcessorFactoryTests.cs index af79e1ee3f72..ab60f5e24c9c 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaAdditionalBlockProcessorFactoryTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaAdditionalBlockProcessorFactoryTests.cs @@ -52,7 +52,7 @@ public void returns_correct_validator_type(AuRaParameters.ValidatorType validato { ValidatorType = validatorType, Addresses = new[] { Address.Zero }, - Validators = new Dictionary() + Validators = new Dictionary() { { 0, new AuRaParameters.Validator() diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs index f30aa9bca8e2..9fd45b2671ac 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs @@ -33,7 +33,7 @@ public void Initialize() _validatorStore = Substitute.For(); _logManager = LimboLogs.Instance; - _validatorStore.GetValidators(Arg.Any()).Returns([TestItem.AddressA, TestItem.AddressB, TestItem.AddressC]); + _validatorStore.GetValidators(Arg.Any()).Returns([TestItem.AddressA, TestItem.AddressB, TestItem.AddressC]); } [Test] @@ -62,9 +62,9 @@ public void repeated_SetMainBlockBranchProcessor_is_idempotent() Assert.That(finalizationManager.LastFinalizedBlockLevel, Is.EqualTo(1)); } - private void FinalizeToLevel(long upperLevel, IChainLevelInfoRepository chainLevelInfoRepository) + private void FinalizeToLevel(ulong upperLevel, IChainLevelInfoRepository chainLevelInfoRepository) { - for (long i = 0; i <= upperLevel; i++) + for (ulong i = 0; i <= upperLevel; i++) { ChainLevelInfo? level = chainLevelInfoRepository.LoadLevel(i); if (level?.MainChainBlock is not null) @@ -79,21 +79,21 @@ public static IEnumerable FinalizingTests { get { - yield return new TestCaseData(10, long.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB }, 1); - yield return new TestCaseData(10, long.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 1); - yield return new TestCaseData(10, long.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD }, 2); - - yield return new TestCaseData(10, 0, new[] { TestItem.AddressA }, 0); - yield return new TestCaseData(10, 0, new[] { TestItem.AddressA, TestItem.AddressB }, 1); - yield return new TestCaseData(10, 0, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 2); - yield return new TestCaseData(10, 0, TestItem.Addresses.Take(10).ToArray(), 6); + yield return new TestCaseData(10, ulong.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB }, 1); + yield return new TestCaseData(10, ulong.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 1); + yield return new TestCaseData(10, ulong.MaxValue, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD }, 2); + + yield return new TestCaseData(10, 0UL, new[] { TestItem.AddressA }, 0); + yield return new TestCaseData(10, 0UL, new[] { TestItem.AddressA, TestItem.AddressB }, 1); + yield return new TestCaseData(10, 0UL, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 2); + yield return new TestCaseData(10, 0UL, TestItem.Addresses.Take(10).ToArray(), 6); } } [TestCaseSource(nameof(FinalizingTests))] - public void correctly_finalizes_blocks_in_chain(int chainLength, long twoThirdsMajorityTransition, Address[] blockCreators, int notFinalizedExpectedCount) + public void correctly_finalizes_blocks_in_chain(int chainLength, ulong twoThirdsMajorityTransition, Address[] blockCreators, int notFinalizedExpectedCount) { - _validatorStore.GetValidators(Arg.Any()).Returns(blockCreators); + _validatorStore.GetValidators(Arg.Any()).Returns(blockCreators); BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(); HashSet finalizedBlocks = []; @@ -113,12 +113,12 @@ public void correctly_finalizes_blocks_in_chain(int chainLength, long twoThirdsM int start = 0; for (int i = start; i < chainLength; i++) { - Hash256 blockHash = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.BlockHash; + Hash256 blockHash = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i).MainChainBlock.BlockHash; Block? block = blockTreeBuilder.TestObject.FindBlock(blockHash, BlockTreeLookupOptions.None); _blockProcessor.BlockProcessed += Raise.EventWith(new BlockProcessedEventArgs(block, [])); } - IEnumerable isBlockFinalized = Enumerable.Range(start, chainLength).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.IsFinalized); + IEnumerable isBlockFinalized = Enumerable.Range(start, chainLength).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i).MainChainBlock.IsFinalized); IEnumerable expected = Enumerable.Range(start, chainLength).Select(i => i < chainLength - notFinalizedExpectedCount); Assert.That(finalizedBlocks.Count, Is.EqualTo(chainLength - notFinalizedExpectedCount)); Assert.That(isBlockFinalized, Is.EqualTo(expected)); @@ -132,7 +132,7 @@ public void correctly_finalizes_blocks_in_already_in_chain_on_initialize() AuRaBlockFinalizationManager finalizationManager = new(blockTreeBuilder.TestObject, blockTreeBuilder.ChainLevelInfoRepository, _validatorStore, _logManager); finalizationManager.SetMainBlockBranchProcessor(_blockProcessor); - IEnumerable result = Enumerable.Range(0, count).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.IsFinalized); + IEnumerable result = Enumerable.Range(0, count).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i).MainChainBlock.IsFinalized); Assert.That(result, Is.EqualTo(new[] { true, false })); } @@ -141,11 +141,11 @@ public void correctly_finalizes_blocks_in_already_in_chain_on_initialize() [TestCase(4, 5, ExpectedResult = new[] { 1, 3, 1, 0, 0 })] public int[] correctly_finalizes_blocks_on_reorganisations(int validators, int chainLength) { - _validatorStore.GetValidators(Arg.Any()).Returns(TestItem.Addresses.Take(validators).ToArray()); + _validatorStore.GetValidators(Arg.Any()).Returns(TestItem.Addresses.Take(validators).ToArray()); void ProcessBlock(BlockTreeBuilder blockTreeBuilder1, int level, int index) { - Hash256 blockHash = blockTreeBuilder1.ChainLevelInfoRepository.LoadLevel(level).BlockInfos[index].BlockHash; + Hash256 blockHash = blockTreeBuilder1.ChainLevelInfoRepository.LoadLevel((ulong)level).BlockInfos[index].BlockHash; Block? block = blockTreeBuilder1.TestObject.FindBlock(blockHash, BlockTreeLookupOptions.None); _blockProcessor.BlockProcessed += Raise.EventWith(new BlockProcessedEventArgs(block, [])); } @@ -173,7 +173,7 @@ void ProcessBlock(BlockTreeBuilder blockTreeBuilder1, int level, int index) ProcessBlock(blockTreeBuilder, chainLength - 1, 0); int[] finalizedBLocks = Enumerable.Range(0, chainLength) - .Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).BlockInfos.Select((b, j) => b.IsFinalized ? j + 1 : 0).Sum()) + .Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i).BlockInfos.Select((b, j) => b.IsFinalized ? j + 1 : 0).Sum()) .ToArray(); return finalizedBLocks; } @@ -182,17 +182,17 @@ public static IEnumerable GetLastFinalizedByTests { get { - yield return new TestCaseData(2, new[] { TestItem.AddressA, TestItem.AddressB }, 2) { ExpectedResult = 0 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB }, 2) { ExpectedResult = 8 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 3) { ExpectedResult = 7 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 4) { ExpectedResult = 0 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 2) { ExpectedResult = 8 }; - yield return new TestCaseData(100, TestItem.Addresses.Take(30).ToArray(), 30) { ExpectedResult = 70 }; + yield return new TestCaseData(2, new[] { TestItem.AddressA, TestItem.AddressB }, 2) { ExpectedResult = 0UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB }, 2) { ExpectedResult = 8UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 3) { ExpectedResult = 7UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 4) { ExpectedResult = 0UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 2) { ExpectedResult = 8UL }; + yield return new TestCaseData(100, TestItem.Addresses.Take(30).ToArray(), 30) { ExpectedResult = 70UL }; } } [TestCaseSource(nameof(GetLastFinalizedByTests))] - public long GetLastFinalizedBy_test(int chainLength, Address[] beneficiaries, int minForFinalization) + public ulong GetLastFinalizedBy_test(int chainLength, Address[] beneficiaries, int minForFinalization) { SetupValidators(minForFinalization, beneficiaries); BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree().OfChainLength(chainLength, blockBeneficiaries: beneficiaries); @@ -200,30 +200,30 @@ public long GetLastFinalizedBy_test(int chainLength, Address[] beneficiaries, in AuRaBlockFinalizationManager finalizationManager = new(blockTree, blockTreeBuilder.ChainLevelInfoRepository, _validatorStore, _logManager); finalizationManager.SetMainBlockBranchProcessor(_blockProcessor); - long result = finalizationManager.GetLastLevelFinalizedBy(blockTree.Head.Hash); + ulong result = finalizationManager.GetLastLevelFinalizedBy(blockTree.Head.Hash); return result; } private void SetupValidators(int minForFinalization, params Address[] beneficiaries) { Address[] validators = beneficiaries.Union(TestItem.Addresses.TakeLast(Math.Max(0, minForFinalization - 1) * 2 - beneficiaries.Length)).ToArray(); - _validatorStore.GetValidators(Arg.Any()).Returns(validators); + _validatorStore.GetValidators(Arg.Any()).Returns(validators); } public static IEnumerable GetFinalizationLevelTests { get { - yield return new TestCaseData(2, new[] { TestItem.AddressA, TestItem.AddressB }, 2, 2) { ExpectedResult = null }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB }, 2, 5) { ExpectedResult = 6 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 3, 5) { ExpectedResult = 7 }; - yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD }, 4, 5) { ExpectedResult = 8 }; - yield return new TestCaseData(100, TestItem.Addresses.Take(30).ToArray(), 30, 60) { ExpectedResult = 89 }; + yield return new TestCaseData(2, new[] { TestItem.AddressA, TestItem.AddressB }, 2, 2UL) { ExpectedResult = null }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB }, 2, 5UL) { ExpectedResult = 6UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC }, 3, 5UL) { ExpectedResult = 7UL }; + yield return new TestCaseData(10, new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD }, 4, 5UL) { ExpectedResult = 8UL }; + yield return new TestCaseData(100, TestItem.Addresses.Take(30).ToArray(), 30, 60UL) { ExpectedResult = 89UL }; } } [TestCaseSource(nameof(GetFinalizationLevelTests))] - public long? GetFinalizationLevel_tests(int chainLength, Address[] beneficiaries, int minForFinalization, long level) + public ulong? GetFinalizationLevel_tests(int chainLength, Address[] beneficiaries, int minForFinalization, ulong level) { SetupValidators(minForFinalization, beneficiaries); BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree().OfChainLength(chainLength, blockBeneficiaries: beneficiaries); @@ -231,14 +231,14 @@ public static IEnumerable GetFinalizationLevelTests AuRaBlockFinalizationManager finalizationManager = new(blockTree, blockTreeBuilder.ChainLevelInfoRepository, _validatorStore, _logManager); finalizationManager.SetMainBlockBranchProcessor(_blockProcessor); - long? result = finalizationManager.GetFinalizationLevel(level); + ulong? result = finalizationManager.GetFinalizationLevel(level); return result; } - [TestCase(2, 11, 10, ExpectedResult = 11)] - [TestCase(3, 11, 10, ExpectedResult = null)] - [TestCase(3, 20, 10, ExpectedResult = 12)] - public long? GetFinalizationLevel_when_before_pivot_and_not_synced(int minForFinalization, long bestKnownBlock, long level) + [TestCase(2, 11UL, 10UL, ExpectedResult = 11UL)] + [TestCase(3, 11UL, 10UL, ExpectedResult = null)] + [TestCase(3, 20UL, 10UL, ExpectedResult = 12UL)] + public ulong? GetFinalizationLevel_when_before_pivot_and_not_synced(int minForFinalization, ulong bestKnownBlock, ulong level) { SetupValidators(minForFinalization); IBlockTree blockTree = Substitute.For(); @@ -259,7 +259,7 @@ public static IEnumerable GetFinalizationLevelTests public void correctly_de_finalizes_blocks_on_block_reprocessing(int chainLength, int rerun, int validatorCount, bool twoThirdsMajorityTransition) { Address[] blockCreators = TestItem.Addresses.Take(validatorCount).ToArray(); - _validatorStore.GetValidators(Arg.Any()).Returns(blockCreators); + _validatorStore.GetValidators(Arg.Any()).Returns(blockCreators); BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(); AuRaBlockFinalizationManager finalizationManager = new( @@ -267,14 +267,14 @@ public void correctly_de_finalizes_blocks_on_block_reprocessing(int chainLength, blockTreeBuilder.ChainLevelInfoRepository, _validatorStore, _logManager, - twoThirdsMajorityTransition ? 0 : long.MaxValue); + twoThirdsMajorityTransition ? 0UL : ulong.MaxValue); finalizationManager.SetMainBlockBranchProcessor(_blockProcessor); blockTreeBuilder.OfChainLength(chainLength, blockBeneficiaries: blockCreators); - FinalizeToLevel(chainLength, blockTreeBuilder.ChainLevelInfoRepository); + FinalizeToLevel((ulong)chainLength, blockTreeBuilder.ChainLevelInfoRepository); List blocks = Enumerable.Range(1, rerun) - .Select(i => blockTreeBuilder.TestObject.FindBlock(chainLength - i, BlockTreeLookupOptions.None)) + .Select(i => blockTreeBuilder.TestObject.FindBlock((ulong)(chainLength - i), BlockTreeLookupOptions.None)) .Reverse() .ToList(); @@ -283,10 +283,10 @@ public void correctly_de_finalizes_blocks_on_block_reprocessing(int chainLength, int majority = (twoThirdsMajorityTransition ? (validatorCount - 1) * 2 / 3 : (validatorCount - 1) / 2) + 1; for (int i = 1; i < rerun + majority; i++) { - Assert.That(blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(chainLength - i).MainChainBlock.IsFinalized, Is.False); + Assert.That(blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)(chainLength - i)).MainChainBlock.IsFinalized, Is.False); } - Assert.That(blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(chainLength - rerun - majority - 1).MainChainBlock.IsFinalized, Is.True); + Assert.That(blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)(chainLength - rerun - majority - 1)).MainChainBlock.IsFinalized, Is.True); } } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs index e6bcf207f3dd..50d42fef103f 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs @@ -58,13 +58,13 @@ public Context() Timestamper = Substitute.For(); AuRaStepCalculator = Substitute.For(); NodeAddress = TestItem.AddressA; - TransactionSource.GetTransactions(Arg.Any(), Arg.Any()).Returns(Array.Empty()); - Sealer.CanSeal(Arg.Any(), Arg.Any()).Returns(true); + TransactionSource.GetTransactions(Arg.Any(), Arg.Any()).Returns(Array.Empty()); + Sealer.CanSeal(Arg.Any(), Arg.Any()).Returns(true); Sealer.SealBlock(Arg.Any(), Arg.Any()).Returns(c => Task.FromResult(c.Arg())); Sealer.Address.Returns(TestItem.AddressA); BlockProcessingQueue.IsEmpty.Returns(true); AuRaStepCalculator.TimeToNextStep.Returns(StepDelay); - BlockTree.BestKnownNumber.Returns(1); + BlockTree.BestKnownNumber.Returns(1UL); BlockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithAura(10, []).TestObject).TestObject); BlockchainProcessor.Process(Arg.Any(), ProcessingOptions.ProducingBlock, Arg.Any(), Arg.Any()).Returns(returnThis: c => { @@ -151,7 +151,7 @@ public async Task Does_not_produce_block_when_QueueNotEmpty() public async Task Does_not_produce_block_when_cannot_seal() { Context context = new(); - context.Sealer.CanSeal(Arg.Any(), Arg.Any()).Returns(false); + context.Sealer.CanSeal(Arg.Any(), Arg.Any()).Returns(false); (await StartStop(context)).ShouldProduceBlocks(Quantity.None()); } @@ -170,7 +170,7 @@ public async Task Produces_block_when_ForceSealing_is_false_and_there_are_transa Context context = new(); AuRaConfig auRaConfig = new() { ForceSealing = false }; context.InitProducer(auRaConfig); - context.TransactionSource.GetTransactions(Arg.Any(), Arg.Any()).Returns(new[] { Build.A.Transaction.TestObject }); + context.TransactionSource.GetTransactions(Arg.Any(), Arg.Any()).Returns(new[] { Build.A.Transaction.TestObject }); (await StartStop(context)).ShouldProduceBlocks(Quantity.AtLeastOne()); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs index b4da1c0bedb8..a138fcfee0ad 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs @@ -18,27 +18,27 @@ namespace Nethermind.AuRa.Test { public class AuRaContractGasLimitOverrideTests { - [TestCase(false, 1, 4000000)] - [TestCase(true, 1, 4000000)] - [TestCase(false, 3, 1000)] - [TestCase(false, 5, 3000000)] - [TestCase(true, 3, 2000000)] - [TestCase(true, 5, 3000000)] - [TestCase(true, 10, 4000000)] - [TestCase(false, 10, 4000000)] - public void GetGasLimit(bool minimum2MlnGasPerBlockWhenUsingBlockGasLimit, long blockNumber, long? expected) + [TestCase(false, 1UL, 4000000)] + [TestCase(true, 1UL, 4000000)] + [TestCase(false, 3UL, 1000)] + [TestCase(false, 5UL, 3000000)] + [TestCase(true, 3UL, 2000000)] + [TestCase(true, 5UL, 3000000)] + [TestCase(true, 10UL, 4000000)] + [TestCase(false, 10UL, 4000000)] + public void GetGasLimit(bool minimum2MlnGasPerBlockWhenUsingBlockGasLimit, ulong blockNumber, long? expected) { IBlockGasLimitContract blockGasLimitContract1 = Substitute.For(); - blockGasLimitContract1.ActivationBlock.Returns(3); - blockGasLimitContract1.Activation.Returns(3); + blockGasLimitContract1.ActivationBlock.Returns(3UL); + blockGasLimitContract1.Activation.Returns(3UL); blockGasLimitContract1.BlockGasLimit(Arg.Any()).Returns(1000u); IBlockGasLimitContract blockGasLimitContract2 = Substitute.For(); - blockGasLimitContract2.ActivationBlock.Returns(5); - blockGasLimitContract2.Activation.Returns(5); + blockGasLimitContract2.ActivationBlock.Returns(5UL); + blockGasLimitContract2.Activation.Returns(5UL); blockGasLimitContract2.BlockGasLimit(Arg.Any()).Returns(3000000u); IBlockGasLimitContract blockGasLimitContract3 = Substitute.For(); - blockGasLimitContract3.ActivationBlock.Returns(10); - blockGasLimitContract3.Activation.Returns(10); + blockGasLimitContract3.ActivationBlock.Returns(10UL); + blockGasLimitContract3.Activation.Returns(10UL); blockGasLimitContract3.BlockGasLimit(Arg.Any()).Throws(new AbiException(string.Empty)); BlocksConfig config = new() { TargetBlockGasLimit = 4000000 }; diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaHealthHintServiceTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaHealthHintServiceTests.cs index 3558fdd3012a..24b6c83271f0 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaHealthHintServiceTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaHealthHintServiceTests.cs @@ -22,7 +22,7 @@ public void GetBlockProcessorAndProducerIntervalHint_returns_expected_result( BlockProcessorIntervalHint test) { ManualTimestamper manualTimestamper = new(DateTime.UtcNow); - AuRaStepCalculator stepCalculator = new(new Dictionary() { { 0, test.StepDuration } }, manualTimestamper, LimboLogs.Instance); + AuRaStepCalculator stepCalculator = new(new Dictionary() { { 0, test.StepDuration } }, manualTimestamper, LimboLogs.Instance); IValidatorStore validatorStore = Substitute.For(); validatorStore.GetValidators().Returns(new Address[test.ValidatorsCount]); IHealthHintService healthHintService = new AuraHealthHintService(stepCalculator, validatorStore); diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs index 647432016edb..6058e61350c4 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs @@ -146,8 +146,8 @@ TestCaseData GetTestCaseData( object cause = null; - _reportingValidator.ReportBenign(Arg.Any
(), Arg.Any(), Arg.Do(c => cause ??= c)); - _reportingValidator.ReportMalicious(Arg.Any
(), Arg.Any(), Arg.Any(), Arg.Do(c => cause ??= c)); + _reportingValidator.ReportBenign(Arg.Any
(), Arg.Any(), Arg.Do(c => cause ??= c)); + _reportingValidator.ReportMalicious(Arg.Any
(), Arg.Any(), Arg.Any(), Arg.Do(c => cause ??= c)); BlockHeader header = null, parent = null; _reportingValidator.TryReportSkipped(Arg.Do(h => header = h), Arg.Do(h => parent = h)); @@ -179,7 +179,7 @@ public void validate_params_out_of_order() _validSealerStrategy.IsValidSealer(Arg.Any>(), Arg.Any
(), Arg.Any(), out _).Returns(true); object cause = null; - _reportingValidator.ReportMalicious(Arg.Any
(), Arg.Any(), Arg.Any(), + _reportingValidator.ReportMalicious(Arg.Any
(), Arg.Any(), Arg.Any(), Arg.Do(c => cause ??= c)); // step 15 arrives first @@ -229,7 +229,7 @@ private static IEnumerable ValidateSealTests } [TestCaseSource(nameof(ValidateSealTests))] - public bool validate_seal(long blockNumber, Address signedAddress, Address recoveredAddress) + public bool validate_seal(ulong blockNumber, Address signedAddress, Address recoveredAddress) { signedAddress ??= _address; recoveredAddress ??= _address; diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs index d9d0d0e41bf6..2faaad8e62f0 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs @@ -83,8 +83,10 @@ public void step_are_calculated_correctly(IList<(long SecondsOffset, long StepDu { DateTimeOffset now = DateTimeOffset.FromUnixTimeSeconds(BaseOffset); ManualTimestamper timestamper = new(now.UtcDateTime); - Dictionary stepDurations = secondsDurations.ToDictionary( - kvp => kvp.SecondsOffset == 0 ? 0 : kvp.SecondsOffset + now.ToUnixTimeSeconds(), + // Keys are ulong as required by AuRaStepCalculator; SecondsOffset==0 maps to key 0, otherwise + // key = SecondsOffset + now.ToUnixTimeSeconds() — both non-negative, cast is safe. + Dictionary stepDurations = secondsDurations.ToDictionary( + kvp => kvp.SecondsOffset == 0 ? 0UL : (ulong)(kvp.SecondsOffset + now.ToUnixTimeSeconds()), kvp => kvp.StepDuration); AuRaStepCalculator calculator = new(stepDurations, timestamper, LimboLogs.Instance); timestamper.Add(TimeSpan.FromSeconds(second)); @@ -92,6 +94,7 @@ public void step_are_calculated_correctly(IList<(long SecondsOffset, long StepDu Assert.That(calculator.TimeToNextStep, Is.EqualTo(TimeSpan.FromSeconds(expectedSecondsToNextStep))); } - private IDictionary GetStepDurationsForSingleStep(long stepDuration) => new Dictionary() { { 0, stepDuration } }; + private IDictionary GetStepDurationsForSingleStep(long stepDuration) => + new Dictionary() { { 0UL, stepDuration } }; } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs index 9ccce79f5a50..b39482e20898 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs @@ -78,7 +78,7 @@ public void For_not_empty_block_tx_filter_should_be_called() public void For_normal_processing_it_should_not_fail_with_gas_remaining_rules() { BranchProcessor processor = CreateProcessor().Processor; - int gasLimit = 10000000; + ulong gasLimit = 10000000; BlockHeader header = Build.A.BlockHeader.WithAuthor(TestItem.AddressD).WithNumber(3).TestObject; Transaction tx = Nethermind.Core.Test.Builders.Build.A.Transaction.WithData(new byte[] { 0, 1 }) .SignedAndResolved().WithChainId(105).WithGasPrice(0).WithValue(0).WithGasLimit(gasLimit + 1).TestObject; @@ -112,7 +112,7 @@ static BlockHeader Process(BranchProcessor auRaBlockProcessor, BlockHeader paren return res; } - Dictionary> contractOverrides = new() + Dictionary> contractOverrides = new() { { 2, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs index f5312dfce87b..9b3ad9cf3c36 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs @@ -35,7 +35,7 @@ public class AuRaContractGasLimitOverrideTests public async Task can_read_block_gas_limit_from_contract() { using TestGasLimitContractBlockchain chain = await TestContractBlockchain.ForTest(); - long gasLimit = chain.GasLimitCalculator.GetGasLimit(chain.BlockTree.Head.Header); + ulong gasLimit = chain.GasLimitCalculator.GetGasLimit(chain.BlockTree.Head.Header); Assert.That(gasLimit, Is.EqualTo(CorrectHeadGasLimit)); } @@ -44,7 +44,7 @@ public async Task caches_read_block_gas_limit() { using TestGasLimitContractBlockchain chain = await TestContractBlockchain.ForTest(); chain.GasLimitCalculator.GetGasLimit(chain.BlockTree.Head.Header); - long? gasLimit = chain.GasLimitOverrideCache.GasLimitCache.Get(chain.BlockTree.Head.Hash); + ulong? gasLimit = chain.GasLimitOverrideCache.GasLimitCache.Get(chain.BlockTree.Head.Hash); Assert.That(gasLimit, Is.EqualTo(CorrectHeadGasLimit)); } @@ -60,7 +60,7 @@ public async Task can_validate_gas_limit_correct() public async Task can_validate_gas_limit_incorrect() { using TestGasLimitContractBlockchain chain = await TestContractBlockchain.ForTest(); - bool isValid = ((AuRaContractGasLimitOverride)chain.GasLimitCalculator).IsGasLimitValid(chain.BlockTree.Head.Header, 100000001, out long? expectedGasLimit); + bool isValid = ((AuRaContractGasLimitOverride)chain.GasLimitCalculator).IsGasLimitValid(chain.BlockTree.Head.Header, 100000001, out ulong? expectedGasLimit); Assert.That(isValid, Is.False); Assert.That(expectedGasLimit, Is.EqualTo(CorrectHeadGasLimit)); } @@ -85,7 +85,7 @@ private AuRaContractGasLimitOverride CreateGasLimitCalculator( IReadOnlyTxProcessingEnvFactory txProcessingEnvFactory ) { - KeyValuePair blockGasLimitContractTransition = chainSpec.EngineChainSpecParametersProvider + KeyValuePair blockGasLimitContractTransition = chainSpec.EngineChainSpecParametersProvider .GetChainSpecParameters().BlockGasLimitContractTransitions .First(); BlockGasLimitContract gasLimitContract = new(AbiEncoder.Instance, blockGasLimitContractTransition.Value, @@ -111,8 +111,8 @@ protected override ChainSpec CreateChainSpec() ChainSpec chainSpec = base.CreateChainSpec(); AuRaChainSpecEngineParameters parameters = chainSpec.EngineChainSpecParametersProvider .GetChainSpecParameters(); - KeyValuePair blockGasLimitContractTransition = parameters.BlockGasLimitContractTransitions.First(); - parameters.BlockGasLimitContractTransitions = new Dictionary() { { 10, blockGasLimitContractTransition.Value } }; + KeyValuePair blockGasLimitContractTransition = parameters.BlockGasLimitContractTransitions.First(); + parameters.BlockGasLimitContractTransitions = new Dictionary() { { 10, blockGasLimitContractTransition.Value } }; return chainSpec; } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 09f6e8251e3d..c9755450d9a1 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -322,12 +322,12 @@ public override async Task AddBlock(params Transaction[] transactions) return b; } - private Transaction[] SignTransactions(IEthereumEcdsa ecdsa, PrivateKey key, UInt256 baseNonce, params Transaction[] transactions) + private Transaction[] SignTransactions(IEthereumEcdsa ecdsa, PrivateKey key, ulong baseNonce, params Transaction[] transactions) { - for (int index = 0; index < transactions.Length; index++) + for (uint index = 0; index < transactions.Length; index++) { Transaction transaction = transactions[index]; - transaction.Nonce = (UInt256)index + baseNonce; + transaction.Nonce = index + baseNonce; ecdsa.Sign(key, transaction, true); transaction.SenderAddress = key.Address; transaction.Hash = transaction.CalculateHash(); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs index 1528cc307f6b..145244429c38 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs @@ -42,7 +42,7 @@ public void SetUp() { BlockRewardContractAddress = _address10, BlockRewardContractTransition = 10, - BlockReward = new SortedDictionary() { { 0, 200 } }, + BlockReward = new SortedDictionary() { { 0, 200 } }, }; _abiEncoder = Substitute.For(); @@ -79,7 +79,7 @@ public void constructor_throws_ArgumentNullException_on_null_transactionProcesso [Test] public void constructor_throws_ArgumentException_on_BlockRewardContractTransition_higher_than_BlockRewardContractTransitions() { - _auraParameters.BlockRewardContractTransitions = new Dictionary() + _auraParameters.BlockRewardContractTransitions = new Dictionary() { {2, Address.FromNumber(2)} }; @@ -88,10 +88,10 @@ public void constructor_throws_ArgumentException_on_BlockRewardContractTransitio Assert.That(action, Throws.TypeOf()); } - [TestCase(1, 200ul)] - [TestCase(5, 200ul)] - [TestCase(9, 200ul)] - public void calculates_rewards_correctly_before_contract_transition(long blockNumber, ulong expectedReward) + [TestCase(1ul, 200ul)] + [TestCase(5ul, 200ul)] + [TestCase(9ul, 200ul)] + public void calculates_rewards_correctly_before_contract_transition(ulong blockNumber, ulong expectedReward) { _block.Header.Number = blockNumber; AuRaRewardCalculator calculator = new(_auraParameters, _abiEncoder, _transactionProcessor); @@ -108,9 +108,9 @@ public void calculates_rewards_correctly_for_genesis() Assert.That(result, Is.Empty); } - [TestCase(10, 100ul)] - [TestCase(15, 150ul)] - public void calculates_rewards_correctly_after_contract_transition(long blockNumber, ulong expectedReward) + [TestCase(10ul, 100ul)] + [TestCase(15ul, 150ul)] + public void calculates_rewards_correctly_after_contract_transition(ulong blockNumber, ulong expectedReward) { _block.Header.Number = blockNumber; BlockReward expected = new(_block.Beneficiary, expectedReward, BlockRewardType.External); @@ -131,9 +131,9 @@ public static IEnumerable SubsequentTransitionsTestCases } [TestCaseSource(nameof(SubsequentTransitionsTestCases))] - public void calculates_rewards_correctly_after_subsequent_contract_transitions(long blockNumber, ulong expectedReward, Address address) + public void calculates_rewards_correctly_after_subsequent_contract_transitions(ulong blockNumber, ulong expectedReward, Address address) { - _auraParameters.BlockRewardContractTransitions = new Dictionary() + _auraParameters.BlockRewardContractTransitions = new Dictionary() { {50, _address50}, {150, _address150} @@ -146,9 +146,9 @@ public void calculates_rewards_correctly_after_subsequent_contract_transitions(l Assert.That(result, Is.EquivalentTo(new[] { expected }).UsingPropertiesComparer()); } - [TestCase(10, 100ul)] - [TestCase(15, 150ul)] - public void calculates_rewards_correctly_for_uncles(long blockNumber, ulong expectedReward) + [TestCase(10ul, 100ul)] + [TestCase(15ul, 150ul)] + public void calculates_rewards_correctly_for_uncles(ulong blockNumber, ulong expectedReward) { _block.Header.Number = blockNumber; _block = _block.WithReplacedBody(new BlockBody(_block.Body.Transactions, new[] diff --git a/src/Nethermind/Nethermind.AuRa.Test/Reward/StaticRewardCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Reward/StaticRewardCalculatorTests.cs index 250ab9ad3212..2b9479ab6468 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Reward/StaticRewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Reward/StaticRewardCalculatorTests.cs @@ -15,34 +15,34 @@ public class StaticRewardCalculatorTests { private readonly Block _block = new(Build.A.BlockHeader.TestObject, new BlockBody()); - [TestCase(4, 200ul)] - [TestCase(5, 150ul)] - [TestCase(9, 150ul)] - [TestCase(10, 100ul)] - [TestCase(999999999, 50ul)] - public void calculates_rewards_correctly_for_thresholds(long blockNumber, ulong expectedReward) + [TestCase(4ul, 200ul)] + [TestCase(5ul, 150ul)] + [TestCase(9ul, 150ul)] + [TestCase(10ul, 100ul)] + [TestCase(999999999ul, 50ul)] + public void calculates_rewards_correctly_for_thresholds(ulong blockNumber, ulong expectedReward) { - Dictionary blockReward = new() { { 0, 200 }, { 5, 150 }, { 10, 100 }, { 11, 50 } }; + Dictionary blockReward = new() { { 0, 200 }, { 5, 150 }, { 10, 100 }, { 11, 50 } }; _block.Header.Number = blockNumber; StaticRewardCalculator calculator = new(blockReward); BlockReward[] result = calculator.CalculateRewards(_block); Assert.That(result, Is.EquivalentTo(new[] { new BlockReward(_block.Beneficiary, expectedReward) }).UsingPropertiesComparer()); } - [TestCase(0, 200ul)] - [TestCase(999999999, 200ul)] - public void calculates_rewards_correctly_for_single_value(long blockNumber, ulong expectedReward) + [TestCase(0ul, 200ul)] + [TestCase(999999999ul, 200ul)] + public void calculates_rewards_correctly_for_single_value(ulong blockNumber, ulong expectedReward) { - Dictionary blockReward = new() { { 0, 200 } }; + Dictionary blockReward = new() { { 0, 200 } }; _block.Header.Number = blockNumber; StaticRewardCalculator calculator = new(blockReward); BlockReward[] result = calculator.CalculateRewards(_block); Assert.That(result, Is.EquivalentTo(new[] { new BlockReward(_block.Beneficiary, expectedReward) }).UsingPropertiesComparer()); } - [TestCase(0, 0ul)] - [TestCase(999999999, 0ul)] - public void calculates_rewards_correctly_for_null_argument(long blockNumber, ulong expectedReward) + [TestCase(0ul, 0ul)] + [TestCase(999999999ul, 0ul)] + public void calculates_rewards_correctly_for_null_argument(ulong blockNumber, ulong expectedReward) { _block.Header.Number = blockNumber; StaticRewardCalculator calculator = new(null); @@ -50,21 +50,21 @@ public void calculates_rewards_correctly_for_null_argument(long blockNumber, ulo Assert.That(result, Is.EquivalentTo(new[] { new BlockReward(_block.Beneficiary, expectedReward) }).UsingPropertiesComparer()); } - [TestCase(9, 0ul)] - [TestCase(10, 200ul)] - public void calculates_rewards_correctly_for_not_supported_value(long blockNumber, ulong expectedReward) + [TestCase(9ul, 0ul)] + [TestCase(10ul, 200ul)] + public void calculates_rewards_correctly_for_not_supported_value(ulong blockNumber, ulong expectedReward) { - Dictionary blockReward = new() { { 10, 200 } }; + Dictionary blockReward = new() { { 10, 200 } }; _block.Header.Number = blockNumber; StaticRewardCalculator calculator = new(blockReward); BlockReward[] result = calculator.CalculateRewards(_block); Assert.That(result, Is.EquivalentTo(new[] { new BlockReward(_block.Beneficiary, expectedReward) }).UsingPropertiesComparer()); } - [TestCase(1, 0ul)] - public void calculates_rewards_correctly_for_empty_dictionary(long blockNumber, ulong expectedReward) + [TestCase(1ul, 0ul)] + public void calculates_rewards_correctly_for_empty_dictionary(ulong blockNumber, ulong expectedReward) { - Dictionary blockReward = []; + Dictionary blockReward = []; _block.Header.Number = blockNumber; StaticRewardCalculator calculator = new(blockReward); BlockReward[] result = calculator.CalculateRewards(_block); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceSealerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceSealerTests.cs index 50dbaa15c9be..e58aba5c7ba9 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceSealerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceSealerTests.cs @@ -30,18 +30,18 @@ public void transactions_are_addable_to_block_after_sealing() IStateReader stateReader = Substitute.For(); Address nodeAddress = TestItem.AddressA; - UInt256 expectedNonce = 10; + ulong expectedNonce = 10; stateReader.TryGetAccount(blockHeader, nodeAddress, out Arg.Any()) .Returns(x => { - x[2] = new AccountStruct(expectedNonce, UInt256.Zero); + x[2] = new AccountStruct(expectedNonce, 0UL); return true; }); ulong expectedTimeStamp = 100; timestamper.UnixTime.Returns(UnixTime.FromSeconds(expectedTimeStamp)); - int gasLimit = 200; + ulong gasLimit = 200; ITxSource innerTxSource = Substitute.For(); innerTxSource.GetTransactions(blockHeader, gasLimit).Returns(new[] { tx1, tx2 }); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceTests.cs index ebeb6ad23b0f..209d0a258a1e 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/GeneratedTxSourceTests.cs @@ -25,7 +25,7 @@ public void Reseal_generated_transactions() IStateReader stateReader = Substitute.For(); BlockHeader parent = Build.A.BlockHeader.TestObject; - long gasLimit = long.MaxValue; + ulong gasLimit = ulong.MaxValue; Transaction poolTx = Build.A.Transaction.WithSenderAddress(TestItem.AddressA).TestObject; GeneratedTransaction generatedTx = Build.A.GeneratedTransaction.WithSenderAddress(TestItem.AddressB).TestObject; innerSource.GetTransactions(parent, gasLimit).Returns(new[] { poolTx, generatedTx }); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs index 456515c34580..06bd337445d6 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs @@ -242,9 +242,9 @@ async Task testFactory() private static PrivateKey GetPrivateKey(int key) => new(key.ToString("X64")); - [TestCase(1, ExpectedResult = true)] - [TestCase(3, ExpectedResult = true)] - public bool allows_transactions_before_transitions(long blockNumber) + [TestCase(1UL, ExpectedResult = true)] + [TestCase(3UL, ExpectedResult = true)] + public bool allows_transactions_before_transitions(ulong blockNumber) { VersionedTransactionPermissionContract transactionPermissionContract = new(AbiEncoder.Instance, TestItem.AddressA, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs index c146a51dd8ab..6fb72ff317c9 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs @@ -148,7 +148,7 @@ public void initializes_pendingValidators_from_db() { _validatorStore = Substitute.For(); - int blockNumber = 10; + ulong blockNumber = 10; Address[] validators = TestItem.Addresses.Take(10).ToArray(); Hash256 blockHash = Keccak.Compute("Test"); PendingValidators pendingValidators = new(blockNumber, blockHash, validators); @@ -164,14 +164,14 @@ public void initializes_pendingValidators_from_db() Assert.That(validator.Validators, Is.EqualTo(validators)); } - [TestCase(1)] - [TestCase(10)] - public void loads_initial_validators_from_contract(long blockNumber) + [TestCase(1UL)] + [TestCase(10UL)] + public void loads_initial_validators_from_contract(ulong blockNumber) { Address initialValidator = TestItem.AddressA; Block block = Build.A.Block.WithParent(_parentHeader).WithNumber(blockNumber).WithBeneficiary(initialValidator).WithAura(1, []).TestObject; SetupInitialValidators(block.Header, initialValidator); - int startBlockNumber = 1; + ulong startBlockNumber = 1; ContractBasedValidator validator = new(_validatorContract, _blockTree, _receiptsStorage, _validatorStore, _validSealerStrategy, _blockFinalizationManager, _parentHeader, _logManager, startBlockNumber); bool finalizeChangeCalled = blockNumber == 1; @@ -207,7 +207,7 @@ public static IEnumerable ConsecutiveInitiateChangeData yield return new TestCaseData(new ConsecutiveInitiateChangeTestParameters { StartBlockNumber = 1, - Reorganisations = new Dictionary() + Reorganisations = new Dictionary() { { 1, new ConsecutiveInitiateChangeTestParameters.ChainInfo() @@ -266,7 +266,7 @@ public static IEnumerable ConsecutiveInitiateChangeData yield return new TestCaseData(new ConsecutiveInitiateChangeTestParameters { StartBlockNumber = 1, - Reorganisations = new Dictionary() + Reorganisations = new Dictionary() { { 1, new ConsecutiveInitiateChangeTestParameters.ChainInfo() @@ -319,7 +319,7 @@ public static IEnumerable ConsecutiveInitiateChangeData yield return new TestCaseData(new ConsecutiveInitiateChangeTestParameters { StartBlockNumber = 1, - Reorganisations = new Dictionary() + Reorganisations = new Dictionary() { { 1, new ConsecutiveInitiateChangeTestParameters.ChainInfo() @@ -369,7 +369,7 @@ public static IEnumerable ConsecutiveInitiateChangeData yield return new TestCaseData(new ConsecutiveInitiateChangeTestParameters { StartBlockNumber = 1, - Reorganisations = new Dictionary() + Reorganisations = new Dictionary() { { 1, new ConsecutiveInitiateChangeTestParameters.ChainInfo() @@ -421,7 +421,7 @@ public static IEnumerable ConsecutiveInitiateChangeData yield return new TestCaseData(new ConsecutiveInitiateChangeTestParameters { StartBlockNumber = 1, - Reorganisations = new Dictionary() + Reorganisations = new Dictionary() { { 1, new ConsecutiveInitiateChangeTestParameters.ChainInfo() @@ -481,7 +481,7 @@ public static IEnumerable ConsecutiveInitiateChangeData [TestCaseSource(nameof(ConsecutiveInitiateChangeData))] public void consecutive_initiate_change_gets_finalized_and_switch_validators(ConsecutiveInitiateChangeTestParameters test) { - Dictionary hashSeeds = []; + Dictionary hashSeeds = []; Address[] currentValidators = GenerateValidators(1); SetupInitialValidators(currentValidators); @@ -489,9 +489,9 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con IAuRaValidator validator = new ContractBasedValidator(_validatorContract, _blockTree, _receiptsStorage, _validatorStore, _validSealerStrategy, _blockFinalizationManager, _blockTree.Head.Header, _logManager, test.StartBlockNumber); test.TryDoReorganisations(test.StartBlockNumber, out _); - for (int i = 0; i < test.Current.NumberOfSteps; i++) + for (uint i = 0; i < test.Current.NumberOfSteps; i++) { - int blockNumber = test.Current.BlockNumber + i; + ulong blockNumber = test.Current.BlockNumber + i; if (test.TryDoReorganisations(blockNumber, out ConsecutiveInitiateChangeTestParameters.ChainInfo lastChain)) { @@ -506,10 +506,12 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con hashSeeds[blockNumber] = 0; _block.Header.Number = blockNumber; - _block.Header.Beneficiary = currentValidators[blockNumber % currentValidators.Length]; - _block.Header.AuRaStep = blockNumber; - _block.Header.Hash = Keccak.Compute((blockNumber + hashSeeds[blockNumber]).ToString()); - _block.Header.ParentHash = blockNumber == test.StartBlockNumber ? Keccak.Zero : Keccak.Compute((blockNumber - 1 + hashSeeds[blockNumber - 1]).ToString()); + _block.Header.Beneficiary = currentValidators[blockNumber % (ulong)currentValidators.Length]; + _block.Header.AuRaStep = (long)blockNumber; + _block.Header.Hash = Keccak.Compute((blockNumber + (ulong)hashSeeds[blockNumber]).ToString()); + _block.Header.ParentHash = blockNumber == test.StartBlockNumber + ? Keccak.Zero + : Keccak.Compute(((blockNumber - 1UL) + (ulong)hashSeeds[blockNumber - 1UL]).ToString()); TxReceipt[] txReceipts = test.GetReceipts(_validatorContract, _block, _contractAddress, _abiEncoder, SetupAbiAddresses); @@ -523,11 +525,11 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con Action preProcess = () => validator.OnBlockProcessingStart(_block); Assert.That(preProcess, Throws.Nothing, test.TestName); validator.OnBlockProcessingEnd(_block, txReceipts); - int finalizedNumber = blockNumber - validator.Validators.MinSealersForFinalization() + 1; + ulong finalizedNumber = blockNumber - (ulong)validator.Validators.MinSealersForFinalization() + 1UL; _blockFinalizationManager.GetLastLevelFinalizedBy(_block.Header.Hash).Returns(finalizedNumber); _blockFinalizationManager.BlocksFinalized += Raise.EventWith( new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(finalizedNumber) - .WithHash(Keccak.Compute((finalizedNumber + hashSeeds[finalizedNumber]).ToString())).TestObject)); + .WithHash(Keccak.Compute((finalizedNumber + (ulong)hashSeeds[finalizedNumber]).ToString())).TestObject)); currentValidators = test.GetCurrentValidators(blockNumber); Assert.That(validator.Validators, Is.EqualTo(currentValidators), $"Validator address should be recognized in block {blockNumber}"); @@ -584,14 +586,16 @@ static IEnumerable GetAllBlocks(BlockTree bt) return new object[] { new Address[] { TestItem.Addresses[addressIndex] } }; }); - _blockFinalizationManager.GetLastLevelFinalizedBy(blockTree.Head.ParentHash).Returns(lastLevelFinalized); + // lastLevelFinalized is a small non-negative int from test parameters; cast to ulong is safe. + _blockFinalizationManager.GetLastLevelFinalizedBy(blockTree.Head.ParentHash).Returns((ulong)lastLevelFinalized); validator.OnBlockProcessingStart(blockTree.FindBlock(blockTree.Head.Hash, BlockTreeLookupOptions.None)); PendingValidators pendingValidators = null; if (expectedBlockValidators.HasValue) { - Block block = GetAllBlocks(blockTree).First(b => b.Number == expectedBlockValidators.Value); + // expectedBlockValidators is a small positive int; block.Number is ulong; comparison via cast is safe. + Block block = GetAllBlocks(blockTree).First(b => b.Number == (ulong)expectedBlockValidators.Value); pendingValidators = new PendingValidators(block.Number, block.Hash, new[] { TestItem.Addresses[block.Number * 10] }); } @@ -623,7 +627,7 @@ private void SetupInitialValidators(BlockHeader header, BlockHeader parentHeader if (parentHeader is null) { - parentHeader = _parentHeader = Build.A.BlockHeader.WithNumber(header.Number - 1).TestObject; + parentHeader = _parentHeader = Build.A.BlockHeader.WithNumber(header.Number - 1UL).TestObject; _blockTree.FindHeader(header.ParentHash, BlockTreeLookupOptions.None).Returns(_parentHeader); } @@ -657,17 +661,17 @@ public class ConsecutiveInitiateChangeTestParameters { private ChainInfo _last; - public int StartBlockNumber { get; set; } + public ulong StartBlockNumber { get; set; } public ChainInfo Current { get; set; } - public IDictionary Reorganisations { get; set; } + public IDictionary Reorganisations { get; set; } public string TestName { get; set; } public override string ToString() => JsonSerializer.Serialize(this); - public bool TryDoReorganisations(int blockNumber, out ChainInfo last) + public bool TryDoReorganisations(ulong blockNumber, out ChainInfo last) { if (Reorganisations.TryGetValue(blockNumber, out ChainInfo chainInfo)) { @@ -683,7 +687,7 @@ public bool TryDoReorganisations(int blockNumber, out ChainInfo last) public TxReceipt[] GetReceipts(ValidatorContract validatorContract, Block block, Address contractAddress, IAbiEncoder encoder, Func dataFunc) { - Address[] validators = Current.Validators?.FirstOrDefault(v => v.InitializeBlock == block.Number)?.Addresses; + Address[] validators = Current.Validators?.FirstOrDefault(v => v.InitializeBlock == (int)block.Number)?.Addresses; if (validators is null) { return []; @@ -708,9 +712,10 @@ public TxReceipt[] GetReceipts(ValidatorContract validatorContract, Block block, } } - public Address[] GetCurrentValidators(int blockNumber) + public Address[] GetCurrentValidators(ulong blockNumber) { - ValidatorsInfo LastFinalizedInitChange(ChainInfo chainInfo, int maxInitializeBlockNumber = int.MaxValue) => chainInfo?.Validators?.LastOrDefault(v => v.FinalizeBlock <= blockNumber && v.InitializeBlock < maxInitializeBlockNumber); + ValidatorsInfo LastFinalizedInitChange(ChainInfo chainInfo, uint maxInitializeBlockNumber = int.MaxValue) => + chainInfo?.Validators?.LastOrDefault(v => v.FinalizeBlock <= (int)blockNumber && v.InitializeBlock < maxInitializeBlockNumber); ValidatorsInfo finalizedInitChange = LastFinalizedInitChange(Current); ValidatorsInfo previousReorgFinalizedInitChange = LastFinalizedInitChange(_last, Current.BlockNumber); @@ -729,7 +734,7 @@ public class ValidatorsInfo public class ChainInfo { - public int BlockNumber { get; set; } + public uint BlockNumber { get; set; } public int NumberOfSteps { get; set; } public int ExpectedFinalizationCount { get; set; } public IList Validators { get; set; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs index 883815218f1a..693b74eded3e 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs @@ -38,7 +38,7 @@ public void SetUp() _finalizationManager = Substitute.For(); _blockTree = Substitute.For(); _validatorStore = Substitute.For(); - _finalizationManager.LastFinalizedBlockLevel.Returns(0); + _finalizationManager.LastFinalizedBlockLevel.Returns(0UL); _factory.CreateValidatorProcessor(default, default, default) .ReturnsForAnyArgs(x => @@ -98,7 +98,7 @@ public void creates_inner_validators() MultiValidator validator = new(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); validator.SetFinalizationManager(_finalizationManager, null); - foreach (long blockNumber in _validator.Validators.Keys.Skip(1)) + foreach (ulong blockNumber in _validator.Validators.Keys.Skip(1)) { _finalizationManager.BlocksFinalized += Raise.EventWith(new FinalizeEventArgs( Build.A.BlockHeader.WithNumber(blockNumber + 1).TestObject, Build.A.BlockHeader.WithNumber(blockNumber).TestObject)); @@ -115,8 +115,8 @@ public void correctly_consecutively_calls_inner_validators(AuRaParameters.Valida // Arrange _validator = GetValidator(validatorType); IAuRaValidator validator = new MultiValidator(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); - Dictionary innerValidatorsFirstBlockCalls = GetInnerValidatorsFirstBlockCalls(_validator); - long maxCalls = innerValidatorsFirstBlockCalls.Values.Max() + 10; + Dictionary innerValidatorsFirstBlockCalls = GetInnerValidatorsFirstBlockCalls(_validator); + ulong maxCalls = innerValidatorsFirstBlockCalls.Values.Max() + 10; // Act ProcessBlocks(maxCalls, validator, blocksToFinalization); @@ -129,13 +129,14 @@ public void correctly_consecutively_calls_inner_validators(AuRaParameters.Valida callCountPerValidator[0] += blocksToFinalization; callCountPerValidator[^1] -= blocksToFinalization; - long GetFinalizedIndex(int j) + ulong GetFinalizedIndex(int j) { - long finalizedIndex = innerValidatorsFirstBlockCalls.Values.ElementAt(j); - return finalizedIndex == 1 ? finalizedIndex : finalizedIndex + blocksToFinalization; + // Safe: finalization indices are derived from block numbers, always non-negative. + ulong finalizedIndex = innerValidatorsFirstBlockCalls.Values.ElementAt(j); + return finalizedIndex == 1 ? finalizedIndex : finalizedIndex + (ulong)blocksToFinalization; } - EnsureInnerValidatorsCalled(i => (_innerValidators[GetFinalizedIndex(i)], callCountPerValidator[i])); + EnsureInnerValidatorsCalled(i => (_innerValidators[(long)GetFinalizedIndex(i)], callCountPerValidator[i])); } [Test] @@ -152,9 +153,9 @@ public void does_not_call_inner_validators_before_start_block() EnsureInnerValidatorsCalled(i => (_innerValidators.ElementAt(i).Value, 0)); } - [TestCase(16L, ExpectedResult = 11)] - [TestCase(21L, ExpectedResult = 21)] - public long initializes_validator_when_producing_block(long blockNumber) + [TestCase(16UL, ExpectedResult = 11)] + [TestCase(21UL, ExpectedResult = 21)] + public long initializes_validator_when_producing_block(ulong blockNumber) { IAuRaValidator validator = new MultiValidator(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); _block.Header.Number = blockNumber; @@ -163,37 +164,54 @@ public long initializes_validator_when_producing_block(long blockNumber) return _innerValidators.Keys.Last(); } - [TestCase(16L, AuRaParameters.ValidatorType.List, true, ExpectedResult = 11)] - [TestCase(21L, AuRaParameters.ValidatorType.List, false, ExpectedResult = 21)] - [TestCase(16L, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 15)] - [TestCase(23L, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 22)] - [TestCase(16L, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 1)] - [TestCase(21L, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 11)] - public long initializes_validator_when_on_nonconsecutive_block(long blockNumber, AuRaParameters.ValidatorType validatorType, bool finalizedLastValidatorBlockLevel) + [TestCase(16UL, AuRaParameters.ValidatorType.List, true, ExpectedResult = 11)] + [TestCase(21UL, AuRaParameters.ValidatorType.List, false, ExpectedResult = 21)] + [TestCase(16UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 15)] + [TestCase(23UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 22)] + [TestCase(16UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 1)] + [TestCase(21UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 11)] + public long initializes_validator_when_on_nonconsecutive_block(ulong blockNumber, AuRaParameters.ValidatorType validatorType, bool finalizedLastValidatorBlockLevel) { _validator = GetValidator(validatorType); IAuRaValidator validator = new MultiValidator(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); - _validator.Validators.ToList().TryGetSearchedItem(in blockNumber, static (l, pair) => l.CompareTo(pair.Key), out KeyValuePair validatorInfo); - _finalizationManager.GetFinalizationLevel(validatorInfo.Key).Returns(finalizedLastValidatorBlockLevel ? blockNumber - 2 : (long?)null); + _validator.Validators.ToList().TryGetSearchedItem, ulong>( + in blockNumber, + static (l, pair) => l.CompareTo(pair.Key), + out KeyValuePair validatorInfo); + + // GetFinalizationLevel returns long? (a block number that has been finalized). + // Safe cast to ulong?: finalization levels are always non-negative block numbers. + ulong? finalizationLevel = finalizedLastValidatorBlockLevel + ? blockNumber - 2UL + : null; + _finalizationManager.GetFinalizationLevel(validatorInfo.Key) + .Returns(finalizationLevel.HasValue ? finalizationLevel.Value : null); + _block.Header.Number = blockNumber; validator.OnBlockProcessingStart(_block); return _innerValidators.Keys.Last(); } - private void ProcessBlocks(long count, IAuRaValidator validator, int blocksToFinalization) + private void ProcessBlocks(ulong count, IAuRaValidator validator, int blocksToFinalization) { - for (int i = 1; i < count; i++) + for (ulong i = 1; i < count; i++) { _block.Header.Number = i; validator.OnBlockProcessingStart(_block); validator.OnBlockProcessingEnd(_block, []); - int finalizedBlock = i - blocksToFinalization; - if (finalizedBlock >= 1) + // Guard against underflow: only raise finalization event once i has advanced + // far enough that (i - blocksToFinalization) is a valid (>= 1) block number. + // Safe: blocksToFinalization is small (0, 1, or 2) and i starts at 1. + if (i >= (ulong)blocksToFinalization) { - _finalizationManager.BlocksFinalized += Raise.EventWith(new FinalizeEventArgs( - Build.A.BlockHeader.WithNumber(i).TestObject, - Build.A.BlockHeader.WithNumber(finalizedBlock).TestObject)); + ulong finalizedBlock = i - (ulong)blocksToFinalization; + if (finalizedBlock >= 1) + { + _finalizationManager.BlocksFinalized += Raise.EventWith(new FinalizeEventArgs( + Build.A.BlockHeader.WithNumber(i).TestObject, + Build.A.BlockHeader.WithNumber(finalizedBlock).TestObject)); + } } } } @@ -210,7 +228,7 @@ private void EnsureInnerValidatorsCalled(Func GetInnerValidatorsFirstBlockCalls( + private Dictionary GetInnerValidatorsFirstBlockCalls( AuRaParameters.Validator validator) => validator.Validators.ToDictionary(static x => x.Value, static x => Math.Max(x.Key + 1, 1)); @@ -218,7 +236,7 @@ private static AuRaParameters.Validator GetValidator(AuRaParameters.ValidatorTyp new() { ValidatorType = AuRaParameters.ValidatorType.Multi, - Validators = new SortedList() + Validators = new SortedList() { { 0, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs index 8b892285d8d0..46ad32732437 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs @@ -42,7 +42,7 @@ public void Report_malicious_sends_transaction([Values(true, false)] bool report } [Test] - public void Report_benign_sends_transaction([Values(0, 5)] long blockNumber) + public void Report_benign_sends_transaction([Values(0UL, 5UL)] ulong blockNumber) { TestContext context = new(true); Transaction transaction = Build.A.Transaction.TestObject; @@ -52,7 +52,7 @@ public void Report_benign_sends_transaction([Values(0, 5)] long blockNumber) } [Test] - public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToReport, [Values(1, 4)] long blockNumber) + public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToReport, [Values(1UL, 4UL)] ulong blockNumber) { ReportingContractBasedValidator.Cache cache = new(); byte[] proof = TestItem.KeccakA.BytesToArray(); @@ -61,7 +61,7 @@ public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToRep for (ulong i = 5; i < 20; i++) { context.ReportingValidatorContract.ReportMalicious(MaliciousMinerAddress, i, proof).Returns(transaction); - context.Validator.ReportMalicious(MaliciousMinerAddress, (long)i, proof, IReportingValidator.MaliciousCause.DuplicateStep); + context.Validator.ReportMalicious(MaliciousMinerAddress, i, proof, IReportingValidator.MaliciousCause.DuplicateStep); } context = new TestContext(false, cache); @@ -76,10 +76,10 @@ public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToRep .ShouldValidatorReport(Arg.Is(h => h.Number == blockNumber - 1), NodeAddress, MaliciousMinerAddress, Arg.Any()) .Returns(0 < validatorsToReport, Enumerable.Range(1, 15).Select(i => i < validatorsToReport).ToArray()); - context.ContractBasedValidator.BlockTree.FindHeader(Arg.Any(), BlockTreeLookupOptions.None, blockNumber: Arg.Any()) + context.ContractBasedValidator.BlockTree.FindHeader(Arg.Any(), BlockTreeLookupOptions.None, blockNumber: Arg.Any()) .Returns(Build.A.BlockHeader.WithNumber(blockNumber - 1).TestObject); - bool isPosDao = blockNumber >= context.PosdaoTransition; + bool isPosDao = blockNumber >= (ulong)context.PosdaoTransition; // resend transactions context.Validator.OnBlockProcessingEnd(block, []); @@ -94,7 +94,7 @@ public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToRep } [Test] - public void Adds_transactions_to_block([Values(0, 5, 15)] int validatorsToReport, [Values(0, 2, 10, 20)] long parentBlockNumber, [Values(false, true)] bool emitInitChangeCallable) + public void Adds_transactions_to_block([Values(0, 5, 15)] int validatorsToReport, [Values(0UL, 2UL, 10UL, 20UL)] ulong parentBlockNumber, [Values(false, true)] bool emitInitChangeCallable) { TestContext context = new(true); byte[] proof = TestItem.KeccakA.BytesToArray(); @@ -104,11 +104,11 @@ public void Adds_transactions_to_block([Values(0, 5, 15)] int validatorsToReport for (ulong i = startReportBlockNumber; i < startReportBlockNumber + (ulong)validatorsToReport; i++) { context.ReportingValidatorContract.ReportMalicious(MaliciousMinerAddress, i, proof).Returns(transaction); - context.Validator.ReportMalicious(MaliciousMinerAddress, (long)i, proof, IReportingValidator.MaliciousCause.DuplicateStep); + context.Validator.ReportMalicious(MaliciousMinerAddress, i, proof, IReportingValidator.MaliciousCause.DuplicateStep); } BlockHeader parent = Build.A.BlockHeader.WithNumber(parentBlockNumber).TestObject; - bool isPosDao = parentBlockNumber + 1 >= context.PosdaoTransition; + bool isPosDao = parentBlockNumber + 1 >= (ulong)context.PosdaoTransition; context.ContractBasedValidator.ValidatorContract .ShouldValidatorReport(parent, NodeAddress, MaliciousMinerAddress, Arg.Any()) .Returns(0 < validatorsToReport, Enumerable.Range(1, 15).Select(i => i < validatorsToReport).ToArray()); @@ -119,7 +119,13 @@ public void Adds_transactions_to_block([Values(0, 5, 15)] int validatorsToReport context.ContractBasedValidator.ValidatorContract.EmitInitiateChange().Returns(initChangeTransaction); Transaction[] transactions = context.Validator.GetTransactions(parent, 3000000).ToArray(); - int addedMaliciousTransactions = (int)Math.Min(validatorsToReport, Math.Max(0, parentBlockNumber - (long)startReportBlockNumber)); + // parentBlockNumber - startReportBlockNumber is ulong; Math.Max needs a common type. + // Both operands unified as ulong; result cast to int is safe because it is bounded + // above by validatorsToReport which is a small non-negative int. + ulong gap = parentBlockNumber >= startReportBlockNumber + ? parentBlockNumber - startReportBlockNumber + : 0UL; + int addedMaliciousTransactions = (int)Math.Min((ulong)validatorsToReport, gap); Assert.That(transactions.Length, Is.EqualTo(Math.Min(ReportingContractBasedValidator.MaxReportsPerBlock, isPosDao ? addedMaliciousTransactions : 0) + (initChangeTransactionAdded ? 1 : 0))); if (initChangeTransactionAdded) { @@ -170,7 +176,7 @@ public void Report_ignores_duplicates_in_same_block() public class TestContext { - public readonly int PosdaoTransition = 3; + public readonly ulong PosdaoTransition = 3; public ReportingContractBasedValidator Validator { get; } public ITxSender TxSender { get; } public IReportingValidatorContract ReportingValidatorContract { get; } @@ -205,7 +211,8 @@ public TestContext(bool forSealing, ReportingContractBasedValidator.Cache cache ITxPool txPool = Substitute.For(); IWorldState stateProvider = Substitute.For(); ISpecProvider specProvider = Substitute.For(); - stateProvider.GetNonce(ReportingValidatorContract.NodeAddress).Returns(UInt256.One); + // GetNonce now returns ulong; use 1UL instead of UInt256.One. + stateProvider.GetNonce(ReportingValidatorContract.NodeAddress).Returns(1UL); Validator = new ReportingContractBasedValidator( ContractBasedValidator, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs index 669ee9a0f287..88329f10938d 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs @@ -83,12 +83,12 @@ public static IEnumerable ValidatorsTests } [TestCaseSource(nameof(ValidatorsTests))] - public void validators_return_as_expected(IDb db, long? blockNumber, IEnumerable<(long FinalizingBlock, Address[] Validators)> validatorsToAdd, Address[] expectedValidators) + public void validators_return_as_expected(IDb db, ulong? blockNumber, IEnumerable<(long FinalizingBlock, Address[] Validators)> validatorsToAdd, Address[] expectedValidators) { ValidatorStore store = new(db); if (validatorsToAdd is not null) { - foreach ((long FinalizingBlock, Address[] Validators) validator in validatorsToAdd.OrderBy(static v => v.FinalizingBlock)) + foreach ((ulong FinalizingBlock, Address[] Validators) validator in validatorsToAdd.OrderBy(static v => v.FinalizingBlock)) { store.SetValidators(validator.FinalizingBlock, validator.Validators); } @@ -142,7 +142,7 @@ public void GetValidators_throws_when_validator_info_missing_from_db() private static MemDb CreateMemDbWithValidators(IEnumerable<(long FinalizingBlock, Address[] Validators)> validators = null) { - static Hash256 GetKey(in long blockNumber) => Keccak.Compute("Validators" + blockNumber); + static Hash256 GetKey(in ulong blockNumber) => Keccak.Compute("Validators" + blockNumber); validators ??= Array.Empty<(long FinalizingBlock, Address[] Validators)>(); (long FinalizingBlock, Address[] Validators)[] ordered = validators.OrderByDescending(static v => v.FinalizingBlock).ToArray(); @@ -152,15 +152,17 @@ private static MemDb CreateMemDbWithValidators(IEnumerable<(long FinalizingBlock for (int i = 0; i < ordered.Length; i++) { (long FinalizingBlock, Address[] Validators) current = ordered[i]; - (long FinalizingBlock, Address[] Validators) next = i + 1 < ordered.Length ? ordered[i + 1] : (-1, Array.Empty
()); - ValidatorInfo validatorInfo = new(current.FinalizingBlock, next.FinalizingBlock, current.Validators); + (long FinalizingBlock, Address[] Validators) next = i + 1 < ordered.Length ? ordered[i + 1] : (-1L, Array.Empty
()); + + // Safe: FinalizingBlock is a block number, always non-negative + ValidatorInfo validatorInfo = new((ulong)current.FinalizingBlock, (ulong)next.FinalizingBlock, current.Validators); if (i == 0) { - memDb.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, current.FinalizingBlock.ToBigEndianByteArrayWithoutLeadingZeros()); + memDb.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, ((ulong)current.FinalizingBlock).ToBigEndianByteArrayWithoutLeadingZeros()); } - memDb.Set(GetKey(current.FinalizingBlock), Rlp.Encode(validatorInfo).Bytes); + memDb.Set(GetKey((ulong)current.FinalizingBlock), Rlp.Encode(validatorInfo).Bytes); } return memDb; diff --git a/src/Nethermind/Nethermind.BalRecorder.Test/BalRecorderE2ETests.cs b/src/Nethermind/Nethermind.BalRecorder.Test/BalRecorderE2ETests.cs index 0c26fd3c89de..de6138b937dc 100644 --- a/src/Nethermind/Nethermind.BalRecorder.Test/BalRecorderE2ETests.cs +++ b/src/Nethermind/Nethermind.BalRecorder.Test/BalRecorderE2ETests.cs @@ -50,7 +50,7 @@ public async Task Record_Then_Replay_RoundTrip() string dir = Path.Combine(Path.GetTempPath(), $"bal-e2e-{Guid.NewGuid():N}"); try { - List<(long Number, byte[] EncodedBal)> recorded; + List<(ulong Number, byte[] EncodedBal)> recorded; await using (IContainer recorder = CreateNode(dir, recording: true, replay: false)) { BlockBuilder builder = recorder.Resolve(); @@ -62,7 +62,7 @@ public async Task Record_Then_Replay_RoundTrip() await using IContainer replayContainer = CreateNode(dir, recording: false, replay: true); IRecordedBalStore store = replayContainer.Resolve(); - foreach ((long number, byte[] expected) in recorded) + foreach ((ulong number, byte[] expected) in recorded) { ReadOnlyBlockAccessList? reread = store.Get(number); Assert.That(reread, Is.Not.Null); @@ -76,12 +76,12 @@ public async Task Record_Then_Replay_RoundTrip() } } - private static List<(long, byte[])> CaptureRecordedBals(IContainer container, int count) + private static List<(ulong, byte[])> CaptureRecordedBals(IContainer container, int count) { IBlockTree blockTree = container.Resolve(); IRecordedBalStore store = container.Resolve(); - List<(long, byte[])> result = []; - for (long i = 1; i <= count; i++) + List<(ulong, byte[])> result = []; + for (ulong i = 1; i <= (ulong)count; i++) { Block? block = blockTree.FindBlock(i); Assert.That(block, Is.Not.Null); @@ -149,7 +149,7 @@ private sealed class BlockBuilder( IPayloadPreparationService payloadPreparationService, PseudoNethermindRunner runner) { - private UInt256 _nonce; + private ulong _nonce; public async Task StartAndBuildBlocks(int count, CancellationToken token) { @@ -191,15 +191,19 @@ private async Task BuildOne(CancellationToken token) } } - private static void RekeyDictionaryToGenesis(IDictionary? dict) + private static void RekeyDictionaryToGenesis(IDictionary? dict) { if (dict is null or { Count: 0 }) return; - long total = dict.Values.Sum(); + ulong total = 0; + foreach (ulong v in dict.Values) + { + total += v; + } dict.Clear(); dict[0] = total; } - private static void RekeyBlockRewardToGenesis(SortedDictionary? dict) + private static void RekeyBlockRewardToGenesis(SortedDictionary? dict) { if (dict is null or { Count: 0 }) return; UInt256 lastReward = dict.Values.Last(); diff --git a/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs b/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs index 3664dceedcc1..bd39cc22f36e 100644 --- a/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs +++ b/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs @@ -14,7 +14,7 @@ public class EraFlatStoreTests private static string TempDir([System.Runtime.CompilerServices.CallerMemberName] string name = "") => Path.Combine(TestContext.CurrentContext.TestDirectory, $"eraflatstore_test_{name}_{System.Threading.Thread.CurrentThread.ManagedThreadId}"); - private static byte[]? TryReadBytes(SlotStore store, long blockNumber) + private static byte[]? TryReadBytes(SlotStore store, ulong blockNumber) { byte[]? result = null; store.TryRead(blockNumber, (data, _) => result = data.ToArray(), 0); @@ -135,12 +135,12 @@ public void ConcurrentWrites_SameEra_DoNotCorrupt() Parallel.For(0, 64, i => { byte[] data = [(byte)i]; - store.Write(i, data); + store.Write((ulong)i, data); }); for (int i = 0; i < 64; i++) { - Assert.That(TryReadBytes(store, i), Is.EqualTo(new[] { (byte)i }), $"slot {i} should be intact"); + Assert.That(TryReadBytes(store, (ulong)i), Is.EqualTo(new[] { (byte)i }), $"slot {i} should be intact"); } } finally { Directory.Delete(dir, true); } diff --git a/src/Nethermind/Nethermind.BalRecorder.Test/FakeRecordedBalStore.cs b/src/Nethermind/Nethermind.BalRecorder.Test/FakeRecordedBalStore.cs index d7f1192ebf2b..7174521801b8 100644 --- a/src/Nethermind/Nethermind.BalRecorder.Test/FakeRecordedBalStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder.Test/FakeRecordedBalStore.cs @@ -10,14 +10,14 @@ namespace Nethermind.BalRecorder.Test; /// In-memory for decorator tests. internal sealed class FakeRecordedBalStore : IRecordedBalStore { - private readonly Dictionary _seeded = []; + private readonly Dictionary _seeded = []; public bool ReplayEnabled { get; init; } public bool RecordingEnabled { get; init; } - public List<(long Number, GeneratedBlockAccessList Bal)> Inserted { get; } = []; + public List<(ulong Number, GeneratedBlockAccessList Bal)> Inserted { get; } = []; - public void Seed(long number, ReadOnlyBlockAccessList bal) => _seeded[number] = bal; + public void Seed(ulong number, ReadOnlyBlockAccessList bal) => _seeded[number] = bal; public void Insert(Block block, GeneratedBlockAccessList bal) => Inserted.Add((block.Number, bal)); - public ReadOnlyBlockAccessList? Get(long blockNumber) => _seeded.GetValueOrDefault(blockNumber); + public ReadOnlyBlockAccessList? Get(ulong blockNumber) => _seeded.GetValueOrDefault(blockNumber); public void Dispose() { } } diff --git a/src/Nethermind/Nethermind.BalRecorder.Test/RecordedBalStoreTests.cs b/src/Nethermind/Nethermind.BalRecorder.Test/RecordedBalStoreTests.cs index 11dbb5ce2b60..b40834b7b620 100644 --- a/src/Nethermind/Nethermind.BalRecorder.Test/RecordedBalStoreTests.cs +++ b/src/Nethermind/Nethermind.BalRecorder.Test/RecordedBalStoreTests.cs @@ -104,8 +104,8 @@ public void BlocksInDifferentEras_UsesSeparateFiles() try { using RecordedBalStore store = new(new BalRecorderConfig { ReplayEnabled = true, RecordingEnabled = true, Path = dir }, new InitConfig(), LimboLogs.Instance); - long era0Block = 0; - long era1Block = 8192; + ulong era0Block = 0; + ulong era1Block = 8192; Block block0 = Build.A.Block.WithNumber(era0Block).TestObject; Block block1 = Build.A.Block.WithNumber(era1Block).TestObject; diff --git a/src/Nethermind/Nethermind.BalRecorder/BalRecorderSpecProvider.cs b/src/Nethermind/Nethermind.BalRecorder/BalRecorderSpecProvider.cs index 83422980a0df..b1a02a43a9a5 100644 --- a/src/Nethermind/Nethermind.BalRecorder/BalRecorderSpecProvider.cs +++ b/src/Nethermind/Nethermind.BalRecorder/BalRecorderSpecProvider.cs @@ -14,7 +14,7 @@ public class BalRecorderSpecProvider(ISpecProvider inner, BalRecorderSpecSwitch // repeated GetSpec / GenesisSpec calls don't allocate a new decorator each time. private readonly ConcurrentDictionary _wrapped = new(ReferenceEqualityComparer.Instance); - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) => + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => inner.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public ForkActivation? MergeBlockNumber => inner.MergeBlockNumber; @@ -22,7 +22,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public UInt256? TerminalTotalDifficulty => inner.TerminalTotalDifficulty; public IReleaseSpec GenesisSpec => Wrap(inner.GenesisSpec); public bool GenesisStateUnavailable => inner.GenesisStateUnavailable; - public long? DaoBlockNumber => inner.DaoBlockNumber; + public ulong? DaoBlockNumber => inner.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => inner.BeaconChainGenesisTimestamp; public ulong NetworkId => inner.NetworkId; public ulong ChainId => inner.ChainId; diff --git a/src/Nethermind/Nethermind.BalRecorder/IRecordedBalStore.cs b/src/Nethermind/Nethermind.BalRecorder/IRecordedBalStore.cs index 29b35ef75cc7..fcdd83b4f1dc 100644 --- a/src/Nethermind/Nethermind.BalRecorder/IRecordedBalStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder/IRecordedBalStore.cs @@ -10,7 +10,7 @@ namespace Nethermind.BalRecorder; public interface IRecordedBalStore : IDisposable { void Insert(Block block, GeneratedBlockAccessList bal); - ReadOnlyBlockAccessList? Get(long blockNumber); + ReadOnlyBlockAccessList? Get(ulong blockNumber); bool ReplayEnabled { get; } bool RecordingEnabled { get; } } diff --git a/src/Nethermind/Nethermind.BalRecorder/RecordedBalStore.cs b/src/Nethermind/Nethermind.BalRecorder/RecordedBalStore.cs index 4ed708069e5e..d38c63f6ed9b 100644 --- a/src/Nethermind/Nethermind.BalRecorder/RecordedBalStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder/RecordedBalStore.cs @@ -29,7 +29,7 @@ public void Insert(Block block, GeneratedBlockAccessList bal) if (_logger.IsDebug) _logger.Debug($"BAL slot for block {block.Number} already filled; skipping."); } - public ReadOnlyBlockAccessList? Get(long blockNumber) + public ReadOnlyBlockAccessList? Get(ulong blockNumber) { ReadState state = new() { Logger = _logger, BlockNumber = blockNumber }; _store.TryRead(blockNumber, static (data, s) => @@ -44,6 +44,6 @@ private sealed class ReadState { public ReadOnlyBlockAccessList? Value; public ILogger Logger; - public long BlockNumber; + public ulong BlockNumber; } } diff --git a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs index 618a59a7738d..d10928f15ada 100644 --- a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs @@ -15,14 +15,14 @@ namespace Nethermind.BalRecorder; public class SlotStore(string directory, string extension = "bin") : IDisposable { private SlotFile? _file; - private long _fileEra = -1; + private ulong _fileEra = ulong.MinValue; private readonly Lock _lock = new(); - private string FilePath(long era) => Path.Combine(directory, $"{era:D8}.{extension}"); + private string FilePath(ulong era) => Path.Combine(directory, $"{era:D8}.{extension}"); - public bool TryRead(long blockNumber, ReadOnlySpanAction action, TArg arg) + public bool TryRead(ulong blockNumber, ReadOnlySpanAction action, TArg arg) { - long era = blockNumber / SlotFile.SlotsPerFile; + ulong era = blockNumber / SlotFile.SlotsPerFile; int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { @@ -38,9 +38,9 @@ public bool TryRead(long blockNumber, ReadOnlySpanAction actio } } - public bool Write(long blockNumber, ReadOnlySpan data) + public bool Write(ulong blockNumber, ReadOnlySpan data) { - long era = blockNumber / SlotFile.SlotsPerFile; + ulong era = blockNumber / SlotFile.SlotsPerFile; int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { @@ -61,7 +61,7 @@ public void Dispose() { _file?.Dispose(); _file = null; - _fileEra = -1; + _fileEra = ulong.MinValue; } } } diff --git a/src/Nethermind/Nethermind.Benchmark/Evm/MemoryCostBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Evm/MemoryCostBenchmark.cs index 26af071b1650..c2e93978853f 100644 --- a/src/Nethermind/Nethermind.Benchmark/Evm/MemoryCostBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Evm/MemoryCostBenchmark.cs @@ -32,7 +32,7 @@ public void Setup() } [Benchmark] - public long Current() + public ulong Current() { UInt256 dest = _location; return _current.CalculateMemoryCost(in dest, _length, out _); diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs index ffb41fc62da8..f803ed2ff890 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs @@ -21,7 +21,7 @@ public RlpDecodeBlockBenchmark() Transaction[] transactions = new Transaction[100]; for (int i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((UInt256)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs index 7f85732865b8..289878c21e8b 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs @@ -26,7 +26,7 @@ public RlpEncodeBlockBenchmark() Transaction[] transactions = new Transaction[100]; for (int i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((UInt256)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs index d4e30f39dee5..08f7acdc08e8 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs @@ -25,7 +25,7 @@ public RlpEncodeHeaderBenchmark() Transaction[] transactions = new Transaction[100]; for (int i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((UInt256)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/Scheduler/BackgroundTaskSchedulerBenchmarks.cs b/src/Nethermind/Nethermind.Benchmark/Scheduler/BackgroundTaskSchedulerBenchmarks.cs index 5ab4d42ecf03..c373c3cdbd82 100644 --- a/src/Nethermind/Nethermind.Benchmark/Scheduler/BackgroundTaskSchedulerBenchmarks.cs +++ b/src/Nethermind/Nethermind.Benchmark/Scheduler/BackgroundTaskSchedulerBenchmarks.cs @@ -167,8 +167,8 @@ private sealed class StubChainHeadInfoProvider : IChainHeadInfoProvider { public IChainHeadSpecProvider SpecProvider => null!; public IReadOnlyStateProvider ReadOnlyStateProvider => null!; - public long HeadNumber => 0; - public long? BlockGasLimit => null; + public ulong HeadNumber => 0; + public ulong? BlockGasLimit => null; public UInt256 CurrentBaseFee => UInt256.Zero; public UInt256 CurrentFeePerBlobGas => UInt256.Zero; public ProofVersion CurrentProofVersion => ProofVersion.V0; diff --git a/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs index 98f615509c19..96d09769f0bd 100644 --- a/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs @@ -138,7 +138,7 @@ public void Setup() }); } - scope.Commit(blockNumber: block + 1); + scope.Commit(blockNumber: (ulong)(block + 1)); FlatSnapshot snapshot = commitTarget.LastSnapshot ?? throw new InvalidOperationException( @@ -146,7 +146,7 @@ public void Setup() snapshot.TryAcquire(); allSnapshots.Add(snapshot); - currentStateId = new StateId(block + 1, scope.RootHash); + currentStateId = new StateId((ulong)(block + 1), scope.RootHash); storageRanges.Add((totalAccountCount + 1, storageAccountCount, slotsPerStorageAccount)); totalAccountCount += accountCount; totalStorageAccountCount += storageAccountCount; diff --git a/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs index 8abbc86b8200..3bfc2330777c 100644 --- a/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs @@ -116,7 +116,7 @@ public void GlobalSetup() }); } - scope.Commit(blockNumber: block + 1); + scope.Commit(blockNumber: (ulong)(block + 1)); FlatSnapshot snapshot = commitTarget.LastSnapshot ?? throw new InvalidOperationException( @@ -124,7 +124,7 @@ public void GlobalSetup() snapshot.TryAcquire(); _baseSnapshots.Add(snapshot); - _currentStateId = new StateId(block + 1, scope.RootHash); + _currentStateId = new StateId((ulong)(block + 1), scope.RootHash); totalAccountCount += accountCount; } diff --git a/src/Nethermind/Nethermind.Benchmark/Store/BloomStorageBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Store/BloomStorageBenchmark.cs index 2cf7ff5fe216..7310854a756b 100644 --- a/src/Nethermind/Nethermind.Benchmark/Store/BloomStorageBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Store/BloomStorageBenchmark.cs @@ -36,16 +36,16 @@ private static int Benchmark(IFileStoreFactory fileStorageFactory, string basePa { Bloom bloom = new(); bloom.Set(i % Bloom.BitLength); - storage.Store(i, bloom); + storage.Store((ulong)i, bloom); }); - IBloomEnumeration blooms = storage.GetBlooms(0, maxBlock); + IBloomEnumeration blooms = storage.GetBlooms(0, (ulong)maxBlock); int i = 0; foreach (Bloom _ in blooms) { i++; - blooms.TryGetBlockNumber(out long _); + blooms.TryGetBlockNumber(out ulong _); } return i; diff --git a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs index e9705b0c0455..cf04457e29e6 100644 --- a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs +++ b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs @@ -355,7 +355,7 @@ public void InsertAndCommitRepeatedlyTimes() { if (i % _repeatedlyFactor == 0) { - using IBlockCommitter _ = trieStore.BeginBlockCommit(i / _repeatedlyFactor); + using IBlockCommitter _ = trieStore.BeginBlockCommit((ulong)(i / _repeatedlyFactor)); tempTree.Commit(); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BeaconBlockRootHandlerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BeaconBlockRootHandlerTests.cs index abbd0cb530af..791c8b007beb 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BeaconBlockRootHandlerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BeaconBlockRootHandlerTests.cs @@ -140,11 +140,11 @@ public void Test_StoreBeaconRoot_AccessListNotNull() Transaction transaction = new() { - Value = UInt256.Zero, + Value = 0ul, Data = header.ParentBeaconBlockRoot!.Bytes.ToArray(), To = Eip4788Constants.BeaconRootsAddress, SenderAddress = Address.SystemUser, - GasLimit = 30_000_000L, + GasLimit = 30_000_000ul, GasPrice = UInt256.Zero, AccessList = new AccessList.Builder().AddAddress(Eip4788Constants.BeaconRootsAddress).Build() }; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockAccessLists/BlockAccessListStoreTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockAccessLists/BlockAccessListStoreTests.cs index 238a95ea33c6..16e41965b70e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockAccessLists/BlockAccessListStoreTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockAccessLists/BlockAccessListStoreTests.cs @@ -22,7 +22,7 @@ public void Round_trips_byte_array_payload() TestMemDb db = new(); BlockAccessListStore store = new(db); - const long blockNumber = 42; + const ulong blockNumber = 42; Hash256 blockHash = TestItem.KeccakA; byte[] encoded = [0xc1, 0x80]; @@ -39,7 +39,7 @@ public void Round_trips_decoded_block_access_list() TestMemDb db = new(); BlockAccessListStore store = new(db); - const long blockNumber = 1_000_000; + const ulong blockNumber = 1_000_000; Hash256 blockHash = TestItem.KeccakB; ReadOnlyBlockAccessList bal = new(); @@ -58,7 +58,7 @@ public void Delete_removes_entry() TestMemDb db = new(); BlockAccessListStore store = new(db); - const long blockNumber = 5; + const ulong blockNumber = 5; Hash256 blockHash = TestItem.KeccakC; byte[] encoded = [0xc1, 0x80]; store.Insert(blockNumber, blockHash, encoded); @@ -100,7 +100,7 @@ public void Stores_under_block_number_prefixed_key() TestMemDb db = new(); BlockAccessListStore store = new(db); - const long blockNumber = 7; + const ulong blockNumber = 7; Hash256 blockHash = TestItem.KeccakA; byte[] encoded = [0xc1, 0x80]; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockFinderExtensionsTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockFinderExtensionsTests.cs index 55bc8cd012bf..836d33b1f90b 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockFinderExtensionsTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockFinderExtensionsTests.cs @@ -43,7 +43,7 @@ public void BlockParameter_ToString_ReturnsLowercaseTypeName(BlockParameterType [Test, MaxTime(Timeout.MaxTestTime)] public void BlockParameter_ToString_ReturnsBlockNumber() => - Assert.That(new BlockParameter(12345L).ToString(), Is.EqualTo("12345")); + Assert.That(new BlockParameter(12345ul).ToString(), Is.EqualTo("12345")); [Test, MaxTime(Timeout.MaxTestTime)] public void BlockParameter_ToString_ReturnsBlockHash() @@ -59,12 +59,12 @@ public void SearchForBlock_WhenBlockIsPruned_IncludesBlockNumberInError() BlockHeader head = Build.A.BlockHeader.WithNumber(1000).TestObject; Block headBlock = Build.A.Block.WithHeader(head).TestObject; blockFinder.Head.Returns(headBlock); - blockFinder.GetLowestBlock().Returns(100); + blockFinder.GetLowestBlock().Returns(100ul); // Mock the underlying method that will be called - blockFinder.FindBlock(50, BlockTreeLookupOptions.None).Returns((Block?)null); + blockFinder.FindBlock(50ul, BlockTreeLookupOptions.None).Returns((Block?)null); - BlockParameter blockParameter = new(50); + BlockParameter blockParameter = new(50ul); SearchResult result = blockFinder.SearchForBlock(blockParameter); Assert.That(result.IsError, Is.True); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs index 079e6b0535ba..42b98f311470 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs @@ -70,7 +70,7 @@ public void ApplyStateChanges_uses_parent_state_without_prestate_sentinels() using (Assert.EnterMultipleScope()) { Assert.That(stateProvider.GetBalance(TestItem.AddressA), Is.EqualTo((UInt256)150)); - Assert.That(stateProvider.GetNonce(TestItem.AddressA), Is.EqualTo((UInt256)3)); + Assert.That(stateProvider.GetNonce(TestItem.AddressA), Is.EqualTo(3ul)); Assert.That(new UInt256(stateProvider.Get(storageCell), isBigEndian: true), Is.EqualTo((UInt256)0x2Au)); } }); @@ -503,9 +503,9 @@ public static IEnumerable BlockValidationTransactionsExecutor_bal_ .SetName("BlockValidationTransactionsExecutor_skips_bal_validation_when_no_validation_requested"); } - [TestCase(2000, false, TestName = "BAL_read_budget_at_2000_gas_passes")] - [TestCase(1999, true, TestName = "BAL_read_budget_at_1999_gas_fails")] - public void ValidateBlockAccessList_storage_read_budget_uses_ItemCost(long gasRemaining, bool shouldThrow) + [TestCase(2000ul, false, TestName = "BAL_read_budget_at_2000_gas_passes")] + [TestCase(1999ul, true, TestName = "BAL_read_budget_at_1999_gas_fails")] + public void ValidateBlockAccessList_storage_read_budget_uses_ItemCost(ulong gasRemaining, bool shouldThrow) { // One extra storage read in suggested BAL costs Eip7928Constants.ItemCost (2000) gas IWorldState stateProvider = TestWorldStateFactory.CreateForTest(); @@ -526,7 +526,7 @@ public void ValidateBlockAccessList_storage_read_budget_uses_ItemCost(long gasRe .TestObject; Block block = Build.A.Block - .WithNumber(1) + .WithNumber(1ul) .WithGasUsed(gasRemaining) .WithBlockAccessList(suggestedBal) .TestObject; @@ -1000,7 +1000,7 @@ public void Parallel_validation_uses_canonical_receipt_and_bal_indexes_with_sche Block block = Build.A.Block .WithNumber(1) - .WithGasLimit(txCount * 1_000_000L) + .WithGasLimit((ulong)txCount * 1_000_000ul) .WithTransactions(transactions) .WithBlockAccessList(new ReadOnlyBlockAccessList()) .TestObject; @@ -1094,7 +1094,7 @@ private static GasValidationResultSlot[] ResultsForCount(int count) } private static GasValidationResult - GasResult(Block block, int txIndex, long blockGasUsed, long blockStateGasUsed, InvalidBlockException? exception = null) + GasResult(Block block, int txIndex, ulong blockGasUsed, ulong blockStateGasUsed, InvalidBlockException? exception = null) { IntrinsicGas intrinsicGas = EthereumGasPolicy.CalculateIntrinsicGas(block.Transactions[txIndex], Amsterdam.Instance, block.Header.GasLimit); return new(blockGasUsed, blockStateGasUsed, intrinsicGas, exception); @@ -1107,7 +1107,7 @@ private static void PrepareSetup(BlockAccessListManager balManager, Block block, balManager.Setup(block); } - private static GasValidationResultSlot[] BuildGasResults(Block block, params (long Gas, long StateGas, InvalidBlockException? Exception)[] rows) + private static GasValidationResultSlot[] BuildGasResults(Block block, params (ulong Gas, ulong StateGas, InvalidBlockException? Exception)[] rows) { GasValidationResultSlot[] slots = ResultsForCount(rows.Length); for (int i = 0; i < rows.Length; i++) @@ -1120,11 +1120,11 @@ private static GasValidationResultSlot[] BuildGasResults(Block block, params (lo private static Transaction[] CreateParallelValidationTransactions(int txCount) { Transaction[] transactions = new Transaction[txCount]; - for (int i = 0; i < transactions.Length; i++) + for (uint i = 0; i < transactions.Length; i++) { transactions[i] = Build.A.Transaction - .WithNonce((UInt256)i) - .WithGasLimit(21_000) + .WithNonce(i) + .WithGasLimit(21_000ul) .TestObject; } @@ -1132,8 +1132,8 @@ private static Transaction[] CreateParallelValidationTransactions(int txCount) } private static Transaction CreateTxForExecutionOrder( - int nonce, - long gasLimit, + uint nonce, + ulong gasLimit, int dataLength = 0, int authorizationCount = 0, int accessListStorageKeys = 0, @@ -1141,7 +1141,7 @@ private static Transaction CreateTxForExecutionOrder( { byte[] data = dataLength == 0 ? [] : new byte[dataLength]; TransactionBuilder builder = Build.A.Transaction - .WithNonce((UInt256)nonce) + .WithNonce(nonce) .WithGasLimit(gasLimit); if (contractCreation) @@ -1277,7 +1277,7 @@ public void Setup(Block block) { } - public void SpendGas(long gas) + public void SpendGas(ulong gas) { } @@ -1342,7 +1342,7 @@ public TransactionResult Execute(Transaction transaction, ITxTracer txTracer) int txIndex = (int)transaction.Nonce; balIndexes.Add((txIndex, balIndex)); - long gasUsed = 21_000 + txIndex; + ulong gasUsed = 21_000ul + (ulong)txIndex; transaction.BlockGasUsed = gasUsed; txTracer.MarkAsSuccess(Address.Zero, gasUsed, [], []); @@ -1434,7 +1434,7 @@ private sealed class RecordingInstructionTxTracer(RecordingParallelSafeBlockTrac { public override bool IsTracingInstructions => true; - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) => + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => blockTracer.RecordOpcode(); } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs index 704fc22718c4..ece08920bbf9 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs @@ -1249,9 +1249,9 @@ public void When_deleting_invalid_block_does_not_delete_blocks_that_are_not_its_ } [Test, MaxTime(Timeout.MaxTestTime), TestCaseSource(nameof(SourceOfBSearchTestCases))] - public void When_lowestInsertedHeaderWasNotPersisted_useBinarySearchToLoadLowestInsertedHeader(long beginIndex, long insertedBlocks) + public void When_lowestInsertedHeaderWasNotPersisted_useBinarySearchToLoadLowestInsertedHeader(ulong beginIndex, ulong insertedBlocks) { - long? expectedResult = insertedBlocks == 0L ? null : beginIndex - insertedBlocks + 1L; + ulong? expectedResult = insertedBlocks == 0ul ? null : beginIndex - insertedBlocks + 1ul; SyncConfig syncConfig = new() { @@ -1266,9 +1266,9 @@ public void When_lowestInsertedHeaderWasNotPersisted_useBinarySearchToLoadLowest BlockTree tree = builder.TestObject; tree.SuggestBlock(Build.A.Block.Genesis.TestObject); - for (long i = beginIndex; i > beginIndex - insertedBlocks; i--) + for (ulong i = beginIndex; i > beginIndex - insertedBlocks; i--) { - tree.Insert(Build.A.BlockHeader.WithNumber(i).WithTotalDifficulty(i).TestObject); + tree.Insert(Build.A.BlockHeader.WithNumber(i).WithTotalDifficulty((long)i).TestObject); } builder.MetadataDb.Delete(MetadataDbKeys.LowestInsertedFastHeaderHash); @@ -1297,9 +1297,9 @@ public void When_lowestInsertedHeaderWasPersisted_doNot_useBinarySearchToLoadLow tree.SuggestBlock(Build.A.Block.Genesis.TestObject); tree.RecalculateTreeLevels(); - for (int i = 1; i < 100; i++) + for (ulong i = 1ul; i < 100ul; i++) { - tree.Insert(Build.A.BlockHeader.WithNumber(i).WithParent(tree.FindHeader(i - 1, BlockTreeLookupOptions.None)!).TestObject); + tree.Insert(Build.A.BlockHeader.WithNumber(i).WithParent(tree.FindHeader(i - 1ul, BlockTreeLookupOptions.None)!).TestObject); } BlockTree loadedTree = Build.A.BlockTree() @@ -1320,10 +1320,10 @@ public void When_lowestInsertedHeaderWasPersisted_doNot_useBinarySearchToLoadLow Assert.That(loadedTree.LowestInsertedHeader?.Number, Is.EqualTo(50)); } - [TestCase(5, 10)] - [TestCase(10, 10)] - [TestCase(12, 0)] - public void Does_not_load_bestKnownNumber_before_syncPivot(long syncPivot, long expectedBestKnownNumber) + [TestCase(5ul, 10ul)] + [TestCase(10ul, 10ul)] + [TestCase(12ul, 0ul)] + public void Does_not_load_bestKnownNumber_before_syncPivot(ulong syncPivot, ulong expectedBestKnownNumber) { SyncConfig syncConfig = new() { @@ -1354,34 +1354,34 @@ public void Does_not_load_bestKnownNumber_before_syncPivot(long syncPivot, long private static readonly object[] SourceOfBSearchTestCases = { - new object[] {1L, 0L}, - new object[] {1L, 1L}, - new object[] {2L, 0L}, - new object[] {2L, 1L}, - new object[] {2L, 2L}, - new object[] {3L, 0L}, - new object[] {3L, 1L}, - new object[] {3L, 2L}, - new object[] {3L, 3L}, - new object[] {4L, 0L}, - new object[] {4L, 1L}, - new object[] {4L, 2L}, - new object[] {4L, 3L}, - new object[] {4L, 4L}, - new object[] {5L, 0L}, - new object[] {5L, 1L}, - new object[] {5L, 2L}, - new object[] {5L, 3L}, - new object[] {5L, 4L}, - new object[] {5L, 5L}, - new object[] {728000, 0L}, - new object[] {7280000L, 1L} + new object[] {1ul, 0ul}, + new object[] {1ul, 1ul}, + new object[] {2ul, 0ul}, + new object[] {2ul, 1ul}, + new object[] {2ul, 2ul}, + new object[] {3ul, 0ul}, + new object[] {3ul, 1ul}, + new object[] {3ul, 2ul}, + new object[] {3ul, 3ul}, + new object[] {4ul, 0ul}, + new object[] {4ul, 1ul}, + new object[] {4ul, 2ul}, + new object[] {4ul, 3ul}, + new object[] {4ul, 4ul}, + new object[] {5ul, 0ul}, + new object[] {5ul, 1ul}, + new object[] {5ul, 2ul}, + new object[] {5ul, 3ul}, + new object[] {5ul, 4ul}, + new object[] {5ul, 5ul}, + new object[] {728000ul, 0ul}, + new object[] {7280000ul, 1ul} }; [Test, MaxTime(Timeout.MaxTestTime), TestCaseSource(nameof(SourceOfBSearchTestCases))] - public void Loads_best_known_correctly_on_inserts(long beginIndex, long insertedBlocks) + public void Loads_best_known_correctly_on_inserts(ulong beginIndex, ulong insertedBlocks) { - long expectedResult = insertedBlocks == 0L ? 0L : beginIndex; + ulong expectedResult = insertedBlocks == 0ul ? 0ul : beginIndex; SyncConfig syncConfig = new() { @@ -1397,7 +1397,7 @@ public void Loads_best_known_correctly_on_inserts(long beginIndex, long inserted tree.SuggestBlock(Build.A.Block.Genesis.TestObject); - for (long i = beginIndex; i > beginIndex - insertedBlocks; i--) + for (ulong i = beginIndex; i > beginIndex - insertedBlocks; i--) { Block block = Build.A.Block.WithNumber(i).WithTotalDifficulty(i).TestObject; tree.Insert(block.Header); @@ -1438,7 +1438,7 @@ public void Loads_best_head_up_to_best_persisted_state() List blocks = [genesis]; - for (long i = 1; i < 100; i++) + for (ulong i = 1ul; i < 100ul; i++) { Block block = Build.A.Block .WithNumber(i) @@ -1446,7 +1446,7 @@ public void Loads_best_head_up_to_best_persisted_state() .WithTotalDifficulty(i).TestObject; blocks.Add(block); parent = block; - if (i <= 50) + if (i <= 50ul) { // tree.Insert(block.Header); tree.SuggestBlock(block); @@ -1457,7 +1457,7 @@ public void Loads_best_head_up_to_best_persisted_state() } } tree.UpdateMainChain(blocks.ToArray(), true); - tree.BestPersistedState = 50; + tree.BestPersistedState = 50ul; BlockTree loadedTree = Build.A.BlockTree() .WithoutSettingHead @@ -1465,14 +1465,14 @@ public void Loads_best_head_up_to_best_persisted_state() .WithSyncConfig(syncConfig) .TestObject; - Assert.That(loadedTree.Head?.Number, Is.EqualTo(50)); + Assert.That(loadedTree.Head?.Number, Is.EqualTo(50ul)); } [MaxTime(Timeout.MaxTestTime)] - [TestCase(1L)] - [TestCase(2L)] - [TestCase(3L)] - public void Loads_best_known_correctly_on_inserts_followed_by_suggests(long pivotNumber) + [TestCase(1ul)] + [TestCase(2ul)] + [TestCase(3ul)] + public void Loads_best_known_correctly_on_inserts_followed_by_suggests(ulong pivotNumber) { SyncConfig syncConfig = new() { @@ -1486,14 +1486,14 @@ public void Loads_best_known_correctly_on_inserts_followed_by_suggests(long pivo tree.SuggestBlock(Build.A.Block.Genesis.TestObject); Block? pivotBlock = null; - for (long i = pivotNumber; i > 0; i--) + for (ulong i = pivotNumber; i > 0; i--) { Block block = Build.A.Block.WithNumber(i).WithTotalDifficulty(i).TestObject; pivotBlock ??= block; tree.Insert(block.Header); } - tree.SuggestHeader(Build.A.BlockHeader.WithNumber(pivotNumber + 1).WithParent(pivotBlock!.Header).TestObject); + tree.SuggestHeader(Build.A.BlockHeader.WithNumber(pivotNumber + 1ul).WithParent(pivotBlock!.Header).TestObject); BlockTree loadedTree = Build.A.BlockTree() .WithoutSettingHead @@ -1501,21 +1501,21 @@ public void Loads_best_known_correctly_on_inserts_followed_by_suggests(long pivo .WithSyncConfig(syncConfig) .TestObject; - Assert.That(tree.BestKnownNumber, Is.EqualTo(pivotNumber + 1), "tree"); - Assert.That(loadedTree.BestKnownNumber, Is.EqualTo(pivotNumber + 1), "loaded tree"); + Assert.That(tree.BestKnownNumber, Is.EqualTo(pivotNumber + 1ul), "tree"); + Assert.That(loadedTree.BestKnownNumber, Is.EqualTo(pivotNumber + 1ul), "loaded tree"); } [Test, MaxTime(Timeout.MaxTestTime)] public void Loads_best_known_correctly_when_head_before_pivot() { - int pivotNumber = 1000; - int head = 10; + ulong pivotNumber = 1000ul; + ulong head = 10ul; SyncConfig syncConfig = new() { PivotNumber = pivotNumber }; - BlockTreeBuilder treeBuilder = Build.A.BlockTree().OfChainLength(head + 1); + BlockTreeBuilder treeBuilder = Build.A.BlockTree().OfChainLength((int)head + 1); BlockTree loadedTree = Build.A.BlockTree() .WithoutSettingHead @@ -1529,7 +1529,7 @@ public void Loads_best_known_correctly_when_head_before_pivot() [Test, MaxTime(Timeout.MaxTestTime)] public void Cannot_insert_genesis() { - long pivotNumber = 0L; + ulong pivotNumber = 0ul; SyncConfig syncConfig = new() { @@ -1550,7 +1550,7 @@ public void Cannot_insert_genesis() [Test, MaxTime(Timeout.MaxTestTime)] public void Should_set_zero_total_difficulty() { - long pivotNumber = 0L; + ulong pivotNumber = 0ul; SyncConfig syncConfig = new() { @@ -1578,7 +1578,7 @@ public void Should_set_zero_total_difficulty() [Test, MaxTime(Timeout.MaxTestTime)] public void Inserts_blooms() { - long pivotNumber = 5L; + ulong pivotNumber = 5ul; SyncConfig syncConfig = new() { @@ -1596,9 +1596,9 @@ public void Inserts_blooms() tree.SuggestBlock(Build.A.Block.Genesis.TestObject); - for (long i = 5; i > 0; i--) + for (ulong i = 5ul; i > 0; i--) { - Block block = Build.A.Block.WithNumber(i).WithTotalDifficulty(1L).TestObject; + Block block = Build.A.Block.WithNumber(i).WithTotalDifficulty(1ul).TestObject; tree.Insert(block.Header); Received.InOrder(() => { @@ -1613,7 +1613,7 @@ public void Block_loading_is_lazy() { SyncConfig syncConfig = new() { - PivotNumber = 0L, + PivotNumber = 0ul, }; BlockTreeBuilder builder = Build.A.BlockTree() @@ -1625,7 +1625,7 @@ public void Block_loading_is_lazy() tree.SuggestBlock(genesis); Block previousBlock = genesis; - for (int i = 1; i < 10; i++) + for (ulong i = 1ul; i < 10ul; i++) { Block block = Build.A.Block.WithNumber(i).WithParent(previousBlock).TestObject; tree.SuggestBlock(block); @@ -1760,12 +1760,7 @@ public void Throws_when_start_at_zero() Assert.Throws(() => blockTree.DeleteChainSlice(0, 1)); } - [Test, MaxTime(Timeout.MaxTestTime)] - public void Throws_when_start_below_zero() - { - BlockTree blockTree = Build.A.BlockTree().OfChainLength(3).TestObject; - Assert.Throws(() => blockTree.DeleteChainSlice(-1, 1)); - } + [Test, MaxTime(Timeout.MaxTestTime)] public void Cannot_delete_too_many() @@ -1831,7 +1826,7 @@ public void Recovers_total_difficulty(int chainLength, bool deleteAllLevels, ulo int chainLeft = deleteAllLevels ? 0 : 1; for (int i = chainLength - 1; i >= chainLeft; i--) { - ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i); + ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i); if (level is not null) { for (int j = 0; j < level.BlockInfos.Length; j++) @@ -1844,7 +1839,7 @@ public void Recovers_total_difficulty(int chainLength, bool deleteAllLevels, ulo } } - blockTreeBuilder.ChainLevelInfoRepository.Delete(i); + blockTreeBuilder.ChainLevelInfoRepository.Delete((ulong)i); } } @@ -1852,7 +1847,7 @@ public void Recovers_total_difficulty(int chainLength, bool deleteAllLevels, ulo for (int i = chainLength - 1; i >= 0; i--) { - ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i); + ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i); Assert.That(level, Is.Not.Null); Assert.That(level!.BlockInfos.Length, Is.EqualTo(1)); @@ -1936,7 +1931,7 @@ public void BlockAddedToMain_should_have_updated_Head() Block block1 = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject; AddToMain(blockTree, block0); - long blockAddedToMainHeadNumber = 0; + ulong blockAddedToMainHeadNumber = 0ul; blockTree.BlockAddedToMain += (_, _) => { blockAddedToMainHeadNumber = blockTree.Head!.Header.Number; }; AddToMain(blockTree, block1); @@ -2089,7 +2084,7 @@ public void Can_insert_headers_in_batch() blockTree.BulkInsertHeader(batch); - for (int i = 1; i < 101; i++) + for (ulong i = 1ul; i < 101ul; i++) { Assert.That(blockTree.FindHeader(i, BlockTreeLookupOptions.None), Is.Not.Null); } @@ -2101,9 +2096,9 @@ private class TestBlockTreeVisitor(ManualResetEvent manualResetEvent) : IBlockTr private bool _wait = true; public bool PreventsAcceptingNewBlocks => true; - public long StartLevelInclusive => 0; - public long EndLevelExclusive => 3; - public async Task VisitLevelStart(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken) + public ulong StartLevelInclusive => 0; + public ulong EndLevelExclusive => 3; + public async Task VisitLevelStart(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { if (_wait) { @@ -2123,7 +2118,7 @@ public Task VisitBlock(Block block, CancellationToken cancell Task.FromResult(BlockVisitOutcome.None); public Task VisitLevelEnd( - ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken) => + ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) => Task.FromResult(LevelVisitOutcome.None); } @@ -2160,7 +2155,7 @@ public void Load_SyncPivot_FromDb() [Test, MaxTime(Timeout.MaxTestTime)] public void On_UpdateMainBranch_UpdateSyncPivot_ToLowestPersistedHeader() { - long pivotNumber = 3L; + ulong pivotNumber = 3ul; SyncConfig syncConfig = new() { @@ -2178,21 +2173,21 @@ public void On_UpdateMainBranch_UpdateSyncPivot_ToLowestPersistedHeader() Block block = Build.A.Block.Genesis.TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); - for (long i = 1; i <= 5; i++) + for (ulong i = 1ul; i <= 5ul; i++) { - block = Build.A.Block.WithTotalDifficulty(1L).WithParent(block).TestObject; + block = Build.A.Block.WithTotalDifficulty(1ul).WithParent(block).TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); tree.UpdateMainChain(block); tree.ForkChoiceUpdated(block.Hash, block.Hash); Assert.That(tree.SyncPivot, Is.EqualTo((pivotNumber, TestItem.KeccakA))); } - tree.BestPersistedState = 5; + tree.BestPersistedState = 5ul; BlockHeader persistedStateHeader = tree.FindHeader(tree.BestPersistedState.Value, BlockTreeLookupOptions.RequireCanonical)!; - for (long i = 6; i < 10; i++) + for (ulong i = 6ul; i < 10ul; i++) { - block = Build.A.Block.WithTotalDifficulty(1L).WithParent(block).TestObject; + block = Build.A.Block.WithTotalDifficulty(1ul).WithParent(block).TestObject; tree.SuggestBlock(block); tree.UpdateMainChain(block); tree.ForkChoiceUpdated(block.Hash, block.Hash); @@ -2203,7 +2198,7 @@ public void On_UpdateMainBranch_UpdateSyncPivot_ToLowestPersistedHeader() [Test, MaxTime(Timeout.MaxTestTime)] public void On_ForkChoiceUpdated_UpdateSyncPivot_ToFinalizedHeader_BeforePersistedState() { - long pivotNumber = 3L; + ulong pivotNumber = 3ul; SyncConfig syncConfig = new() { @@ -2221,18 +2216,18 @@ public void On_ForkChoiceUpdated_UpdateSyncPivot_ToFinalizedHeader_BeforePersist Block block = Build.A.Block.Genesis.TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); - for (long i = 1; i <= 10; i++) + for (ulong i = 1ul; i <= 10ul; i++) { - block = Build.A.Block.WithTotalDifficulty(1L).WithParent(block).TestObject; + block = Build.A.Block.WithTotalDifficulty(1ul).WithParent(block).TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); tree.UpdateMainChain(block); Assert.That(tree.SyncPivot, Is.EqualTo((pivotNumber, TestItem.KeccakA))); } - tree.BestPersistedState = 7; + tree.BestPersistedState = 7ul; BlockHeader persistedStateHeader = tree.FindHeader(tree.BestPersistedState.Value, BlockTreeLookupOptions.RequireCanonical)!; - for (long i = 4; i < 10; i++) + for (ulong i = 4ul; i < 10ul; i++) { BlockHeader header = tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!; tree.ForkChoiceUpdated(header.Hash, header.Hash); @@ -2251,7 +2246,7 @@ public void On_ForkChoiceUpdated_UpdateSyncPivot_ToFinalizedHeader_BeforePersist [Test, MaxTime(Timeout.MaxTestTime)] public void On_UpdateMainBranch_UpdateSyncPivot_ToHeaderUnderReorgDepth() { - long pivotNumber = 3L; + ulong pivotNumber = 3ul; SyncConfig syncConfig = new() { @@ -2269,24 +2264,24 @@ public void On_UpdateMainBranch_UpdateSyncPivot_ToHeaderUnderReorgDepth() Block block = Build.A.Block.Genesis.TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); - for (long i = 1; i <= 5; i++) + for (ulong i = 1ul; i <= 5ul; i++) { block = Build.A.Block .WithParent(block) - .WithDifficulty(1L) - .WithTotalDifficulty(block.TotalDifficulty + 1) + .WithDifficulty(1ul) + .WithTotalDifficulty(block.TotalDifficulty + 1ul) .TestObject; Assert.That(tree.SuggestBlock(block), Is.EqualTo(AddBlockResult.Added)); tree.UpdateMainChain(block); Assert.That(tree.SyncPivot, Is.EqualTo((pivotNumber, TestItem.KeccakA))); } - for (long i = 6; i < 100; i++) + for (ulong i = 6ul; i < 100ul; i++) { block = Build.A.Block .WithParent(block) - .WithDifficulty(1L) - .WithTotalDifficulty(block.TotalDifficulty + 1) + .WithDifficulty(1ul) + .WithTotalDifficulty(block.TotalDifficulty + 1ul) .TestObject; tree.SuggestBlock(block); tree.UpdateMainChain(block); @@ -2412,13 +2407,13 @@ public void UpdateMainChain_WhenBeaconSyncMarksThenReorgsToSibling_ClearsStaleMa } // FindCanonicalBlockInfo must return null for all orphaned heights - for (int h = 2; h <= descendantCount + 1; h++) + for (ulong h = 2ul; h <= (ulong)descendantCount + 1ul; h++) { Assert.That(blockTree.FindCanonicalBlockInfo(h), Is.Null, $"H={h} must return null — orphaned after reorg"); } // Canonical lookup at H=1 must return sibling - BlockInfo? infoAt1 = blockTree.FindCanonicalBlockInfo(1); + BlockInfo? infoAt1 = blockTree.FindCanonicalBlockInfo(1ul); Assert.That(infoAt1, Is.Not.Null); Assert.That(infoAt1!.BlockHash, Is.EqualTo(sibling.Hash!), "H=1 must return sibling's hash"); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs index ebb302553ce1..4ee7b0b6fa00 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs @@ -188,14 +188,14 @@ public void Sequential_queries_work_correctly() { (BlockTree tree, BlockhashCache cache) = BuildTest(512); - for (int blockNum = 256; blockNum < 512; blockNum += 50) + for (ulong blockNum = 256ul; blockNum < 512ul; blockNum += 50ul) { BlockHeader? block = tree.FindHeader(blockNum, BlockTreeLookupOptions.None); for (int depth = 1; depth <= 100; depth += 25) { Hash256? result = cache.GetHash(block!, depth); - BlockHeader? expected = tree.FindHeader(blockNum - depth, BlockTreeLookupOptions.None); + BlockHeader? expected = tree.FindHeader(blockNum - (ulong)depth, BlockTreeLookupOptions.None); Assert.That(result, Is.EqualTo(expected!.Hash!), $"block {blockNum} depth {depth}"); } } @@ -206,14 +206,14 @@ public async Task Periodic_pruning_maintains_cache_size() { (BlockTree tree, BlockhashCache cache) = BuildTest(1000); - for (int i = 100; i < 1000; i += 100) + for (ulong i = 100ul; i < 1000ul; i += 100ul) { BlockHeader block = tree.FindHeader(i, BlockTreeLookupOptions.None)!; await cache.Prefetch(block); - if (i > 500) + if (i > 500ul) { - int pruned = cache.PruneBefore(i - 400); + int pruned = cache.PruneBefore(i - 400ul); Assert.That(pruned, Is.GreaterThan(0)); Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(401, 1, 5))); } @@ -225,7 +225,7 @@ public void Can_stitch_block_ranges() { (BlockTree tree, BlockhashCache cache) = BuildTest(1000); - for (int i = 100; i <= 500; i += 100) + for (ulong i = 100ul; i <= 500ul; i += 100ul) { BlockHeader block = tree.FindHeader(i, BlockTreeLookupOptions.None)!; cache.GetHash(block, 50); @@ -233,7 +233,7 @@ public void Can_stitch_block_ranges() Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(255, 5, 0))); - for (int i = 100; i <= 500; i += 100) + for (ulong i = 100ul; i <= 500ul; i += 100ul) { BlockHeader block = tree.FindHeader(i, BlockTreeLookupOptions.None)!; cache.GetHash(block, BlockhashCache.MaxDepth); @@ -264,15 +264,15 @@ public async Task Can_support_multiple_forks() [Test] public async Task Can_prune_old_forks() { - const int depth = BlockhashCache.MaxDepth * 5 + 1; - (BlockTree tree, BlockhashCache cache) = BuildTest(depth); - for (int i = BlockhashCache.MaxDepth; i < depth; i += BlockhashCache.MaxDepth) + const ulong depth = BlockhashCache.MaxDepth * 5 + 1; + (BlockTree tree, BlockhashCache cache) = BuildTest((int)depth); + for (ulong i = (ulong)BlockhashCache.MaxDepth; i < depth; i += (ulong)BlockhashCache.MaxDepth) { cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, BlockhashCache.MaxDepth); } - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(depth, 1, 5))); - await cache.Prefetch(tree.FindHeader(depth - 1, BlockTreeLookupOptions.RequireCanonical)!); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)depth, 1, 5))); + await cache.Prefetch(tree.FindHeader(depth - 1ul, BlockTreeLookupOptions.RequireCanonical)!); await Task.Delay(100); Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(BlockhashCache.MaxDepth * 2 + 1, 1, 3))); } @@ -296,17 +296,17 @@ public async Task Prefetch_prunes() Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(200, 1, 1))); } - [TestCase(300)] - [TestCase(50)] - public async Task Prefetch_reuses_parent_data(int chainDepth) + [TestCase(300ul)] + [TestCase(50ul)] + public async Task Prefetch_reuses_parent_data(ulong chainDepth) { - (BlockTree tree, BlockhashCache cache) = BuildTest(chainDepth); - BlockHeader head = tree.FindHeader(chainDepth - 1, BlockTreeLookupOptions.None)!; - BlockHeader prev = tree.FindHeader(chainDepth - 2, BlockTreeLookupOptions.None)!; + (BlockTree tree, BlockhashCache cache) = BuildTest((int)chainDepth); + BlockHeader head = tree.FindHeader(chainDepth - 1ul, BlockTreeLookupOptions.None)!; + BlockHeader prev = tree.FindHeader(chainDepth - 2ul, BlockTreeLookupOptions.None)!; Hash256[] prevHashes = (await cache.Prefetch(prev, CancellationToken.None))!; Hash256[] headHashes = (await cache.Prefetch(head, CancellationToken.None))!; - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(Math.Min(chainDepth - 1, FlatCacheItemLength), 1, 2))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)Math.Min(chainDepth - 1ul, (ulong)FlatCacheItemLength), 1, 2))); Assert.Multiple(() => { int compareLength = headHashes.Length - 1; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs index fb497fb3441e..559f878f3562 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs @@ -143,7 +143,7 @@ public void Lookup_with_competing_branches_after_fast_sync(int additionalBlocks) current = Build.A.Block.WithParent(current).TestObject; } - long lookupNumber = current.Number - 256; + ulong lookupNumber = current.Number - 256ul; Hash256? result = provider.GetBlockhash(current.Header, lookupNumber, Frontier.Instance); Assert.That(result, Is.Not.Null); } @@ -173,21 +173,21 @@ public void Can_handle_non_main_chain_in_fast_sync() } [MaxTime(Timeout.MaxTestTime)] - [TestCase(512, -1, true, TestName = "Can_get_parent_hash")] - [TestCase(512, 0, false, TestName = "Cannot_ask_for_self")] - [TestCase(512, 1, false, TestName = "Cannot_ask_about_future")] - [TestCase(512, -256, true, TestName = "Can_lookup_up_to_256_before")] - [TestCase(512, -257, false, TestName = "No_lookup_more_than_256_before")] - public void Blockhash_lookup_with_full_chain(int chainLength, int lookupOffset, bool expectNonNull) + [TestCase(512ul, -1, true, TestName = "Can_get_parent_hash")] + [TestCase(512ul, 0, false, TestName = "Cannot_ask_for_self")] + [TestCase(512ul, 1, false, TestName = "Cannot_ask_about_future")] + [TestCase(512ul, -256, true, TestName = "Can_lookup_up_to_256_before")] + [TestCase(512ul, -257, false, TestName = "No_lookup_more_than_256_before")] + public void Blockhash_lookup_with_full_chain(ulong chainLength, int lookupOffset, bool expectNonNull) { Block genesis = Build.A.Block.Genesis.TestObject; - BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfChainLength(chainLength); + BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfChainLength((int)chainLength); BlockTree tree = blockTreeBuilder.TestObject; BlockhashProvider provider = CreateBlockHashProvider(blockTreeBuilder.HeaderStore, Frontier.Instance); - BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; + BlockHeader head = tree.FindHeader(chainLength - 1ul, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - long lookupNumber = chainLength + lookupOffset; + ulong lookupNumber = (ulong)((long)chainLength + lookupOffset); Hash256? result = provider.GetBlockhash(current.Header, lookupNumber, Frontier.Instance); if (expectNonNull) @@ -218,17 +218,17 @@ public void UInt_256_overflow() } [MaxTime(Timeout.MaxTestTime)] - [TestCase(1)] - [TestCase(512)] - [TestCase(8192)] - [TestCase(8193)] - public void Eip2935_enabled_Eip7709_disabled_and_then_get_hash(int chainLength) + [TestCase(1ul)] + [TestCase(512ul)] + [TestCase(8192ul)] + [TestCase(8193ul)] + public void Eip2935_enabled_Eip7709_disabled_and_then_get_hash(ulong chainLength) { Block genesis = Build.A.Block.Genesis.TestObject; - BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength); + BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength((int)chainLength); BlockTree tree = blockTreeBuilder.TestObject; - BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); + BlockHeader? head = tree.FindHeader(chainLength - 1ul, BlockTreeLookupOptions.None); // number = chainLength (IWorldState worldState, Hash256 stateRoot) = CreateWorldState(); @@ -271,11 +271,11 @@ private static void AssertGenesisHash(IReleaseSpec spec, BlockhashProvider provi [Test, MaxTime(Timeout.MaxTestTime)] public void Eip2935_poc_trimmed_hashes() { - int chainLength = 42; + ulong chainLength = 42ul; Block genesis = Build.A.Block.Genesis.TestObject; - BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; + BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength((int)chainLength).TestObject; - BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); + BlockHeader? head = tree.FindHeader(chainLength - 1ul, BlockTreeLookupOptions.None); // number = chainLength (IWorldState worldState, Hash256 stateRoot) = CreateWorldState(); @@ -309,7 +309,7 @@ public void BlockAccessListManager_blockhash_state_changes_match_BlockhashStore( IWorldState balWorldState = CreateWorldStateWithHistoryContract(spec); Block parent = Build.A.Block.WithNumber(41).TestObject; Block current = Build.A.Block.WithParent(parent).TestObject; - UInt256 parentBlockIndex = new((ulong)((current.Number - 1) % spec.Eip2935RingBufferSize)); + UInt256 parentBlockIndex = new((current.Number - 1) % spec.Eip2935RingBufferSize); StorageCell storageCell = new(Eip2935Constants.BlockHashHistoryAddress, parentBlockIndex); using IDisposable legacyScope = legacyWorldState.BeginScope(current.Header); @@ -373,7 +373,7 @@ public void BlockhashStore_uses_custom_ring_buffer_size() // At block 150 with buffer size 100, we need hashes for blocks 50-149 // Block 150 stores block 149's hash (already done above) // Now process blocks 51-149 from the tree to store blocks 50-148 - for (long blockNum = chainLength - customRingBufferSize + 1; blockNum < chainLength; blockNum++) + for (ulong blockNum = chainLength - customRingBufferSize + 1; blockNum < chainLength; blockNum++) { BlockHeader? header = tree.FindHeader(blockNum, BlockTreeLookupOptions.None); Assert.That(header, Is.Not.Null, $"Block {blockNum} should exist in tree"); @@ -383,7 +383,7 @@ public void BlockhashStore_uses_custom_ring_buffer_size() // Now verify all blocks behave correctly with custom ring buffer size // At block 150 with buffer size 100, only blocks [50, 149] should be retrievable - for (long blockNum = 1; blockNum < chainLength - customRingBufferSize; blockNum++) + for (ulong blockNum = 1ul; blockNum < (chainLength - customRingBufferSize); blockNum++) { Hash256? result = store.GetBlockHashFromState(current.Header, blockNum, customSpec); @@ -391,7 +391,7 @@ public void BlockhashStore_uses_custom_ring_buffer_size() $"Block {blockNum} should be outside custom ring buffer of size {customRingBufferSize} (proves custom size is used, not default 8191)"); } - for (long blockNum = chainLength - customRingBufferSize; blockNum < chainLength; blockNum++) + for (ulong blockNum = chainLength - customRingBufferSize; blockNum < chainLength; blockNum++) { BlockHeader? expectedHeader = tree.FindHeader(blockNum, BlockTreeLookupOptions.None); Hash256? result = store.GetBlockHashFromState(current.Header, blockNum, customSpec); @@ -414,7 +414,7 @@ public async Task Prefetches_come_in_wrong_order() SlowHeaderStore slowHeaderStore = new(blockTreeBuilder.HeaderStore) { SlowBlockNumber = 2 }; BlockTree tree = blockTreeBuilder.TestObject; BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; - long expectedBlockNumber = head.Number - 2; + ulong expectedBlockNumber = head.Number - 2; BlockHeader expected = tree.FindHeader(expectedBlockNumber, BlockTreeLookupOptions.None)!; BlockHeader previousHead = tree.FindHeader(chainLength - 4, BlockTreeLookupOptions.None)!; BlockhashProvider provider = CreateBlockHashProvider(slowHeaderStore, Frontier.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs index 281aed95c90e..8a31b5a7cf8a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs @@ -21,42 +21,42 @@ namespace Nethermind.Blockchain.Test.Bloom; public class BloomStorageTests { [MaxTime(Timeout.MaxTestTime)] - [TestCase(0, 0)] - [TestCase(1, 1)] - [TestCase(0, 10)] - [TestCase(10, 12)] - public void Empty_storage_does_not_contain_blocks(long from, long to) + [TestCase(0ul, 0ul)] + [TestCase(1ul, 1ul)] + [TestCase(0ul, 10ul)] + [TestCase(10ul, 12ul)] + public void Empty_storage_does_not_contain_blocks(ulong from, ulong to) { BloomStorage storage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); Assert.That(storage.ContainsRange(from, to), Is.False); } [MaxTime(Timeout.MaxTestTime)] - [TestCase(0, 0, ExpectedResult = false)] - [TestCase(1, 1, ExpectedResult = true)] - [TestCase(0, 10, ExpectedResult = false)] - [TestCase(1, 10, ExpectedResult = true)] - [TestCase(10, 12, ExpectedResult = false)] - public bool Initialized_storage_contain_blocks_as_db(long from, long to) + [TestCase(0ul, 0ul, ExpectedResult = false)] + [TestCase(1ul, 1ul, ExpectedResult = true)] + [TestCase(0ul, 10ul, ExpectedResult = false)] + [TestCase(1ul, 10ul, ExpectedResult = true)] + [TestCase(10ul, 12ul, ExpectedResult = false)] + public bool Initialized_storage_contain_blocks_as_db(ulong from, ulong to) { MemDb memColumnsDb = new(); - memColumnsDb.Set(BloomStorage.MinBlockNumberKey, 1L.ToBigEndianByteArrayWithoutLeadingZeros()); - memColumnsDb.Set(BloomStorage.MaxBlockNumberKey, 11L.ToBigEndianByteArrayWithoutLeadingZeros()); + memColumnsDb.Set(BloomStorage.MinBlockNumberKey, 1UL.ToBigEndianByteArrayWithoutLeadingZeros()); + memColumnsDb.Set(BloomStorage.MaxBlockNumberKey, 11UL.ToBigEndianByteArrayWithoutLeadingZeros()); BloomStorage storage = new(new BloomConfig(), memColumnsDb, new InMemoryDictionaryFileStoreFactory()); return storage.ContainsRange(from, to); } [MaxTime(Timeout.MaxTestTime)] - [TestCase(0, 0, ExpectedResult = false)] - [TestCase(1, 1, ExpectedResult = true)] - [TestCase(0, 10, ExpectedResult = false)] - [TestCase(1, 10, ExpectedResult = true)] - [TestCase(10, 12, ExpectedResult = false)] - public bool Contain_blocks_after_store(long from, long to) + [TestCase(0ul, 0ul, ExpectedResult = false)] + [TestCase(1ul, 1ul, ExpectedResult = true)] + [TestCase(0ul, 10ul, ExpectedResult = false)] + [TestCase(1ul, 10ul, ExpectedResult = true)] + [TestCase(10ul, 12ul, ExpectedResult = false)] + public bool Contain_blocks_after_store(ulong from, ulong to) { BloomStorage storage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); - for (long i = 1; i < 11; i++) + for (ulong i = 1; i < 11; i++) { storage.Store(i, Core.Bloom.Empty); } @@ -68,39 +68,39 @@ public static IEnumerable GetBloomsTestCases { get { - static IEnumerable GetRange(long expectedFound, int offset = 0) => Enumerable.Range(offset, (int)expectedFound).Select(static i => (long)i); + static IEnumerable GetRange(long expectedFound, int offset = 0) => Enumerable.Range(offset, (int)expectedFound).Select(static i => (ulong)i); int searchesPerBucket = 1 + LevelMultiplier + LevelMultiplier * LevelMultiplier + LevelMultiplier * LevelMultiplier * LevelMultiplier; int bucketItems = new BloomStorage(new BloomConfig() { IndexLevelBucketSizes = new[] { LevelMultiplier, LevelMultiplier, LevelMultiplier } }, new MemDb(), new InMemoryDictionaryFileStoreFactory()).MaxBucketSize; int count = bucketItems * Buckets; int maxIndex = count - 1; - yield return new TestCaseData(0, maxIndex, false, Enumerable.Empty(), Buckets) + yield return new TestCaseData(0UL, (ulong)maxIndex, false, Enumerable.Empty(), Buckets) .SetName("Returns_no_blocks_when_blooms_do_not_match"); - yield return new TestCaseData(0, maxIndex, true, GetRange(count), Buckets * searchesPerBucket) + yield return new TestCaseData(0UL, (ulong)maxIndex, true, GetRange(count), Buckets * searchesPerBucket) .SetName("Returns_all_blocks_when_all_blooms_match"); - yield return new TestCaseData(5, 49, true, GetRange(45, 5), 4 + 45) + yield return new TestCaseData(5UL, 49UL, true, GetRange(45, 5), 4 + 45) .SetName("Returns_range_after_level_one_lookup"); - yield return new TestCaseData(0, LevelMultiplier * LevelMultiplier * LevelMultiplier - 1, true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier), searchesPerBucket - 1) + yield return new TestCaseData(0UL, (ulong)(LevelMultiplier * LevelMultiplier * LevelMultiplier - 1), true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier), searchesPerBucket - 1) .SetName("Returns_single_bucket_without_highest_level_lookup"); - yield return new TestCaseData(0, LevelMultiplier * LevelMultiplier * LevelMultiplier * 2 - 1, true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier * 2), (searchesPerBucket - 1) * 2) + yield return new TestCaseData(0UL, (ulong)(LevelMultiplier * LevelMultiplier * LevelMultiplier * 2 - 1), true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier * 2), (searchesPerBucket - 1) * 2) .SetName("Returns_two_buckets_without_highest_level_lookup"); - yield return new TestCaseData(0, LevelMultiplier * LevelMultiplier * LevelMultiplier * 3 - 1, true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier * 3), searchesPerBucket * 3) + yield return new TestCaseData(0UL, (ulong)(LevelMultiplier * LevelMultiplier * LevelMultiplier * 3 - 1), true, GetRange(LevelMultiplier * LevelMultiplier * LevelMultiplier * 3), searchesPerBucket * 3) .SetName("Returns_three_buckets_with_highest_level_lookup"); } } [TestCaseSource(nameof(GetBloomsTestCases))] - public void Returns_proper_blooms_after_store(long from, long to, bool isMatch, IEnumerable expectedBlocks, long expectedBloomsChecked) + public void Returns_proper_blooms_after_store(ulong from, ulong to, bool isMatch, IEnumerable expectedBlocks, long expectedBloomsChecked) { BloomStorage storage = CreateBloomStorage(new BloomConfig() { IndexLevelBucketSizes = new[] { LevelMultiplier, LevelMultiplier, LevelMultiplier } }); long bloomsChecked = 0; IBloomEnumeration bloomEnumeration = storage.GetBlooms(from, to); - IList ranges = []; + IList ranges = []; foreach (Core.Bloom unused in bloomEnumeration) { bloomsChecked++; - if (isMatch && bloomEnumeration.TryGetBlockNumber(out long blockNumber)) + if (isMatch && bloomEnumeration.TryGetBlockNumber(out ulong blockNumber)) { ranges.Add(blockNumber); } @@ -111,22 +111,22 @@ public void Returns_proper_blooms_after_store(long from, long to, bool isMatch, } [MaxTime(Timeout.MaxTestTime)] - [TestCase(1, 10, new long[] { 4 }, new[] { 4 })] - [TestCase(0, 4, new long[] { 4 }, new[] { 4 })] - [TestCase(1, 10, new long[] { 1, 4, 6, 8 }, new[] { 4 })] - [TestCase(1, 10, new long[] { 4, 6, 8 }, new[] { 4, 4 })] - [TestCase(1, 10, new long[] { 4, 8, 16, 32 }, new[] { 4, 4 })] - [TestCase(1, 48, new long[] { 4, 8, 16, 32 }, new[] { 4, 4 })] - [TestCase(5, 60, new long[] { 4, 8, 49 }, new[] { 8, 3 })] - [TestCase(1, 120, new long[] { 4, 8, 64, 65 }, new[] { 4, 4, 4 })] - [TestCase(0, 120, new long[] { 0, 1, 2, 3, 5, 7, 11, 120 }, new[] { 9, 3 })] - public void Can_find_bloom_with_fromBlock_offset(long from, long to, long[] blocksSet, int[] levels) + [TestCase(1UL, 10UL, new ulong[] { 4 }, new[] { 4 })] + [TestCase(0UL, 4UL, new ulong[] { 4 }, new[] { 4 })] + [TestCase(1UL, 10UL, new ulong[] { 1, 4, 6, 8 }, new[] { 4 })] + [TestCase(1UL, 10UL, new ulong[] { 4, 6, 8 }, new[] { 4, 4 })] + [TestCase(1UL, 10UL, new ulong[] { 4, 8, 16, 32 }, new[] { 4, 4 })] + [TestCase(1UL, 48UL, new ulong[] { 4, 8, 16, 32 }, new[] { 4, 4 })] + [TestCase(5UL, 60UL, new ulong[] { 4, 8, 49 }, new[] { 8, 3 })] + [TestCase(1UL, 120UL, new ulong[] { 4, 8, 64, 65 }, new[] { 4, 4, 4 })] + [TestCase(0UL, 120UL, new ulong[] { 0, 1, 2, 3, 5, 7, 11, 120 }, new[] { 9, 3 })] + public void Can_find_bloom_with_fromBlock_offset(ulong from, ulong to, ulong[] blocksSet, int[] levels) { BloomStorage storage = CreateBloomStorage(new BloomConfig { IndexLevelBucketSizes = levels }); Core.Bloom bloom = new(); byte[] bytes = { 1, 2, 3 }; bloom.Set(bytes); - foreach (long blockNumber in blocksSet) + foreach (ulong blockNumber in blocksSet) { if (blockNumber > storage.MaxBlockNumber + 1) { @@ -136,16 +136,16 @@ public void Can_find_bloom_with_fromBlock_offset(long from, long to, long[] bloc } IBloomEnumeration bloomEnumeration = storage.GetBlooms(from, to); - IList foundBlocks = new List(blocksSet.Length); + IList foundBlocks = new List(blocksSet.Length); foreach (Core.Bloom b in bloomEnumeration) { - if (b.Matches(bytes) && bloomEnumeration.TryGetBlockNumber(out long block)) + if (b.Matches(bytes) && bloomEnumeration.TryGetBlockNumber(out ulong block)) { foundBlocks.Add(block); } } - long[] expectedFoundBlocks = blocksSet.Where(b => b >= from && b <= to).ToArray(); + ulong[] expectedFoundBlocks = blocksSet.Where(b => b >= from && b <= to).ToArray(); TestContext.Out.WriteLine($"Expected found blocks: {string.Join(", ", expectedFoundBlocks)}"); Assert.That(foundBlocks, Is.EqualTo(expectedFoundBlocks)); } @@ -158,7 +158,7 @@ private static BloomStorage CreateBloomStorage(BloomConfig? bloomConfig = null) BloomStorage storage = new(bloomConfig ?? new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); int bucketItems = storage.MaxBucketSize * Buckets; - for (long i = 0; i < bucketItems; i++) + for (ulong i = 0; i < (ulong)bucketItems; i++) { storage.Store(i, Core.Bloom.Empty); } @@ -180,7 +180,7 @@ public void Can_safely_insert_concurrently(int maxBlock) => RunInsertAndVerify(m { Core.Bloom bloom = new(); bloom.Set(i % Core.Bloom.BitLength); - storage.Store(i, bloom); + storage.Store((ulong)i, bloom); }); }); @@ -192,12 +192,12 @@ public void Can_safely_insert_concurrently(int maxBlock) => RunInsertAndVerify(m [TestCase(ushort.MaxValue * 128 + 127, Explicit = true)] public void Can_safely_insert_in_batch(int maxBlock) => RunInsertAndVerify(maxBlock, (storage, count) => { - using ArrayPoolList<(long, Core.Bloom)> bloomInsertions = new(count); + using ArrayPoolList<(ulong, Core.Bloom)> bloomInsertions = new(count); for (int i = 0; i < count; i++) { Core.Bloom bloom = new(); bloom.Set(i % Core.Bloom.BitLength); - bloomInsertions.Add((i, bloom)); + bloomInsertions.Add(((ulong)i, bloom)); } storage.Store(bloomInsertions); }); @@ -214,14 +214,14 @@ private static void RunInsertAndVerify(int maxBlock, Action i insertAction(storage, maxBlock + 1); - IBloomEnumeration blooms = storage.GetBlooms(0, maxBlock); + IBloomEnumeration blooms = storage.GetBlooms(0, (ulong)maxBlock); int j = 0; foreach (Core.Bloom bloom in blooms) { j++; - (long FromBlock, long ToBlock) = blooms.CurrentIndices; + (ulong FromBlock, ulong ToBlock) = blooms.CurrentIndices; int fromBlock = (int)(FromBlock % Core.Bloom.BitLength); - int toBlock = (int)(Math.Min(ToBlock, maxBlock) % Core.Bloom.BitLength); + int toBlock = (int)(Math.Min(ToBlock, (ulong)maxBlock) % Core.Bloom.BitLength); Core.Bloom expectedBloom = new(); for (int i = fromBlock; i <= toBlock; i++) { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs index 0e7c4a80a9f8..7ab75ae64e0e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Builders/FilterBuilder.cs @@ -38,7 +38,7 @@ public FilterBuilder WithId(int id) return this; } - public FilterBuilder FromBlock(long number) + public FilterBuilder FromBlock(ulong number) { _fromBlock = new BlockParameter(number); return this; @@ -67,7 +67,7 @@ public FilterBuilder FromLatestBlock() public FilterBuilder FromFutureBlock() { - _fromBlock = new BlockParameter(1000000); + _fromBlock = new BlockParameter(1000000ul); return this; } @@ -79,7 +79,7 @@ public FilterBuilder FromPendingBlock() return this; } - public FilterBuilder ToBlock(long number) + public FilterBuilder ToBlock(ulong number) { _toBlock = new BlockParameter(number); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/CompositeTxSourceTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/CompositeTxSourceTests.cs index c1b2e7e6c183..2552757d4624 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/CompositeTxSourceTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/CompositeTxSourceTests.cs @@ -34,7 +34,7 @@ public void selectTransactions_injects_transactions_from_ImmediateTransactionSou ITxSource CreateImmediateTransactionSource(BlockHeader header, Address address, List txs, bool createsTransaction) { ITxSource immediateTransactionSource = Substitute.For(); - immediateTransactionSource.GetTransactions(header, Arg.Any()).Returns(x => + immediateTransactionSource.GetTransactions(header, Arg.Any()).Returns(x => { if (createsTransaction) { @@ -51,7 +51,7 @@ ITxSource CreateImmediateTransactionSource(BlockHeader header, Address address, } BlockHeader parentHeader = Build.A.BlockHeader.TestObject; - int gasLimit = 1000; + ulong gasLimit = 1000ul; List expected = []; ITxSource innerPendingTxSelector = Substitute.For(); @@ -61,7 +61,7 @@ ITxSource CreateImmediateTransactionSource(BlockHeader header, Address address, ITxSource immediateTransactionSource3 = CreateImmediateTransactionSource(parentHeader, TestItem.AddressD, expected, true); Transaction[] originalTxs = Build.A.Transaction.TestObjectNTimes(5); - innerPendingTxSelector.GetTransactions(parentHeader, Arg.Any()).Returns(originalTxs); + innerPendingTxSelector.GetTransactions(parentHeader, Arg.Any()).Returns(originalTxs); CompositeTxSource compositeTxSource = new( immediateTransactionSource1, immediateTransactionSource2, immediateTransactionSource3, innerPendingTxSelector); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SinglePendingTxSelectorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SinglePendingTxSelectorTests.cs index b8a5311a2cbb..f3acd2c433d7 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SinglePendingTxSelectorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SinglePendingTxSelectorTests.cs @@ -48,7 +48,7 @@ public void When_many_transactions_returns_one_with_lowest_nonce_and_highest_tim Transaction[] result = selector.GetTransactions(_anyParent, 1000000).ToArray(); Assert.That(result.Length, Is.EqualTo(1)); Assert.That(result[0].Timestamp, Is.EqualTo((UInt256)8)); - Assert.That(result[0].Nonce, Is.EqualTo((UInt256)1)); + Assert.That(result[0].Nonce, Is.EqualTo(1ul)); } } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs index c4cc94c3acaa..dfd6027459a5 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs @@ -49,11 +49,11 @@ private static BlockAccessListManager CreateAmsterdamBalManager() new WithdrawalProcessorFactory(LimboLogs.Instance)); } - private static (BlockAccessListManager, Block) BuildAmsterdamBlock(long blockGasLimit, params Transaction[] txs) + private static (BlockAccessListManager, Block) BuildAmsterdamBlock(ulong blockGasLimit, params Transaction[] txs) { BlockAccessListManager balManager = CreateAmsterdamBalManager(); Block block = Build.A.Block - .WithNumber(1) + .WithNumber(1ul) .WithGasLimit(blockGasLimit) .WithTransactions(txs) .WithBlockAccessList(new ReadOnlyBlockAccessList()) @@ -73,7 +73,7 @@ private static GasValidationResultSlot[] ResultsForCount(int n) } private static GasValidationResult - GasResult(Block block, int txIndex, long blockGasUsed, long blockStateGasUsed, InvalidBlockException? exception = null) + GasResult(Block block, int txIndex, ulong blockGasUsed, ulong blockStateGasUsed, InvalidBlockException? exception = null) { IntrinsicGas intrinsicGas = EthereumGasPolicy.CalculateIntrinsicGas(block.Transactions[txIndex], Amsterdam.Instance, block.Header.GasLimit); return new(blockGasUsed, blockStateGasUsed, intrinsicGas, exception); @@ -81,16 +81,16 @@ private static GasValidationResult // Boundary: post-tx cumulative state hits the limit exactly (must accept, // IncrementalValidation uses strict >) vs exceeds by 1 (must reject). - [TestCase(200_000L, true, TestName = "Eip8037_boundary_state_exact_fit_accepts")] - [TestCase(200_001L, false, TestName = "Eip8037_boundary_state_exceeded_by_one_rejects")] - public void Eip8037_boundary_state(long blockStateGasUsed, bool accepts) + [TestCase(200_000ul, true, TestName = "Eip8037_boundary_state_exact_fit_accepts")] + [TestCase(200_001ul, false, TestName = "Eip8037_boundary_state_exceeded_by_one_rejects")] + public void Eip8037_boundary_state(ulong blockStateGasUsed, bool accepts) { - long blockGasLimit = 200_000; - Transaction tx1 = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(50_000).TestObject; + ulong blockGasLimit = 200_000ul; + Transaction tx1 = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(50_000ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, tx1); GasValidationResultSlot[] results = ResultsForCount(1); - results[0].TrySetResult(GasResult(block, 0, 50_000, blockStateGasUsed)); + results[0].TrySetResult(GasResult(block, 0, 50_000ul, blockStateGasUsed)); if (accepts) { @@ -115,18 +115,18 @@ public void Eip8037_boundary_state(long blockStateGasUsed, bool accepts) [Test] public void Eip8037_creation_tx_regular_check_actual_usage_modest_accepts() { - long blockGasLimit = 16_777_216 + 53_000 + 1; // cap + intrinsic_regular + 1 - Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216).TestObject; + ulong blockGasLimit = 16_777_216ul + 53_000ul + 1ul; // cap + intrinsic_regular + 1 + Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; Transaction createTx = Build.A.Transaction.WithHash(TestItem.KeccakB) .WithCode([]) - .WithGasLimit(53_000 + IntrinsicNewAccountState) - .WithNonce(1).TestObject; + .WithGasLimit(53_000ul + (ulong)IntrinsicNewAccountState) + .WithNonce(1ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, filler, createTx); GasValidationResultSlot[] results = ResultsForCount(2); // Filler used full cap; create tx used modest regular + intrinsic state. - results[0].TrySetResult(GasResult(block, 0, 16_777_216, 0)); - results[1].TrySetResult(GasResult(block, 1, 53_000, IntrinsicNewAccountState)); + results[0].TrySetResult(GasResult(block, 0, 16_777_216ul, 0ul)); + results[1].TrySetResult(GasResult(block, 1, 53_000ul, (ulong)IntrinsicNewAccountState)); Assert.DoesNotThrow(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None)); @@ -144,16 +144,16 @@ public void Eip8037_creation_tx_regular_check_actual_usage_modest_accepts() [Test] public void Eip8037_single_tx_state_check_exceeds_block_limit_rejects() { - long blockGasLimit = 16_777_216 + 100; // cap + tiny headroom + ulong blockGasLimit = 16_777_216ul + 100ul; // cap + tiny headroom // tx.gas = blockGasLimit + intrinsic_regular + 1 -> spec inclusion check rejects on state dim. Transaction onlyTx = Build.A.Transaction.WithHash(TestItem.KeccakA) - .WithGasLimit(blockGasLimit + 21_000 + 1).TestObject; + .WithGasLimit(blockGasLimit + 21_000ul + 1ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, onlyTx); GasValidationResultSlot[] results = ResultsForCount(1); // Simulate execution finishing with modest actual gas (post-execution view). // Spec inclusion check rejects before execution even though post-execution gas would fit. - results[0].TrySetResult(GasResult(block, 0, 21_000, 0)); + results[0].TrySetResult(GasResult(block, 0, 21_000ul, 0ul)); Assert.Throws(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[1], null, CancellationToken.None), @@ -168,18 +168,18 @@ public void Eip8037_single_tx_state_check_exceeds_block_limit_rejects() [Test] public void Eip8037_creation_tx_state_check_exceeded_rejects() { - long blockGasLimit = 16_777_216 + 200_000; // cap + headroom for filler state - Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216).TestObject; + ulong blockGasLimit = 16_777_216ul + 200_000ul; // cap + headroom for filler state + Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; Transaction createTx = Build.A.Transaction.WithHash(TestItem.KeccakB) .WithCode([]) - .WithGasLimit(53_000 + (blockGasLimit - 100_000) + 1) // state contribution exceeds remaining state by 1 - .WithNonce(1).TestObject; + .WithGasLimit(53_000ul + (blockGasLimit - 100_000ul) + 1ul) // state contribution exceeds remaining state by 1 + .WithNonce(1ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, filler, createTx); GasValidationResultSlot[] results = ResultsForCount(2); - results[0].TrySetResult(GasResult(block, 0, 50_000, 100_000)); // filler post-exec + results[0].TrySetResult(GasResult(block, 0, 50_000ul, 100_000ul)); // filler post-exec // Simulate creation tx ran with modest actual gas - spec would have rejected at inclusion. - results[1].TrySetResult(GasResult(block, 1, 53_000, IntrinsicNewAccountState)); + results[1].TrySetResult(GasResult(block, 1, 53_000ul, (ulong)IntrinsicNewAccountState)); Assert.Throws(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None), @@ -195,12 +195,12 @@ public void Eip8037_creation_tx_state_check_exceeded_rejects() [Test] public void Eip8037_eip7825_cap_with_modest_actual_gas_accepts() { - long blockGasLimit = 16_777_216 + 100; - Transaction tx = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216).TestObject; + ulong blockGasLimit = 16_777_216ul + 100ul; + Transaction tx = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, tx); GasValidationResultSlot[] results = ResultsForCount(1); - results[0].TrySetResult(GasResult(block, 0, 50_000, 0)); + results[0].TrySetResult(GasResult(block, 0, 50_000ul, 0ul)); Assert.DoesNotThrow(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[1], null, CancellationToken.None)); @@ -219,12 +219,12 @@ public void Sequential_executor_applies_eip8037_inclusion_check_before_execution new BlocksConfig { ParallelExecution = false }, new WithdrawalProcessorFactory(LimboLogs.Instance)); - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100ul; Transaction tx = Build.A.Transaction.WithHash(TestItem.KeccakA) - .WithGasLimit(blockGasLimit + 21_000 + 1) + .WithGasLimit(blockGasLimit + 21_000ul + 1ul) .TestObject; Block block = Build.A.Block - .WithNumber(1) + .WithNumber(1ul) .WithGasLimit(blockGasLimit) .WithTransactions(tx) .TestObject; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ExitOnBlocknumberHandlerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ExitOnBlocknumberHandlerTests.cs index 34d04d45bf72..9609ceff5618 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ExitOnBlocknumberHandlerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ExitOnBlocknumberHandlerTests.cs @@ -13,11 +13,11 @@ namespace Nethermind.Blockchain.Test; [Parallelizable(ParallelScope.All)] public class ExitOnBlocknumberHandlerTests { - [TestCase(10, false)] - [TestCase(99, false)] - [TestCase(100, true)] - [TestCase(101, true)] - public void Will_Exit_When_BlockReached(long blockNumber, bool exitReceived) + [TestCase(10ul, false)] + [TestCase(99ul, false)] + [TestCase(100ul, true)] + [TestCase(101ul, true)] + public void Will_Exit_When_BlockReached(ulong blockNumber, bool exitReceived) { IBlockTree blockTree = Substitute.For(); IProcessExitSource processExitSource = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs index 1cda52d846dc..9ca31132cc5e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs @@ -407,6 +407,6 @@ private static Ranges GenerateLogIndexRanges() } private static FilterBuilder BuildFilter() => FilterBuilder.New() - .FromBlock(FromBlock) - .ToBlock(ToBlock); + .FromBlock((ulong)FromBlock) + .ToBlock((ulong)ToBlock); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs index d7947d4d80ca..d22fb995ca41 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs @@ -203,31 +203,31 @@ public static IEnumerable FilterByTopicsTestsData { get { - yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakA) }, false, new long[] { 1, 1, 4 }).SetName("filter_by_topic_A_without_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakB) }, false, new long[] { 1, 4 }).SetName("filter_by_any_then_topic_B_without_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakA), TestTopicExpressions.Any }, false, new long[] { 4 }).SetName("filter_by_any_A_any_without_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakB), TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakE) }, false, new long[] { 4 }).SetName("filter_by_B_any_E_without_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB) }, false, new long[] { 1, 1, 4, 4 }).SetName("filter_by_topic_A_or_B_without_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB), TestTopicExpressions.Specific(TestItem.KeccakB) }, false, new long[] { 1, 4 }).SetName("filter_by_A_or_B_then_B_without_bloom"); - - yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakA) }, true, new long[] { 1, 1, 4 }).SetName("filter_by_topic_A_with_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakB) }, true, new long[] { 1, 4 }).SetName("filter_by_any_then_topic_B_with_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakA), TestTopicExpressions.Any }, true, new long[] { 4 }).SetName("filter_by_any_A_any_with_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakB), TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakE) }, true, new long[] { 4 }).SetName("filter_by_B_any_E_with_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB) }, true, new long[] { 1, 1, 4, 4 }).SetName("filter_by_topic_A_or_B_with_bloom"); - yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB), TestTopicExpressions.Specific(TestItem.KeccakB) }, true, new long[] { 1, 4 }).SetName("filter_by_A_or_B_then_B_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakA) }, false, new ulong[] { 1ul, 1ul, 4ul }).SetName("filter_by_topic_A_without_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakB) }, false, new ulong[] { 1ul, 4ul }).SetName("filter_by_any_then_topic_B_without_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakA), TestTopicExpressions.Any }, false, new ulong[] { 4ul }).SetName("filter_by_any_A_any_without_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakB), TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakE) }, false, new ulong[] { 4ul }).SetName("filter_by_B_any_E_without_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB) }, false, new ulong[] { 1ul, 1ul, 4ul, 4ul }).SetName("filter_by_topic_A_or_B_without_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB), TestTopicExpressions.Specific(TestItem.KeccakB) }, false, new ulong[] { 1ul, 4ul }).SetName("filter_by_A_or_B_then_B_without_bloom"); + + yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakA) }, true, new ulong[] { 1ul, 1ul, 4ul }).SetName("filter_by_topic_A_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakB) }, true, new ulong[] { 1ul, 4ul }).SetName("filter_by_any_then_topic_B_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakA), TestTopicExpressions.Any }, true, new ulong[] { 4ul }).SetName("filter_by_any_A_any_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Specific(TestItem.KeccakB), TestTopicExpressions.Any, TestTopicExpressions.Specific(TestItem.KeccakE) }, true, new ulong[] { 4ul }).SetName("filter_by_B_any_E_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB) }, true, new ulong[] { 1ul, 1ul, 4ul, 4ul }).SetName("filter_by_topic_A_or_B_with_bloom"); + yield return new TestCaseData(new[] { TestTopicExpressions.Or(TestItem.KeccakA, TestItem.KeccakB), TestTopicExpressions.Specific(TestItem.KeccakB) }, true, new ulong[] { 1ul, 4ul }).SetName("filter_by_A_or_B_then_B_with_bloom"); } } [TestCaseSource(nameof(FilterByTopicsTestsData))] - public void filter_by_topics_and_return_logs_in_order(TopicExpression[] topics, bool withBloomDb, long[] expectedBlockNumbers) + public void filter_by_topics_and_return_logs_in_order(TopicExpression[] topics, bool withBloomDb, ulong[] expectedBlockNumbers) { StoreTreeBlooms(withBloomDb); LogFilter logFilter = AllBlockFilter().WithTopicExpressions(topics).Build(); FilterLog[] logs = _logFinder.FindLogs(logFilter).ToArray(); - long[] blockNumbers = logs.Select(static (log) => log.BlockNumber).ToArray(); + ulong[] blockNumbers = logs.Select(static (log) => log.BlockNumber).ToArray(); Assert.That(expectedBlockNumbers, Is.EqualTo(blockNumbers)); } @@ -406,10 +406,10 @@ public void query_intersected_range_from_log_index(string name, .Returns(_ => Array.Empty().Cast().GetEnumerator()); Address address = TestItem.AddressA; - BlockHeader fromHeader = Build.A.BlockHeader.WithNumber(from).TestObject; - BlockHeader toHeader = Build.A.BlockHeader.WithNumber(to).TestObject; + BlockHeader fromHeader = Build.A.BlockHeader.WithNumber((ulong)from).TestObject; + BlockHeader toHeader = Build.A.BlockHeader.WithNumber((ulong)to).TestObject; LogFilter filter = FilterBuilder.New() - .FromBlock(from).ToBlock(to) + .FromBlock((ulong)from).ToBlock((ulong)to) .WithAddress(address) .Build(); @@ -446,7 +446,7 @@ private void StoreTreeBlooms(bool withBloomDb) { if (withBloomDb) { - for (int i = 0; i <= _blockTree.Head!.Number; i++) + for (ulong i = 0ul; i <= _blockTree.Head!.Number; i++) { _bloomStorage.Store(i, _blockTree.FindHeader(i)!.Bloom!); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPrunerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPrunerTests.cs index cbade6173145..e074d8e689ed 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPrunerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPrunerTests.cs @@ -190,7 +190,7 @@ private class TestContext { private readonly bool _clearPrunedDb; private readonly Hash256 _stateRoot; - private long _head; + private ulong _head; public TestFullPruningDb FullPruningDb { get; } public IPruningTrigger PruningTrigger { get; } = Substitute.For(); public IBlockTree BlockTree { get; } = Substitute.For(); @@ -300,7 +300,7 @@ public void AddBlocks(long count) { for (int i = 0; i < count; i++) { - long number = _head + 1; + ulong number = _head + 1ul; BlockTree.BestPersistedState.Returns(_head); Block head = Build.A.Block.WithStateRoot(_stateRoot).WithNumber(number).TestObject; BlockTree.Head.Returns(head); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs index 286345becdb5..cd59f95325a2 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs @@ -179,7 +179,7 @@ private static async Task RunPruning(PruningTestBlockchain chain, int time, bool PruningTriggerEventArgs args = new(); chain.PruningTrigger.Prune += Raise.Event>(args); if (args.Status != PruningStatus.Starting) return; - for (int i = 0; i < Reorganization.MaxDepth + 2; i++) + for (ulong i = 0ul; i < Reorganization.MaxDepth + 2ul; i++) { await chain.AddBlock(); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs index 94bf6b03bd81..06f8e1ab5ed8 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs @@ -37,19 +37,19 @@ public partial class ScenarioBuilder private Address _contractAddress = null!; private TestRpcBlockchain _testRpcBlockchain = null!; - private long _eip1559TransitionBlock; + private ulong _eip1559TransitionBlock; private bool _eip1559Enabled; private Task? _antecedent; - private UInt256 _currentNonce = 1; + private ulong _currentNonce = 1ul; - public ScenarioBuilder WithEip1559TransitionBlock(long transitionBlock) + public ScenarioBuilder WithEip1559TransitionBlock(ulong transitionBlock) { _eip1559Enabled = true; _eip1559TransitionBlock = transitionBlock; return this; } - private async Task CreateTestBlockchainAsync(long gasLimit) + private async Task CreateTestBlockchainAsync(ulong gasLimit) { await ExecuteAntecedentIfNeeded(); TestSingleReleaseSpecProvider spec = new( @@ -73,7 +73,7 @@ private async Task CreateTestBlockchainAsync(long gasLimit) return this; } - public ScenarioBuilder CreateTestBlockchain(long gasLimit = 10000000000) + public ScenarioBuilder CreateTestBlockchain(ulong gasLimit = 10000000000ul) { _antecedent = CreateTestBlockchainAsync(gasLimit); return this; @@ -102,18 +102,18 @@ private async Task DeployContractAsync() return this; } - public ScenarioBuilder SendEip1559Transaction(long gasLimit = 1000000, UInt256? gasPremium = null, UInt256? feeCap = null, bool serviceTransaction = false) + public ScenarioBuilder SendEip1559Transaction(ulong gasLimit = 1000000ul, UInt256? gasPremium = null, UInt256? feeCap = null, bool serviceTransaction = false) { _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, feeCap ?? UInt256.Zero, serviceTransaction); return this; } - public ScenarioBuilder SendLegacyTransaction(long gasLimit = 1000000, UInt256? gasPremium = null, bool serviceTransaction = false, UInt256? nonce = null) + public ScenarioBuilder SendLegacyTransaction(ulong gasLimit = 1000000ul, UInt256? gasPremium = null, bool serviceTransaction = false, ulong? nonce = null) { _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, UInt256.Zero, serviceTransaction, nonce); return this; } - private async Task SendTransactionAsync(long gasLimit, UInt256 gasPrice, UInt256 feeCap, bool serviceTransaction, UInt256? nonce = null) + private async Task SendTransactionAsync(ulong gasLimit, UInt256 gasPrice, UInt256 feeCap, bool serviceTransaction, ulong? nonce = null) { await ExecuteAntecedentIfNeeded(); byte[] txData = _abiEncoder.Encode( @@ -127,7 +127,7 @@ private async Task SendTransactionAsync(long gasLimit, UInt256 SenderAddress = _address, GasLimit = gasLimit, GasPrice = gasPrice, - DecodedMaxFeePerGas = feeCap, + DecodedMaxFeePerGas = (ulong)feeCap, Nonce = nonce ?? _currentNonce++, IsServiceTransaction = serviceTransaction }; @@ -167,7 +167,8 @@ private async Task BlocksBeforeTransitionShouldHaveZeroBaseFeeA IBlockTree blockTree = _testRpcBlockchain.BlockTree; Block startingBlock = blockTree.Head!; Assert.That(startingBlock.Header.BaseFeePerGas, Is.EqualTo(UInt256.Zero)); - for (long i = startingBlock.Number; i < _eip1559TransitionBlock - 1; ++i) + ulong limit = _eip1559TransitionBlock > 0ul ? _eip1559TransitionBlock - 1ul : 0ul; + for (ulong i = startingBlock.Number; i < limit; ++i) { await _testRpcBlockchain.AddBlock(TestBlockchainUtil.AddBlockFlags.MayHaveExtraTx); Block currentBlock = blockTree.Head!; @@ -278,15 +279,15 @@ public async Task BlockProducer_returns_correctly_decreases_base_fee_on_empty_bl [Test, MaxTime(Timeout.MaxTestTime)] public async Task BaseFee_should_decrease_when_we_send_transactions_below_gas_target() { - long gasLimit = 3000000; + ulong gasLimit = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .CreateTestBlockchain(gasLimit) .DeployContract() .BlocksBeforeTransitionShouldHaveZeroBaseFee() .AssertNewBlock(Eip1559Constants.DefaultForkBaseFee) - .SendLegacyTransaction(gasLimit / 3, 20.GWei) - .SendEip1559Transaction(gasLimit / 3, 1.GWei, 20.GWei) + .SendLegacyTransaction(gasLimit / 3ul, 20.GWei) + .SendEip1559Transaction(gasLimit / 3ul, 1.GWei, 20.GWei) .AssertNewBlock(875000000) .AssertNewBlockWithDecreasedBaseFee() .AssertNewBlockWithDecreasedBaseFee(); @@ -296,15 +297,15 @@ public async Task BaseFee_should_decrease_when_we_send_transactions_below_gas_ta [Test, MaxTime(Timeout.MaxTestTime)] public async Task BaseFee_should_not_change_when_we_send_transactions_equal_gas_target() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .CreateTestBlockchain(gasTarget) .DeployContract() .BlocksBeforeTransitionShouldHaveZeroBaseFee() .AssertNewBlock(Eip1559Constants.DefaultForkBaseFee) - .SendLegacyTransaction(gasTarget / 2, 20.GWei) - .SendEip1559Transaction(gasTarget / 2, 1.GWei, 20.GWei) + .SendLegacyTransaction(gasTarget / 2ul, 20.GWei) + .SendEip1559Transaction(gasTarget / 2ul, 1.GWei, 20.GWei) .AssertNewBlock(875000000) .AssertNewBlock(875000000) .AssertNewBlockWithDecreasedBaseFee(); @@ -314,16 +315,16 @@ public async Task BaseFee_should_not_change_when_we_send_transactions_equal_gas_ [Test, MaxTime(Timeout.MaxTestTime)] public async Task BaseFee_should_increase_when_we_send_transactions_above_gas_target() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .CreateTestBlockchain(gasTarget) .DeployContract() .BlocksBeforeTransitionShouldHaveZeroBaseFee() .AssertNewBlock(Eip1559Constants.DefaultForkBaseFee) - .SendLegacyTransaction(gasTarget / 2, 20.GWei) - .SendEip1559Transaction(gasTarget / 2, 1.GWei, 20.GWei) - .SendLegacyTransaction(gasTarget / 2, 20.GWei) + .SendLegacyTransaction(gasTarget / 2ul, 20.GWei) + .SendEip1559Transaction(gasTarget / 2ul, 1.GWei, 20.GWei) + .SendLegacyTransaction(gasTarget / 2ul, 20.GWei) .AssertNewBlock(875000000) .AssertNewBlockWithIncreasedBaseFee() .AssertNewBlockWithDecreasedBaseFee(); @@ -333,13 +334,13 @@ public async Task BaseFee_should_increase_when_we_send_transactions_above_gas_ta [Test, MaxTime(Timeout.MaxTestTime)] public async Task When_base_fee_decreases_previously_fee_too_low_transaction_is_included() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .CreateTestBlockchain(gasTarget) .BlocksBeforeTransitionShouldHaveZeroBaseFee() .AssertNewBlock(Eip1559Constants.DefaultForkBaseFee) - .SendLegacyTransaction(gasTarget / 2, 7.GWei / 10, nonce: UInt256.Zero) + .SendLegacyTransaction(gasTarget / 2ul, 7.GWei / 10, nonce: 0ul) .AssertNewBlock(875000000) .AssertNewBlock(765625000) .AssertNewBlock(669921875) // added tx in 9th block diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.FeeCollector.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.FeeCollector.cs index 8e5510526b66..c95683739529 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.FeeCollector.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.FeeCollector.cs @@ -47,7 +47,7 @@ private async Task AssertNewBlockFeeCollectedAsync(UInt256 expe [Test, MaxTime(Timeout.MaxTestTime)] public async Task FeeCollector_should_collect_burned_fees_when_eip1559_and_fee_collector_are_set() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .WithFeeCollector(TestItem.AddressE) @@ -64,7 +64,7 @@ public async Task FeeCollector_should_collect_burned_fees_when_eip1559_and_fee_c [Test, MaxTime(Timeout.MaxTestTime)] public async Task FeeCollector_should_not_collect_burned_fees_when_eip1559_is_not_set() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithFeeCollector(TestItem.AddressE) .CreateTestBlockchain(gasTarget) @@ -80,7 +80,7 @@ public async Task FeeCollector_should_not_collect_burned_fees_when_eip1559_is_no [Test, MaxTime(Timeout.MaxTestTime)] public async Task FeeCollector_should_not_collect_burned_fees_when_transaction_is_free() { - long gasTarget = 3000000; + ulong gasTarget = 3000000ul; BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis() .WithEip1559TransitionBlock(6) .WithFeeCollector(TestItem.AddressE) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs index b2b9904c2fda..605606ae6460 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs @@ -162,7 +162,7 @@ public async Task DevBlockProducer_OnGlobalWorldState_IsProducingAndSuggestingBl BuildBlocksWhenRequested trigger = new(); StandardBlockProducerRunner runner = new(trigger, testRpc.BlockTree, blockProducer); - long currentHead = testRpc.BlockTree.Head?.Number ?? 0; + ulong currentHead = testRpc.BlockTree.Head?.Number ?? 0ul; _ = new NonProcessingProducedBlockSuggester(testRpc.BlockTree, runner); @@ -170,7 +170,7 @@ public async Task DevBlockProducer_OnGlobalWorldState_IsProducingAndSuggestingBl await trigger.BuildBlock(testRpc.BlockTree.Head?.Header); - Assert.That(testRpc.BlockTree.BestSuggestedHeader?.Number, Is.EqualTo(currentHead + 1)); + Assert.That(testRpc.BlockTree.BestSuggestedHeader?.Number, Is.EqualTo(currentHead + 1ul)); } private async Task CreateTestRpc() diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs index b2af26a6e07a..bdb9899a4084 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs @@ -66,7 +66,7 @@ public void Parallel_and_non_parallel_root_hashing_produce_same_root() TxReceipt[] receipts = new TxReceipt[receiptCount]; for (int i = 0; i < receiptCount; i++) { - receipts[i] = Build.A.Receipt.WithAllFieldsFilled.WithGasUsedTotal(1000 + i).TestObject; + receipts[i] = Build.A.Receipt.WithAllFieldsFilled.WithGasUsedTotal((ulong)(1000 + i)).TestObject; } using TrackingCappedArrayPool parallelPool = new(receiptCount * 4, canBeParallel: true); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs index 8888c0fb4319..f65009d73e99 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs @@ -107,7 +107,7 @@ public void Parallel_and_non_parallel_root_hashing_produce_same_root() Transaction[] transactions = new Transaction[txCount]; for (int i = 0; i < txCount; i++) { - transactions[i] = Build.A.Transaction.WithNonce((UInt256)(i + 1)).Signed().TestObject; + transactions[i] = Build.A.Transaction.WithNonce((ulong)(i + 1)).Signed().TestObject; } using TrackingCappedArrayPool pool = new(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReadOnlyBlockTreeTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReadOnlyBlockTreeTests.cs index f3513b527993..d98edf49178d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReadOnlyBlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReadOnlyBlockTreeTests.cs @@ -30,24 +30,24 @@ public void DeleteChainSlice_throws_when_endNumber_other_than_bestKnownNumber() } [MaxTime(Timeout.MaxTestTime)] - [TestCase(10, 20, 15, null, false, true, TestName = "No corrupted block.")] - [TestCase(10, 20, 15, 19, false, true, TestName = "Corrupted block too far.")] - [TestCase(10, 20, 5, 19, false, true, TestName = "Start before head.")] - [TestCase(0, 20, 5, 19, false, true, TestName = "Head genesis.")] - [TestCase(null, 20, 5, 19, false, true, TestName = "Head null.")] - [TestCase(10, 20, 15, 16, false, false, TestName = "Allow deletion.")] - - [TestCase(10, 20, 15, null, true, false, TestName = "Force - No corrupted block.")] - [TestCase(10, 20, 15, 19, true, false, TestName = "Force - Corrupted block too far.")] - [TestCase(10, 20, 5, 19, true, true, TestName = "Force - Start before head.")] - [TestCase(0, 20, 5, 19, true, true, TestName = "Force - Head genesis.")] - [TestCase(null, 20, 5, 19, true, true, TestName = "Force - Head null.")] - public void DeleteChainSlice_throws_when_corrupted_blocks_not_found(long? head, long bestKnown, long start, long? corruptedBlock, bool force, bool throws) + [TestCase(10ul, 20ul, 15ul, null, false, true, TestName = "No corrupted block.")] + [TestCase(10ul, 20ul, 15ul, 19ul, false, true, TestName = "Corrupted block too far.")] + [TestCase(10ul, 20ul, 5ul, 19ul, false, true, TestName = "Start before head.")] + [TestCase(0ul, 20ul, 5ul, 19ul, false, true, TestName = "Head genesis.")] + [TestCase(null, 20ul, 5ul, 19ul, false, true, TestName = "Head null.")] + [TestCase(10ul, 20ul, 15ul, 16ul, false, false, TestName = "Allow deletion.")] + + [TestCase(10ul, 20ul, 15ul, null, true, false, TestName = "Force - No corrupted block.")] + [TestCase(10ul, 20ul, 15ul, 19ul, true, false, TestName = "Force - Corrupted block too far.")] + [TestCase(10ul, 20ul, 5ul, 19ul, true, true, TestName = "Force - Start before head.")] + [TestCase(0ul, 20ul, 5ul, 19ul, true, true, TestName = "Force - Head genesis.")] + [TestCase(null, 20ul, 5ul, 19ul, true, true, TestName = "Force - Head null.")] + public void DeleteChainSlice_throws_when_corrupted_blocks_not_found(ulong? head, ulong bestKnown, ulong start, ulong? corruptedBlock, bool force, bool throws) { _innerBlockTree.Head.Returns(head is null ? null : Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(head.Value).TestObject).TestObject); _innerBlockTree.BestKnownNumber.Returns(bestKnown); - _innerBlockTree.FindHeader(Arg.Any(), Arg.Any()) - .Returns(c => c.Arg() == corruptedBlock ? null : Build.A.BlockHeader.WithNumber(c.Arg()).TestObject); + _innerBlockTree.FindHeader(Arg.Any(), Arg.Any()) + .Returns(c => c.Arg() == corruptedBlock ? null : Build.A.BlockHeader.WithNumber(c.Arg()).TestObject); Action action = () => _blockTree.DeleteChainSlice(start, force: force); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs index e9ed88011355..ef9e51d18ca1 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs @@ -314,10 +314,10 @@ public void When_TxLookupLimitIs_NegativeOne_DoNotIndexTxHash() Assert.That(() => _receiptsDb.GetColumnDb(ReceiptsColumns.Transactions)[receipts[0].TxHash!.Bytes], Is.Null.After(100, 10)); } - [TestCase(1L, false)] - [TestCase(10L, false)] - [TestCase(11L, true)] - public void Should_only_prune_index_tx_hashes_if_blockNumber_is_bigger_than_lookupLimit(long blockNumber, bool willPruneOldIndices) + [TestCase(1ul, false)] + [TestCase(10ul, false)] + [TestCase(11ul, true)] + public void Should_only_prune_index_tx_hashes_if_blockNumber_is_bigger_than_lookupLimit(ulong blockNumber, bool willPruneOldIndices) { _receiptConfig.TxLookupLimit = 10; CreateStorage(); @@ -333,7 +333,7 @@ public void When_HeadBlockIsFarAhead_DoNotIndexTxHash() { _receiptConfig.TxLookupLimit = 1000; CreateStorage(); - (Block block, TxReceipt[] receipts) = InsertBlock(isFinalized: true, headNumber: 1001); + (Block block, TxReceipt[] receipts) = InsertBlock(isFinalized: true, headNumber: 1001ul); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(block)); Assert.That(() => _receiptsDb.GetColumnDb(ReceiptsColumns.Transactions)[receipts[0].TxHash!.Bytes], Is.Null.After(100, 10)); } @@ -437,7 +437,7 @@ public void When_NewHeadBlock_ClearOldTxIndex_And_KeepsReceipts() Assert.That(_receiptsDb.GetColumnDb(ReceiptsColumns.Transactions)[txHashBytes], Is.Not.Null); } - Block newHead = Build.A.Block.WithNumber(_receiptConfig.TxLookupLimit.Value + 1).TestObject; + Block newHead = Build.A.Block.WithNumber((ulong)_receiptConfig.TxLookupLimit.Value + 1ul).TestObject; _blockTree.FindBestSuggestedHeader().Returns(newHead.Header); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(newHead)); @@ -448,7 +448,7 @@ public void When_NewHeadBlock_ClearOldTxIndex_And_KeepsReceipts() Assert.That(_storage.HasBlock(receipts[0].BlockNumber, receipts[0].BlockHash!)); } - private (Block block, TxReceipt[] receipts) PrepareBlock(Block? block = null, bool isFinalized = false, long? headNumber = null) + private (Block block, TxReceipt[] receipts) PrepareBlock(Block? block = null, bool isFinalized = false, ulong? headNumber = null) { block ??= Build.A.Block .WithNumber(1) @@ -484,7 +484,7 @@ public void When_NewHeadBlock_ClearOldTxIndex_And_KeepsReceipts() return (block, receipts); } - private (Block block, TxReceipt[] receipts) InsertBlock(Block? block = null, bool isFinalized = false, long? headNumber = null, WriteFlags writeFlags = WriteFlags.None) + private (Block block, TxReceipt[] receipts) InsertBlock(Block? block = null, bool isFinalized = false, ulong? headNumber = null, WriteFlags writeFlags = WriteFlags.None) { (block, TxReceipt[] receipts) = PrepareBlock(block, isFinalized, headNumber); _storage.Insert(block, receipts, writeFlags: writeFlags); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReorgDepthFinalizedStateProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReorgDepthFinalizedStateProviderTests.cs index cd1f1fbe0770..02a3f76452d7 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReorgDepthFinalizedStateProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReorgDepthFinalizedStateProviderTests.cs @@ -28,11 +28,11 @@ public void Setup() public void FinalizedBlockNumber_ReturnsCorrectValue() { // Arrange - long bestKnownNumber = 1000; + ulong bestKnownNumber = 1000; _blockTree.BestKnownNumber.Returns(bestKnownNumber); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(bestKnownNumber - Reorganization.MaxDepth)); @@ -42,8 +42,8 @@ public void FinalizedBlockNumber_ReturnsCorrectValue() public void GetFinalizedStateRootAt_ReturnsNull_WhenBlockNumberExceedsFinalizedBlock() { // Arrange - long bestKnownNumber = 100; - long blockNumber = 100; + ulong bestKnownNumber = 100; + ulong blockNumber = 100; _blockTree.BestKnownNumber.Returns(bestKnownNumber); // Act @@ -51,15 +51,15 @@ public void GetFinalizedStateRootAt_ReturnsNull_WhenBlockNumberExceedsFinalizedB // Assert Assert.That(result, Is.Null); - _blockTree.DidNotReceive().FindHeader(Arg.Any(), Arg.Any()); + _blockTree.DidNotReceive().FindHeader(Arg.Any(), Arg.Any()); } [Test] public void GetFinalizedStateRootAt_ReturnsStateRoot_WhenBlockNumberIsFinalized() { // Arrange - long bestKnownNumber = 1000; - long blockNumber = 900; + ulong bestKnownNumber = 1000; + ulong blockNumber = 900; Hash256 expectedStateRoot = TestItem.KeccakA; BlockHeader header = Build.A.BlockHeader.WithStateRoot(expectedStateRoot).TestObject; @@ -78,8 +78,8 @@ public void GetFinalizedStateRootAt_ReturnsStateRoot_WhenBlockNumberIsFinalized( public void GetFinalizedStateRootAt_AtBoundary_ReturnsStateRoot() { // Arrange - long bestKnownNumber = 1000; - long blockNumber = bestKnownNumber - Reorganization.MaxDepth; // Exactly at the boundary + ulong bestKnownNumber = 1000; + ulong blockNumber = bestKnownNumber - Reorganization.MaxDepth; // Exactly at the boundary Hash256 expectedStateRoot = TestItem.KeccakD; BlockHeader header = Build.A.BlockHeader.WithStateRoot(expectedStateRoot).TestObject; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Rewards/RewardCalculatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Rewards/RewardCalculatorTests.cs index 32fc1bd53e43..ceb93e7bc44d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Rewards/RewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Rewards/RewardCalculatorTests.cs @@ -14,10 +14,10 @@ namespace Nethermind.Blockchain.Test.Rewards; public class RewardCalculatorTests { [MaxTime(Timeout.MaxTestTime)] - [TestCase(3L, 1L, 2, 5312500000000000000L, 3750000000000000000L, TestName = "Two_uncles_from_the_same_coinbase")] - [TestCase(3L, 1L, 1, 5156250000000000000L, 3750000000000000000L, TestName = "One_uncle")] - [TestCase(3L, 0L, 0, 5000000000000000000L, 0L, TestName = "No_uncles")] - public void Frontier_era_rewards(long blockNumber, long uncleNumber, int uncleCount, + [TestCase(3UL, 1UL, 2, 5312500000000000000L, 3750000000000000000L, TestName = "Two_uncles_from_the_same_coinbase")] + [TestCase(3UL, 1UL, 1, 5156250000000000000L, 3750000000000000000L, TestName = "One_uncle")] + [TestCase(3UL, 0UL, 0, 5000000000000000000L, 0L, TestName = "No_uncles")] + public void Frontier_era_rewards(ulong blockNumber, ulong uncleNumber, int uncleCount, long expectedMinerReward, long expectedUncleReward) { Block[] uncles = Enumerable.Range(0, uncleCount) @@ -38,7 +38,7 @@ public void Frontier_era_rewards(long blockNumber, long uncleNumber, int uncleCo [TestCase("ConstantinopleFix", 2125000000000000000L, 1500000000000000000L, TestName = "Constantinople_reward_two_uncles")] public void Post_frontier_two_uncle_rewards(string fork, long expectedMinerReward, long expectedUncleReward) { - long blockNumber = fork == "Byzantium" + ulong blockNumber = fork == "Byzantium" ? MainnetSpecProvider.ByzantiumBlockNumber : MainnetSpecProvider.ConstantinopleFixBlockNumber; Block uncle = Build.A.Block.WithNumber(blockNumber - 2).TestObject; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/SlowHeaderStore.cs b/src/Nethermind/Nethermind.Blockchain.Test/SlowHeaderStore.cs index bb338743dba1..9838a902fa37 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/SlowHeaderStore.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/SlowHeaderStore.cs @@ -12,9 +12,9 @@ namespace Nethermind.Blockchain.Test; public class SlowHeaderStore(IHeaderStore headerStore) : IHeaderStore { - public long SlowBlockNumber { get; set; } = 100; + public ulong SlowBlockNumber { get; set; } = 100; - public BlockHeader? Get(Hash256 blockHash, long? blockNumber = null) + public BlockHeader? Get(Hash256 blockHash, ulong? blockNumber = null) { if (blockNumber < SlowBlockNumber) Thread.Sleep(10); return headerStore.Get(blockHash, blockNumber); @@ -22,11 +22,11 @@ public class SlowHeaderStore(IHeaderStore headerStore) : IHeaderStore public void Insert(BlockHeader header) => headerStore.Insert(header); public void BulkInsert(IReadOnlyList headers) => headerStore.BulkInsert(headers); - public BlockHeader? Get(Hash256 blockHash, bool shouldCache, long? blockNumber = null) => headerStore.Get(blockHash, shouldCache, blockNumber); + public BlockHeader? Get(Hash256 blockHash, bool shouldCache, ulong? blockNumber = null) => headerStore.Get(blockHash, shouldCache, blockNumber); public void Cache(BlockHeader header) => headerStore.Cache(header); public void Delete(Hash256 blockHash) => headerStore.Delete(blockHash); - public void InsertBlockNumber(Hash256 blockHash, long blockNumber) => headerStore.InsertBlockNumber(blockHash, blockNumber); - public long? GetBlockNumber(Hash256 blockHash) => headerStore.GetBlockNumber(blockHash); - public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, Hash256 endBlockHash, int count) => + public void InsertBlockNumber(Hash256 blockHash, ulong blockNumber) => headerStore.InsertBlockNumber(blockHash, blockNumber); + public ulong? GetBlockNumber(Hash256 blockHash) => headerStore.GetBlockNumber(blockHash); + public IOwnedReadOnlyList FindReversedHeaders(ulong endBlockNumber, Hash256 endBlockHash, int count) => headerStore.FindReversedHeaders(endBlockNumber, endBlockHash, count); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionComparisonTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionComparisonTests.cs index 569b27d51011..5c7cb30fedf2 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionComparisonTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionComparisonTests.cs @@ -41,16 +41,16 @@ public void ProducerGasPriceComparer_for_legacy_transactions(int gasPriceX, int [MaxTime(Timeout.MaxTestTime)] // head block number before eip 1559 transition - [TestCase(10, 10, 0, 0, 0)] - [TestCase(15, 10, 10, 1, -1)] - [TestCase(2, 3, 20, 0, 1)] + [TestCase(10, 10, 0, 0ul, 0)] + [TestCase(15, 10, 10, 1ul, -1)] + [TestCase(2, 3, 20, 0ul, 1)] // head block number after eip 1559 transition - [TestCase(10, 10, 16, 5, 0)] - [TestCase(15, 10, 11, 6, -1)] - [TestCase(2, 3, 33, 7, 1)] - public void GasPriceComparer_for_legacy_transactions_1559(int gasPriceX, int gasPriceY, int headBaseFee, long headBlockNumber, int expectedResult) + [TestCase(10, 10, 16, 5ul, 0)] + [TestCase(15, 10, 11, 6ul, -1)] + [TestCase(2, 3, 33, 7ul, 1)] + public void GasPriceComparer_for_legacy_transactions_1559(int gasPriceX, int gasPriceY, int headBaseFee, ulong headBlockNumber, int expectedResult) { - long eip1559Transition = 5; + ulong eip1559Transition = 5; TestingContext context = new TestingContext(true, eip1559Transition) .WithHeadBaseFeeNumber((UInt256)headBaseFee) .WithHeadBlockNumber(headBlockNumber); @@ -60,16 +60,16 @@ public void GasPriceComparer_for_legacy_transactions_1559(int gasPriceX, int gas [MaxTime(Timeout.MaxTestTime)] // head block number before eip 1559 transition - [TestCase(10, 10, 0, 0, 0)] - [TestCase(15, 10, 10, 1, -1)] - [TestCase(2, 3, 20, 0, 1)] + [TestCase(10, 10, 0, 0ul, 0)] + [TestCase(15, 10, 10, 1ul, -1)] + [TestCase(2, 3, 20, 0ul, 1)] // head block number after eip 1559 transition - [TestCase(10, 10, 16, 5, 0)] - [TestCase(15, 10, 11, 6, -1)] - [TestCase(2, 3, 33, 7, 1)] - public void ProducerGasPriceComparer_for_legacy_transactions_1559(int gasPriceX, int gasPriceY, int headBaseFee, long headBlockNumber, int expectedResult) + [TestCase(10, 10, 16, 5ul, 0)] + [TestCase(15, 10, 11, 6ul, -1)] + [TestCase(2, 3, 33, 7ul, 1)] + public void ProducerGasPriceComparer_for_legacy_transactions_1559(int gasPriceX, int gasPriceY, int headBaseFee, ulong headBlockNumber, int expectedResult) { - long eip1559Transition = 5; + ulong eip1559Transition = 5; TestingContext context = new(true, eip1559Transition); IComparer comparer = context.GetProducerComparer(new BlockPreparationContext(0, 0)); AssertLegacyTransactions(comparer, gasPriceX, gasPriceY, expectedResult); @@ -86,15 +86,15 @@ private void AssertLegacyTransactions(IComparer comparer, int gasPr } [MaxTime(Timeout.MaxTestTime)] - [TestCase(10, 5, 12, 4, 4, 6, -1)] - [TestCase(10, 5, 12, 4, 10, 6, 1)] - [TestCase(10, 4, 12, 4, 4, 6, 1)] - [TestCase(12, 4, 12, 4, 4, 6, 0)] - [TestCase(10, 5, 12, 4, 4, 3, -1)] - [TestCase(10, 5, 12, 4, 10, 3, -1)] - public void GasPriceComparer_for_eip1559_transactions(int feeCapX, int gasPremiumX, int feeCapY, int gasPremiumY, int headBaseFee, long headBlockNumber, int expectedResult) + [TestCase(10, 5, 12, 4, 4, 6ul, -1)] + [TestCase(10, 5, 12, 4, 10, 6ul, 1)] + [TestCase(10, 4, 12, 4, 4, 6ul, 1)] + [TestCase(12, 4, 12, 4, 4, 6ul, 0)] + [TestCase(10, 5, 12, 4, 4, 3ul, -1)] + [TestCase(10, 5, 12, 4, 10, 3ul, -1)] + public void GasPriceComparer_for_eip1559_transactions(int feeCapX, int gasPremiumX, int feeCapY, int gasPremiumY, int headBaseFee, ulong headBlockNumber, int expectedResult) { - long eip1559Transition = 5; + ulong eip1559Transition = 5; TestingContext context = new TestingContext(true, eip1559Transition) .WithHeadBaseFeeNumber((UInt256)headBaseFee) .WithHeadBlockNumber(headBlockNumber); @@ -108,10 +108,10 @@ public void GasPriceComparer_for_eip1559_transactions(int feeCapX, int gasPremiu [TestCase(4, 3, 0, 0, 0)] public void GasPriceComparer_use_gas_bottleneck_when_it_is_not_null(int gasPriceX, int gasPriceY, int gasBottleneckX, int gasBottleneckY, int expectedResult) { - long eip1559Transition = long.MaxValue; + ulong eip1559Transition = ulong.MaxValue; TestingContext context = new TestingContext(false, eip1559Transition) .WithHeadBaseFeeNumber((UInt256)0) - .WithHeadBlockNumber(1); + .WithHeadBlockNumber(1ul); IComparer comparer = context.DefaultComparer; Transaction x = Build.A.Transaction.WithSenderAddress(TestItem.AddressA) .WithGasPrice((UInt256)gasPriceX).WithGasBottleneck((UInt256)gasBottleneckX).TestObject; @@ -122,15 +122,15 @@ public void GasPriceComparer_use_gas_bottleneck_when_it_is_not_null(int gasPrice } [MaxTime(Timeout.MaxTestTime)] - [TestCase(10, 5, 12, 4, 4, 6, -1)] - [TestCase(10, 5, 12, 4, 10, 6, 1)] - [TestCase(10, 4, 12, 4, 4, 6, 1)] - [TestCase(12, 4, 12, 4, 4, 6, 0)] - [TestCase(10, 5, 12, 4, 4, 3, -1)] - [TestCase(10, 5, 12, 4, 10, 3, -1)] - public void ProducerGasPriceComparer_for_eip1559_transactions_1559(int feeCapX, int gasPremiumX, int feeCapY, int gasPremiumY, int headBaseFee, long headBlockNumber, int expectedResult) + [TestCase(10, 5, 12, 4, 4, 6ul, -1)] + [TestCase(10, 5, 12, 4, 10, 6ul, 1)] + [TestCase(10, 4, 12, 4, 4, 6ul, 1)] + [TestCase(12, 4, 12, 4, 4, 6ul, 0)] + [TestCase(10, 5, 12, 4, 4, 3ul, -1)] + [TestCase(10, 5, 12, 4, 10, 3ul, -1)] + public void ProducerGasPriceComparer_for_eip1559_transactions_1559(int feeCapX, int gasPremiumX, int feeCapY, int gasPremiumY, int headBaseFee, ulong headBlockNumber, int expectedResult) { - long eip1559Transition = 5; + ulong eip1559Transition = 5; TestingContext context = new(true, eip1559Transition); IComparer comparer = context.GetProducerComparer(new BlockPreparationContext((UInt256)headBaseFee, headBlockNumber)); Assert1559Transactions(comparer, feeCapX, gasPremiumX, feeCapY, gasPremiumY, expectedResult); @@ -152,10 +152,10 @@ private class TestingContext { private readonly IBlockTree _blockTree; private readonly ITransactionComparerProvider _transactionComparerProvider; - private long _blockNumber; + private ulong _blockNumber; private UInt256 _baseFee; - public TestingContext(bool isEip1559Enabled = false, long eip1559TransitionBlock = 0) + public TestingContext(bool isEip1559Enabled = false, ulong eip1559TransitionBlock = 0) { ReleaseSpec releaseSpec = new(); ReleaseSpec eip1559ReleaseSpec = new() { IsEip1559Enabled = isEip1559Enabled, Eip1559TransitionBlock = eip1559TransitionBlock }; @@ -173,7 +173,7 @@ public TestingContext(bool isEip1559Enabled = false, long eip1559TransitionBlock public IComparer GetProducerComparer(BlockPreparationContext blockPreparationContext) => _transactionComparerProvider.GetDefaultProducerComparer(blockPreparationContext); - public TestingContext WithHeadBlockNumber(long headBlockNumber) + public TestingContext WithHeadBlockNumber(ulong headBlockNumber) { _blockNumber = headBlockNumber; UpdateBlockTreeHead(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs index fa275631e9fc..c38aad16bfbb 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs @@ -67,7 +67,7 @@ public enum AuthorityPreState public static IEnumerable Eip8037AuthRefundCases() { - yield return new TestCaseData(AuthorityPreState.Nonexistent, false, 0UL, 0L) + yield return new TestCaseData(AuthorityPreState.Nonexistent, false, 0UL, 0UL) .SetName("Nonexistent authority - no auth state refund"); yield return new TestCaseData(AuthorityPreState.Nonexistent, true, 0UL, GasCostOf.PerAuthBaseState) .SetName("Nonexistent authority clear - refunds auth-base state gas"); @@ -86,7 +86,7 @@ public void Execute_Eip8037AuthRefunds_UpdateReceiptAndBlockGas( AuthorityPreState authorityPreState, bool clearDelegation, ulong authorityNonce, - long expectedStateGasRefund) + ulong expectedStateGasRefund) { UseSpec(Amsterdam.Instance); @@ -112,8 +112,8 @@ public void Execute_Eip8037AuthRefunds_UpdateReceiptAndBlockGas( _stateProvider.InsertCode(authority.Address, ValueKeccak.Compute(delegation), delegation, Amsterdam.Instance); } - long intrinsicRegularGas = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular; - long intrinsicStateGas = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; + ulong intrinsicRegularGas = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular; + ulong intrinsicStateGas = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; Transaction tx = Build.A.Transaction .WithType(TxType.SetCode) .WithTo(newDelegation) @@ -121,7 +121,7 @@ public void Execute_Eip8037AuthRefunds_UpdateReceiptAndBlockGas( .WithAuthorizationCode(_ethereumEcdsa.Sign(authority, _specProvider.ChainId, authTarget, authorityNonce)) .SignedAndResolved(_ethereumEcdsa, sender, true) .TestObject; - Block block = Build.A.Block.WithNumber(long.MaxValue) + Block block = Build.A.Block.WithNumber(ulong.MaxValue) .WithTimestamp(MainnetSpecProvider.AmsterdamBlockTimestamp) .WithTransactions(tx) .WithGasLimit(Eip7825Constants.DefaultTxGasLimitCap + intrinsicStateGas) @@ -141,7 +141,7 @@ public void Execute_Eip8037AuthRefunds_UpdateReceiptAndBlockGas( Assert.That(tx.SpentGas, Is.EqualTo(intrinsicRegularGas + intrinsicStateGas - expectedStateGasRefund)); Assert.That(receiptsTracer.LastReceipt.GasUsedTotal, Is.EqualTo(intrinsicRegularGas + intrinsicStateGas - expectedStateGasRefund)); Assert.That(block.Header.GasUsed, Is.EqualTo(Math.Max(intrinsicRegularGas, intrinsicStateGas - expectedStateGasRefund))); - Assert.That(_stateProvider.GetNonce(authority.Address), Is.EqualTo((UInt256)(authorityNonce + 1))); + Assert.That(_stateProvider.GetNonce(authority.Address), Is.EqualTo(authorityNonce + 1)); byte[] expectedCode = clearDelegation ? [] @@ -345,7 +345,7 @@ public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int c Transaction tx = Build.A.Transaction .WithType(TxType.SetCode) .WithTo(signer.Address) - .WithGasLimit(GasCostOf.Transaction + GasCostOf.NewAccount * count) + .WithGasLimit(GasCostOf.Transaction + GasCostOf.NewAccount * (ulong)count) .WithAuthorizationCode(Enumerable.Range(0, count) .Select(i => _ethereumEcdsa.Sign( signer, @@ -354,7 +354,7 @@ public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int c 0)).ToArray()) .SignedAndResolved(_ethereumEcdsa, sender, true) .TestObject; - Block block = Build.A.Block.WithNumber(long.MaxValue) + Block block = Build.A.Block.WithNumber(ulong.MaxValue) .WithTimestamp(MainnetSpecProvider.PragueBlockTimestamp) .WithTransactions(tx) .WithGasLimit(100000000).TestObject; @@ -363,7 +363,7 @@ public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int c _transactionProcessor.Execute(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), tracer); - Assert.That(tracer.GasSpent, Is.EqualTo(GasCostOf.Transaction + GasCostOf.NewAccount * count)); + Assert.That(tracer.GasSpent, Is.EqualTo(GasCostOf.Transaction + GasCostOf.NewAccount * (ulong)count)); } public void Execute_TxHasDifferentAmount() @@ -750,15 +750,15 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.ColdAccountAccess + GasCostOf.VeryLow, true, - 100_000, + 100_000ul, false ).SetName("EXTCODESIZE delegated - cold access"); yield return new TestCaseData( extcodesizeCode, - 23602, + 23602ul, true, //Gas limit is set so it doesn't have enough for accessing the account - 23602, + 23602ul, true ).SetName("EXTCODESIZE delegated - out of gas"); yield return new TestCaseData( @@ -767,7 +767,7 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.ColdAccountAccess + GasCostOf.VeryLow, false, - 100_000, + 100_000ul, false ).SetName("EXTCODESIZE not delegated - cold access"); byte[] extcodecopyCode = @@ -785,7 +785,7 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.VeryLow + GasCostOf.Base * 3, true, - 100_000, + 100_000ul, false ).SetName("EXTCODECOPY delegated - cold access"); yield return new TestCaseData( @@ -795,7 +795,7 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.VeryLow + GasCostOf.Base * 3, false, - 100_000, + 100_000ul, false ).SetName("EXTCODECOPY not delegated - cold access"); byte[] extcodehashCode = @@ -809,7 +809,7 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.ColdAccountAccess + GasCostOf.VeryLow, true, - 100_000, + 100_000ul, false ).SetName("EXTCODEHASH delegated - cold access"); yield return new TestCaseData( @@ -818,7 +818,7 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.ColdAccountAccess + GasCostOf.VeryLow, false, - 100_000, + 100_000ul, false ).SetName("EXTCODEHASH not delegated - cold access"); byte[] callOpcode = @@ -834,20 +834,17 @@ public static IEnumerable AccountAccessGasCases() .Done; yield return new TestCaseData( callOpcode, - GasCostOf.Transaction - + GasCostOf.WarmStateRead - + GasCostOf.ColdAccountAccess - + GasCostOf.VeryLow * 7, + 34550ul, true, - 100_000, + 100_000ul, false ).SetName("CALL delegated - cold access"); yield return new TestCaseData( callOpcode, - 23621, + 23621ul, true, //Gas limit is set so it doesn't have enough for accessing the account - 23621, + 23621ul, true ).SetName("CALL delegated - out of gas"); yield return new TestCaseData( @@ -856,12 +853,12 @@ public static IEnumerable AccountAccessGasCases() + GasCostOf.ColdAccountAccess + GasCostOf.VeryLow * 7, false, - 100_000, + 100_000ul, false ).SetName("CALL not delegated - cold access"); } [TestCaseSource(nameof(AccountAccessGasCases))] - public void Execute_DifferentAccountAccessOpcodes_ChargesCorrectAccountAccessGas(byte[] code, long expectedGas, bool isDelegated, long gasLimit, bool shouldRunOutOfGas) + public void Execute_DifferentAccountAccessOpcodes_ChargesCorrectAccountAccessGas(byte[] code, ulong expectedGas, bool isDelegated, ulong gasLimit, bool shouldRunOutOfGas) { PrivateKey signer = TestItem.PrivateKeyA; PrivateKey sender = TestItem.PrivateKeyB; @@ -884,7 +881,7 @@ public void Execute_DifferentAccountAccessOpcodes_ChargesCorrectAccountAccessGas .WithGasLimit(gasLimit) .SignedAndResolved(_ethereumEcdsa, sender, true) .TestObject; - Block block = Build.A.Block.WithNumber(long.MaxValue) + Block block = Build.A.Block.WithNumber(ulong.MaxValue) .WithTimestamp(MainnetSpecProvider.PragueBlockTimestamp) .WithTransactions(tx) .WithGasLimit(10000000).TestObject; @@ -991,7 +988,7 @@ public void Execute_AuthorityAccountExistsOrNot_NonceIsIncrementedByOne(bool acc .WithGasLimit(10000000).TestObject; _ = _transactionProcessor.Execute(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); - Assert.That(_stateProvider.GetNonce(authority.Address), Is.EqualTo((UInt256)1)); + Assert.That(_stateProvider.GetNonce(authority.Address), Is.EqualTo(1ul)); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index c1fae6688f30..f21eb6dd559d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -78,7 +78,7 @@ public void Sets_state_root_on_receipts_before_eip658(bool withStateDiff, bool w { Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithGasLimit(100000).TestObject; - long blockNumber = eip155Enabled + ulong blockNumber = eip155Enabled ? MainnetSpecProvider.ByzantiumBlockNumber : MainnetSpecProvider.ByzantiumBlockNumber - 1; Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx).TestObject; @@ -147,7 +147,7 @@ public void Can_handle_quick_fail_on_not_enough_balance_on_intrinsic_gas() .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; - tx.Value = AccountBalance - 3 * GasCostOf.Transaction; + tx.Value = (ulong)(AccountBalance - 3 * GasCostOf.Transaction); Block block = Build.A.Block.WithNumber(MainnetSpecProvider.BerlinBlockNumber).WithTransactions(tx).TestObject; @@ -163,7 +163,7 @@ public void Can_handle_quick_fail_on_not_enough_balance_on_reserved_gas_payment( .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; - tx.Value = AccountBalance - GasCostOf.Transaction; + tx.Value = (ulong)(AccountBalance - GasCostOf.Transaction); Block block = Build.A.Block.WithNumber(MainnetSpecProvider.BerlinBlockNumber).WithTransactions(tx).TestObject; TransactionResult result = Execute(tx, block); @@ -196,13 +196,13 @@ public void Can_handle_quick_fail_on_above_block_gas_limit() [Test] public void Balance_is_not_changed_on_call_and_restore() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction .WithValue(AccountBalance - (UInt256)gasLimit) .WithGasPrice(1) .WithGasLimit(gasLimit) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(1ul).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; _transactionProcessor.CallAndRestore(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); @@ -212,14 +212,14 @@ public void Balance_is_not_changed_on_call_and_restore() [Test] public void Account_is_not_created_on_call_and_restore() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction .WithValue(0.Ether) .WithGasPrice(1) .WithGasLimit(gasLimit) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyD, eip155Enabled) .TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(1ul).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; Assert.That(_stateProvider.AccountExists(TestItem.PrivateKeyD.Address), Is.False); _transactionProcessor.CallAndRestore(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); @@ -229,20 +229,20 @@ public void Account_is_not_created_on_call_and_restore() [Test] public void Nonce_is_not_changed_on_call_and_restore() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithValue(1.Ether - (UInt256)gasLimit).WithGasPrice(1).WithGasLimit(gasLimit).TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(1ul).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; _transactionProcessor.CallAndRestore(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); - Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(UInt256.Zero)); + Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(0ul)); } [TestCase(true)] [TestCase(false)] public void Can_estimate_with_value(bool systemUser) { - long gasLimit = 100000; - Transaction tx = Build.A.Transaction.WithValue(UInt256.MaxValue).WithGasLimit(gasLimit) + ulong gasLimit = 100000ul; + Transaction tx = Build.A.Transaction.WithValue(ulong.MaxValue).WithGasLimit(gasLimit) .WithSenderAddress(systemUser ? Address.SystemUser : TestItem.AddressA).TestObject; Block block = Build.A.Block.WithParent(_baseBlock).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; @@ -255,14 +255,14 @@ public void Can_estimate_with_value(bool systemUser) } else { - Assert.That(tracer.GasSpent, Is.EqualTo(21000)); + Assert.That(tracer.GasSpent, Is.EqualTo(21000ul)); } } [TestCaseSource(nameof(EstimateWithHighTxValueTestCases))] - public long Should_not_estimate_tx_with_high_value(UInt256 txValue) + public ulong Should_not_estimate_tx_with_high_value(UInt256 txValue) { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction .WithValue(txValue) @@ -270,13 +270,13 @@ public long Should_not_estimate_tx_with_high_value(UInt256 txValue) .WithGasLimit(gasLimit) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(1ul).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; EstimateGasTracer tracer = new(); BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); if (txValue == AccountBalance) { @@ -311,12 +311,12 @@ public static IEnumerable EstimateWithHighTxValueTestCases yield return new TestCaseData(AccountBalance - GasCostOf.Transaction - gasLimit + 1) { TestName = "More than (account balance - tx cost)", ExpectedResult = GasCostOf.Transaction }; yield return new TestCaseData(AccountBalance) - { TestName = "Exactly account balance", ExpectedResult = (long)GasCostOf.Transaction }; + { TestName = "Exactly account balance", ExpectedResult = GasCostOf.Transaction }; yield return new TestCaseData(AccountBalance + 1) - { TestName = "More than account balance", ExpectedResult = 0L }; - yield return new TestCaseData(UInt256.MaxValue - gasLimit) - { TestName = "Max value possible", ExpectedResult = 0L }; + { TestName = "More than account balance", ExpectedResult = 0ul }; + yield return new TestCaseData((UInt256)ulong.MaxValue - gasLimit) + { TestName = "Max value possible", ExpectedResult = 0ul }; } } @@ -330,7 +330,7 @@ public void Should_reject_tx_with_high_max_fee_per_gas(ulong topDigit) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; - long blockNumber = MainnetSpecProvider.LondonBlockNumber; + ulong blockNumber = MainnetSpecProvider.LondonBlockNumber; Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx).TestObject; TransactionResult result = Execute(tx, block); Assert.That(result.TransactionExecuted, Is.False); @@ -339,7 +339,7 @@ public void Should_reject_tx_with_high_max_fee_per_gas(ulong topDigit) [TestCase] public void Can_estimate_simple() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithParent(_baseBlock).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; @@ -349,8 +349,8 @@ public void Can_estimate_simple() _transactionProcessor.CallAndRestore(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), tracer); - Assert.That(tracer.GasSpent, Is.EqualTo(21000)); - Assert.That(estimator.Estimate(tx, block.Header, tracer, out string? err, 0), Is.EqualTo(21000)); + Assert.That(tracer.GasSpent, Is.EqualTo(21000ul)); + Assert.That(estimator.Estimate(tx, block.Header, tracer, out string? err, 0), Is.EqualTo(21000ul)); Assert.That(err, Is.Null); } @@ -367,10 +367,10 @@ public void Can_estimate_with_refund() .Op(Instruction.STOP) .Done; - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(initByteCode).WithGasLimit(gasLimit).TestObject; - Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2ul * gasLimit).TestObject; EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, MuirGlacier.Instance); @@ -382,13 +382,13 @@ public void Can_estimate_with_refund() BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; + ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); IReleaseSpec releaseSpec = Berlin.Instance; - Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend - GasCostOf.SStoreNetMeteredEip2200 + 1)); - Assert.That(tracer.GasSpent, Is.EqualTo(54764L)); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(75465L)); + Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo((ulong)RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend - GasCostOf.SStoreNetMeteredEip2200 + 1ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(54788ul)); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + Assert.That(estimate, Is.EqualTo(75489ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -405,11 +405,11 @@ public void Can_estimate_with_destroy_refund_and_below_intrinsic_pre_berlin() .Call(contractAddress, 46179) .Op(Instruction.STOP).Done; - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(initByteCode).WithGasLimit(gasLimit).TestObject; - Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; - Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; + Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(byteCode).WithGasLimit(gasLimit).WithNonce(1ul).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2ul * gasLimit).TestObject; IReleaseSpec releaseSpec = MuirGlacier.Instance; EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, releaseSpec); @@ -422,18 +422,18 @@ public void Can_estimate_with_destroy_refund_and_below_intrinsic_pre_berlin() BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; + ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); - Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(24080)); - Assert.That(tracer.GasSpent, Is.EqualTo(35228L)); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(54225)); + Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(24080ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(35300ul)); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + Assert.That(estimate, Is.EqualTo(54297ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); } - private void ConfirmEnoughEstimate(Transaction tx, Block block, long estimate) + private void ConfirmEnoughEstimate(Transaction tx, Block block, ulong estimate) { BlockExecutionContext blkCtx = new(block.Header, _specProvider.GetSpec(block.Header)); @@ -456,10 +456,10 @@ public void Can_estimate_with_stipend() .Op(Instruction.STOP) .Done; - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(initByteCode).WithGasLimit(gasLimit).TestObject; - Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2ul * gasLimit).TestObject; IReleaseSpec releaseSpec = MuirGlacier.Instance; EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, releaseSpec); @@ -472,12 +472,12 @@ public void Can_estimate_with_stipend() BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; + ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); - Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(2300)); - Assert.That(tracer.GasSpent, Is.EqualTo(85669L)); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(87969L)); + Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(2300ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(85981ul)); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + Assert.That(estimate, Is.EqualTo(88281ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -497,10 +497,10 @@ public void Can_estimate_with_stipend_and_refund() .Op(Instruction.STOP) .Done; - long gasLimit = 200000; + ulong gasLimit = 200000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(initByteCode).WithGasLimit(gasLimit).TestObject; - Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2ul * gasLimit).TestObject; IReleaseSpec releaseSpec = _specProvider.GetSpec(block.Header); EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, releaseSpec); @@ -513,12 +513,12 @@ public void Can_estimate_with_stipend_and_refund() BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; + ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); - Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend)); - Assert.That(tracer.GasSpent, Is.EqualTo(87429L)); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(108130L)); + Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo((ulong)RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend)); + Assert.That(tracer.GasSpent, Is.EqualTo(87753ul)); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + Assert.That(estimate, Is.EqualTo(108454ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -535,11 +535,11 @@ public void Can_estimate_with_single_call() byte[] byteCode = Prepare.EvmCode .Call(contractAddress, 46179).Done; - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(initByteCode).WithGasLimit(gasLimit).TestObject; - Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; - Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; + Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithCode(byteCode).WithGasLimit(gasLimit).WithNonce(1ul).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2ul * gasLimit).TestObject; IReleaseSpec releaseSpec = _specProvider.GetSpec(block.Header); EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, releaseSpec); @@ -553,12 +553,12 @@ public void Can_estimate_with_single_call() BlocksConfig blocksConfig = new(); GasEstimator estimator = new(_transactionProcessor, _stateProvider, _specProvider, blocksConfig); - long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; + ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); - Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(1)); - Assert.That(tracer.GasSpent, Is.EqualTo(54224L)); - long estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(54224L)); + Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(1ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(54284ul)); + ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); + Assert.That(estimate, Is.EqualTo(54284ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -567,7 +567,7 @@ public void Can_estimate_with_single_call() [TestCase] public void Disables_Eip158_for_system_transactions() { - long blockNumber = MainnetSpecProvider.SpuriousDragonBlockNumber + 1; + ulong blockNumber = MainnetSpecProvider.SpuriousDragonBlockNumber + 1; _stateProvider.CreateAccount(TestItem.PrivateKeyA.Address, 0.Ether); IReleaseSpec spec = _specProvider.GetSpec((ForkActivation)blockNumber); @@ -587,7 +587,7 @@ public void Disables_Eip158_for_system_transactions() [TestCase] public void Balance_is_changed_on_buildup_and_restored() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled).WithValue(0).WithGasPrice(1).WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.ByzantiumBlockNumber).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; @@ -602,7 +602,7 @@ public void Balance_is_changed_on_buildup_and_restored() [TestCase] public void Account_is_not_created_on_buildup_and_restore() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction .WithValue(0.Ether) .WithGasPrice(1) @@ -622,7 +622,7 @@ public void Account_is_not_created_on_buildup_and_restore() [TestCase] public void Nonce_is_not_changed_on_buildup_and_restore() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx = Build.A.Transaction .WithValue(AccountBalance - (UInt256)gasLimit) .WithGasPrice(1) @@ -633,21 +633,21 @@ public void Nonce_is_not_changed_on_buildup_and_restore() Snapshot state = _stateProvider.TakeSnapshot(); _transactionProcessor.BuildUp(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); - Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo((UInt256)1)); + Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(1ul)); _stateProvider.Restore(state); - Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(UInt256.Zero)); + Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(0ul)); } [TestCase] public void State_changed_twice_in_buildup_should_have_correct_gas_cost() { - long gasLimit = 100000; + ulong gasLimit = 100000ul; Transaction tx1 = Build.A.Transaction .WithValue(0).WithGasPrice(1).WithGasLimit(GasCostOf.Transaction) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; Transaction tx2 = Build.A.Transaction - .WithValue(0).WithNonce(1).WithGasPrice(1).WithGasLimit(GasCostOf.Transaction) + .WithValue(0).WithNonce(1ul).WithGasPrice(1).WithGasLimit(GasCostOf.Transaction) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.ByzantiumBlockNumber).WithTransactions(tx1, tx2).WithGasLimit(gasLimit).TestObject; @@ -720,7 +720,7 @@ public void Warmup_does_not_modify_sender_nonce() .WithGasLimit(100000).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - UInt256 nonceBefore = _stateProvider.GetNonce(TestItem.AddressA); + ulong nonceBefore = _stateProvider.GetNonce(TestItem.AddressA); _transactionProcessor.Warmup(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), NullTxTracer.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs index aaa6966d8abf..ba1380713491 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs @@ -190,7 +190,7 @@ public static IEnumerable EnoughShardBlobTransactionsSelectedTestCases "Enough shard blob transactions and others selected"); ProperTransactionsSelectedTestCase higherPriorityTransactionsSelected = ProperTransactionsSelectedTestCase.Eip1559Default; - IDictionary accounts = higherPriorityTransactionsSelected.AccountStates; + IDictionary accounts = higherPriorityTransactionsSelected.AccountStates; accounts[TestItem.AddressA] = (1000, 0); accounts[TestItem.AddressB] = (1000, 0); accounts[TestItem.AddressC] = (1000, 0); @@ -231,7 +231,7 @@ private static Transaction CreateBlobTransaction(Address address, PrivateKey key => CreateBlobTransaction(address, key, maxFee, blobCount, nonce: 1); private static Transaction CreateBlobTransaction( - Address address, PrivateKey key, UInt256 maxFee, int blobCount, UInt256 nonce, uint priority = 1) => + Address address, PrivateKey key, UInt256 maxFee, int blobCount, ulong nonce, uint priority = 1) => Build.A.Transaction .WithSenderAddress(address) .WithShardBlobTxTypeAndFields(blobCount) @@ -255,7 +255,7 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce = 1; + ulong nonce = 1; AddTxs(txCount: 5, blobsPerTx: 5, account: 0, txs, ref nonce); AddTxs(txCount: 7, blobsPerTx: 1, account: 0, txs, ref nonce); @@ -269,7 +269,7 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce = 1; + ulong nonce = 1; AddTxs(txCount: 5, blobsPerTx: 5, account: 0, txs, ref nonce); AddTxs(txCount: 1, blobsPerTx: 2, account: 0, txs, ref nonce); AddTxs(txCount: 5, blobsPerTx: 1, account: 0, txs, ref nonce); @@ -284,7 +284,7 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce = 1; + ulong nonce = 1; AddTxs(txCount: 5, blobsPerTx: 5, account: 0, txs, ref nonce); nonce = 1; AddTxs(txCount: 5, blobsPerTx: 1, account: 1, txs, ref nonce); @@ -300,9 +300,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 5, blobsPerTx: 5, account: 0, txs, ref nonce0); - UInt256 nonce1 = 2; + ulong nonce1 = 2; AddTxs(txCount: 5, blobsPerTx: 3, account: 1, txs, ref nonce1); AddTxs(txCount: 5, blobsPerTx: 1, account: 0, txs, ref nonce0); @@ -316,9 +316,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 5, blobsPerTx: 4, account: 1, txs, ref nonce1); AddTxs(txCount: 3, blobsPerTx: 1, account: 0, txs, ref nonce0); @@ -333,9 +333,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 2, blobsPerTx: 2, account: 1, txs, ref nonce1, priority: 1); AddTxs(txCount: 3, blobsPerTx: 2, account: 0, txs, ref nonce0, priority: 1); @@ -349,9 +349,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 2, blobsPerTx: 2, account: 1, txs, ref nonce1, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 0, txs, ref nonce0, priority: 1); @@ -365,10 +365,10 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 2, blobsPerTx: 2, account: 1, txs, ref nonce1, priority: 1); blobTxs.Transactions = txs; @@ -381,9 +381,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 2, blobsPerTx: 2, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 1, txs, ref nonce1, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 1, txs, ref nonce1, priority: 1); @@ -397,9 +397,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 1, txs, ref nonce1, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 0, txs, ref nonce0, priority: 1); @@ -414,9 +414,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 1, txs, ref nonce1, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 1, txs, ref nonce1, priority: 1); @@ -429,9 +429,9 @@ public static IEnumerable BlobTransactionOrderingTestCases ProperTransactionsSelectedTestCase blobTxs = CreateTestCase(); List txs = []; - UInt256 nonce1 = 1; + ulong nonce1 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 1, txs, ref nonce1, priority: 1); - UInt256 nonce0 = 1; + ulong nonce0 = 1; AddTxs(txCount: 1, blobsPerTx: 5, account: 0, txs, ref nonce0, priority: 1); AddTxs(txCount: 3, blobsPerTx: 1, account: 0, txs, ref nonce0, priority: 1); @@ -444,7 +444,7 @@ public static IEnumerable BlobTransactionOrderingTestCases static ProperTransactionsSelectedTestCase CreateTestCase() { ProperTransactionsSelectedTestCase higherPriorityTransactionsSelected = ProperTransactionsSelectedTestCase.Eip1559Default; - IDictionary accounts = higherPriorityTransactionsSelected.AccountStates; + IDictionary accounts = higherPriorityTransactionsSelected.AccountStates; accounts[TestItem.AddressA] = (1000000, 0); accounts[TestItem.AddressB] = (1000000, 0); higherPriorityTransactionsSelected.ReleaseSpec = Cancun.Instance; @@ -452,7 +452,7 @@ static ProperTransactionsSelectedTestCase CreateTestCase() return higherPriorityTransactionsSelected; } - void AddTxs(int txCount, int blobsPerTx, int account, List txs, ref UInt256 nonce, int priority = -1) + void AddTxs(int txCount, int blobsPerTx, int account, List txs, ref ulong nonce, int priority = -1) { (Address address, PrivateKey key) eoa = accounts[account]; for (int i = 0; i < txCount; i++) @@ -514,11 +514,11 @@ Hash256 SetAccountStates(IEnumerable
missingAddresses) using IDisposable _ = stateProvider.BeginScope(IWorldState.PreGenesis); - foreach (KeyValuePair accountState in testCase.AccountStates + foreach (KeyValuePair accountState in testCase.AccountStates .Where(v => !missingAddressesSet.Contains(v.Key))) { stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); - for (int i = 0; i < accountState.Value.Nonce; i++) + for (ulong i = 0; i < accountState.Value.Nonce; i++) { stateProvider.IncrementNonce(accountState.Key); } @@ -585,11 +585,11 @@ Dictionary GroupTransactions(bool supportBlobs) => public class ProperTransactionsSelectedTestCase { - public IDictionary AccountStates { get; } = - new Dictionary(); + public IDictionary AccountStates { get; } = + new Dictionary(); public List Transactions { get; set; } = []; - public long GasLimit { get; set; } + public ulong GasLimit { get; set; } public List ExpectedSelectedTransactions { get; } = []; public UInt256 MinGasPriceForMining { get; set; } = 1; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs index 2da51f5b6b12..3c5d3add286d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs @@ -300,11 +300,11 @@ void SetAccountStates(IEnumerable
missingAddresses) { HashSet
missingAddressesSet = missingAddresses.ToHashSet(); - foreach (KeyValuePair accountState in testCase.AccountStates + foreach (KeyValuePair accountState in testCase.AccountStates .Where(v => !missingAddressesSet.Contains(v.Key))) { stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); - for (int i = 0; i < accountState.Value.Nonce; i++) + for (ulong i = 0; i < accountState.Value.Nonce; i++) { stateProvider.IncrementNonce(accountState.Key); } @@ -454,7 +454,7 @@ public class WorldStateStab() public new bool TryGetAccount(Address address, out AccountStruct account) { - account = new(UInt256.Zero, UInt256.MaxValue); + account = new(0ul, ulong.MaxValue); return true; } @@ -466,7 +466,7 @@ private sealed class TestReadOnlyStateProvider : IReadOnlyStateProvider public bool TryGetAccount(Address address, out AccountStruct account) { - account = new(UInt256.Zero, UInt256.MaxValue); + account = new(0ul, ulong.MaxValue); return true; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/BlockValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/BlockValidatorTests.cs index 90508c66f72c..7125869ee845 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/BlockValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/BlockValidatorTests.cs @@ -263,9 +263,9 @@ public void ValidateSuggestedBlock_SuggestedBlockIsInvalid_CorrectErrorIsSet(Blo Assert.That(error, Does.StartWith(expectedError)); } - [TestCase(30_000, true)] - [TestCase(29_999, false)] - public void ValidateSuggestedBlock_enforces_bal_item_gas_limit_boundary(long gasLimit, bool expectedValid) + [TestCase(30_000ul, true)] + [TestCase(29_999ul, false)] + public void ValidateSuggestedBlock_enforces_bal_item_gas_limit_boundary(ulong gasLimit, bool expectedValid) { BlockHeader parent = Build.A.BlockHeader.TestObject; ReadOnlyBlockAccessList bal = Build.A.BlockAccessList.WithPrecompileChanges(parent.Hash!, timestamp: 12).TestObject; @@ -300,7 +300,7 @@ public void ValidateSuggestedBlock_enforces_bal_index_bounds(uint index, bool ex .TestObject; Block suggestedBlock = Build.A.Block .WithParent(parent) - .WithGasLimit(10_000) + .WithGasLimit(10_000ul) .WithTransactions(2, Amsterdam.Instance) .WithBlobGasUsed(0) .WithWithdrawals([]) @@ -326,7 +326,7 @@ public void ValidateSuggestedBlock_rejects_bal_item_when_gas_limit_allows_no_ite .TestObject; Block suggestedBlock = Build.A.Block .WithParent(parent) - .WithGasLimit(0) + .WithGasLimit(0ul) .WithTransactions([]) .WithBlobGasUsed(0) .WithWithdrawals([]) @@ -339,9 +339,9 @@ public void ValidateSuggestedBlock_rejects_bal_item_when_gas_limit_allows_no_ite AssertValidation(false, isValid, error, "BlockAccessListGasLimitExceeded"); } - [TestCase(30_000, true)] - [TestCase(29_999, false)] - public void ValidateProcessedBlock_enforces_bal_item_gas_limit_boundary_for_rlp_imported_blocks(long gasLimit, bool expectedValid) + [TestCase(30_000ul, true)] + [TestCase(29_999ul, false)] + public void ValidateProcessedBlock_enforces_bal_item_gas_limit_boundary_for_rlp_imported_blocks(ulong gasLimit, bool expectedValid) { // Hive eels/consume-rlp feeds blocks via RLP, which leaves Block.BlockAccessList null // (BlockDecoder does not decode BAL). The pre-execution check in @@ -412,7 +412,7 @@ public void ValidateSuggestedBlock_rejects_bal_index_above_tx_count_plus_one(uin Block suggestedBlock = Build.A.Block .WithParent(parent) - .WithGasLimit(30_000_000) + .WithGasLimit(30_000_000ul) .WithBlobGasUsed(0) .WithWithdrawals([]) .WithBal(bal) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index 1f686e6ebc69..3ed8c6e410b7 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -81,7 +81,7 @@ public void Valid_when_valid() [TestCase(-1, true, TestName = "When_gas_limit_just_correct_high")] public void When_gas_limit_above_parent(int adjustment, bool expectedResult) { - _block.Header.GasLimit = _parentBlock.Header.GasLimit + (long)BigInteger.Divide(_parentBlock.Header.GasLimit, 1024) + adjustment; + _block.Header.GasLimit = (ulong)((long)_parentBlock.Header.GasLimit + (long)_parentBlock.Header.GasLimit / 1024 + adjustment); _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); @@ -93,7 +93,7 @@ public void When_gas_limit_above_parent(int adjustment, bool expectedResult) [TestCase(0, false, TestName = "When_gas_limit_is_just_too_low")] public void When_gas_limit_below_parent(int adjustment, bool expectedResult) { - _block.Header.GasLimit = _parentBlock.Header.GasLimit - (long)BigInteger.Divide(_parentBlock.Header.GasLimit, 1024) + adjustment; + _block.Header.GasLimit = (ulong)((long)_parentBlock.Header.GasLimit - (long)_parentBlock.Header.GasLimit / 1024 + adjustment); _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); @@ -189,21 +189,21 @@ public void Header_field_corruption_returns_false(Action corrupt) } [MaxTime(Timeout.MaxTestTime)] - [TestCase(10000000, 4, 20000000, true)] - [TestCase(10000000, 4, 20019530, true)] - [TestCase(10000000, 4, 20019531, false)] - [TestCase(10000000, 4, 19980470, true)] - [TestCase(10000000, 4, 19980469, false)] - [TestCase(20000000, 5, 20000000, true)] - [TestCase(20000000, 5, 20019530, true)] - [TestCase(20000000, 5, 20019531, false)] - [TestCase(20000000, 5, 19980470, true)] - [TestCase(20000000, 5, 19980469, false)] - [TestCase(40000000, 5, 40039061, true)] - [TestCase(40000000, 5, 40039062, false)] - [TestCase(40000000, 5, 39960939, true)] - [TestCase(40000000, 5, 39960938, false)] - public void When_gaslimit_is_on_london_fork(long parentGasLimit, long blockNumber, long gasLimit, bool expectedResult) + [TestCase(10000000ul, 4ul, 20000000ul, true)] + [TestCase(10000000ul, 4ul, 20019530ul, true)] + [TestCase(10000000ul, 4ul, 20019531ul, false)] + [TestCase(10000000ul, 4ul, 19980470ul, true)] + [TestCase(10000000ul, 4ul, 19980469ul, false)] + [TestCase(20000000ul, 5ul, 20000000ul, true)] + [TestCase(20000000ul, 5ul, 20019530ul, true)] + [TestCase(20000000ul, 5ul, 20019531ul, false)] + [TestCase(20000000ul, 5ul, 19980470ul, true)] + [TestCase(20000000ul, 5ul, 19980469ul, false)] + [TestCase(40000000ul, 5ul, 40039061ul, true)] + [TestCase(40000000ul, 5ul, 40039062ul, false)] + [TestCase(40000000ul, 5ul, 39960939ul, true)] + [TestCase(40000000ul, 5ul, 39960938ul, false)] + public void When_gaslimit_is_on_london_fork(ulong parentGasLimit, ulong blockNumber, ulong gasLimit, bool expectedResult) { OverridableReleaseSpec spec = new(London.Instance) { @@ -233,13 +233,13 @@ public void When_gas_limit_is_long_max_value() { _validator = new HeaderValidator(_blockTree, _ethash, _specProvider, new OneLoggerLogManager(new(_testLogger))); _parentBlock = Build.A.Block.WithDifficulty(1) - .WithGasLimit(long.MaxValue) + .WithGasLimit(ulong.MaxValue) .WithNumber(5) .TestObject; _block = Build.A.Block.WithParent(_parentBlock) .WithDifficulty(131072) .WithMixHash(new Hash256("0xd7db5fdd332d3a65d6ac9c4c530929369905734d3ef7a91e373e81d0f010b8e8")) - .WithGasLimit(long.MaxValue) + .WithGasLimit(ulong.MaxValue) .WithNumber(_parentBlock.Number + 1) .WithNonce(0).TestObject; _block.Header.Hash = _block.CalculateHash(); @@ -251,11 +251,11 @@ public void When_gas_limit_is_long_max_value() private static IEnumerable NegativeFieldCases() { - yield return new TestCaseData(new Action(b => b.Header.Number = -1)) + yield return new TestCaseData(new Action(b => b.Header.Number = unchecked((ulong)-1))) .SetName("When_block_number_is_negative"); - yield return new TestCaseData(new Action(b => b.Header.GasUsed = -1)) + yield return new TestCaseData(new Action(b => b.Header.GasUsed = unchecked((ulong)-1))) .SetName("When_gas_used_is_negative"); - yield return new TestCaseData(new Action(b => b.Header.GasLimit = -1)) + yield return new TestCaseData(new Action(b => b.Header.GasLimit = unchecked((ulong)-1))) .SetName("When_gas_limit_is_negative"); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/DbBlocksLoaderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/DbBlocksLoaderTests.cs index b0f8d2884e9c..58bb4282e823 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/DbBlocksLoaderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/DbBlocksLoaderTests.cs @@ -34,7 +34,7 @@ public async Task Can_load_blocks_from_db() MemDb headersDb = new(); BlockTree testTree = Build.A.BlockTree(genesisBlock).OfChainLength(chainLength).TestObject; - for (int i = 0; i < testTree.Head!.Number + 1; i++) + for (ulong i = 0ul; i < testTree.Head!.Number + 1ul; i++) { Block ithBlock = testTree.FindBlock(i, BlockTreeLookupOptions.None)!; blockStore.Insert(ithBlock); @@ -80,7 +80,7 @@ public async Task Can_load_blocks_from_db_odd() MemDb headersDb = new(); BlockTree testTree = Build.A.BlockTree(genesisBlock).OfChainLength(chainLength).TestObject; - for (int i = 0; i < testTree.Head!.Number + 1; i++) + for (ulong i = 0ul; i < testTree.Head!.Number + 1ul; i++) { Block ithBlock = testTree.FindBlock(i, BlockTreeLookupOptions.None)!; blockStore.Insert(ithBlock); @@ -170,7 +170,7 @@ public async Task Can_load_from_DB_when_there_is_an_invalid_block_in_DB_and_a_va DbBlocksLoader loader = new(tree2, LimboNoErrorLogger.Instance, null, 1); await tree2.Accept(loader, tokenSource.Token); - Assert.That(tree2.BestKnownNumber, Is.EqualTo(3L), "best known"); + Assert.That(tree2.BestKnownNumber, Is.EqualTo(3ul), "best known"); BlockTestAssertions.AssertBlockHeaderEquivalent(tree2.Head!.Header, block3B.Header); BlockTestAssertions.AssertBlockHeaderEquivalent(tree2.BestSuggestedHeader, block3B.Header); @@ -232,7 +232,7 @@ public async Task Can_load_from_DB_when_there_is_only_an_invalid_chain_in_DB() /* note the block tree historically loads one less block than it could */ - Assert.That(tree2.BestKnownNumber, Is.EqualTo(0L), "best known"); + Assert.That(tree2.BestKnownNumber, Is.EqualTo(0ul), "best known"); Assert.That(tree2.Head!.Hash, Is.EqualTo(block0.Hash), "head"); Assert.That(tree2.BestSuggestedHeader!.Hash, Is.EqualTo(block0.Hash), "suggested"); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs index e4d7b2eed5b7..e7f9c3c1c90a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs @@ -98,14 +98,14 @@ public async Task Suggesting_blocks_works_correctly_after_processor_restart(int TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev, testTimeout: Timeout.MaxTestTime * 4).Build(); await testRpc.BlockchainProcessor.StopAsync(); IBlockTree tree = testRpc.BlockTree; - long startingBlockNumber = tree.Head!.Number; + ulong startingBlockNumber = tree.Head!.Number; SuggestNumberOfBlocks(tree, suggestedBlocksAmount); await testRpc.RestartBlockchainProcessor(); Task waitTask = suggestedBlocksAmount != 0 - ? testRpc.WaitForNewHeadWhere(b => b.Number == startingBlockNumber + suggestedBlocksAmount) + ? testRpc.WaitForNewHeadWhere(b => b.Number == startingBlockNumber + (ulong)suggestedBlocksAmount) : Task.CompletedTask; // fixing after restart StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, testRpc.StateReader, LimboNoErrorLogger.Instance, 5); @@ -116,7 +116,7 @@ public async Task Suggesting_blocks_works_correctly_after_processor_restart(int // add a new block at the end await testRpc.AddBlock(); - Assert.That(tree.Head!.Number, Is.EqualTo(startingBlockNumber + suggestedBlocksAmount + 1)); + Assert.That(tree.Head!.Number, Is.EqualTo(startingBlockNumber + (ulong)suggestedBlocksAmount + 1ul)); } [MaxTime(Timeout.MaxTestTime)] @@ -206,7 +206,7 @@ public async Task When_head_block_is_followed_by_a_block_bodies_gap_it_should_de Assert.That(blockInfosDb.Get(4), Is.Null, "level 4"); Assert.That(blockInfosDb.Get(5), Is.Null, "level 5"); - Assert.That(tree.BestKnownNumber, Is.EqualTo(2L), "best known"); + Assert.That(tree.BestKnownNumber, Is.EqualTo(2ul), "best known"); BlockTestAssertions.AssertBlockHeaderEquivalent(tree.Head?.Header, block2.Header); BlockTestAssertions.AssertBlockHeaderEquivalent(tree.BestSuggestedHeader, block2.Header); } diff --git a/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs b/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs index 233cfb236dc6..7572e306f914 100644 --- a/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs +++ b/src/Nethermind/Nethermind.Blockchain/BeaconBlockRoot/BeaconBlockRootHandler.cs @@ -14,7 +14,7 @@ namespace Nethermind.Blockchain.BeaconBlockRoot; public class BeaconBlockRootHandler(ITransactionProcessor processor, IWorldState stateProvider) : IBeaconBlockRootHandler { - private const long GasLimit = 30_000_000L; + private const ulong GasLimit = 30_000_000UL; AccessList? IHasAccessList.GetAccessList(Block block, IReleaseSpec spec) => BeaconRootsAccessList(block, spec, includeStorageCells: true).accessList; @@ -64,12 +64,12 @@ public void StoreBeaconRoot(Block block, IReleaseSpec spec, ITxTracer tracer) BlockHeader? header = block.Header; Transaction transaction = new() { - Value = UInt256.Zero, + Value = 0, Data = header.ParentBeaconBlockRoot.Bytes.ToArray(), To = toAddress, SenderAddress = Address.SystemUser, GasLimit = GasLimit, - GasPrice = UInt256.Zero, + GasPrice = 0, AccessList = accessList }; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/BlockAccessListStore.cs b/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/BlockAccessListStore.cs index 9d623ec1680b..e611257e745d 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/BlockAccessListStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/BlockAccessListStore.cs @@ -24,7 +24,7 @@ public class BlockAccessListStore( private readonly BlockAccessListDecoder _balDecoder = decoder ?? new(); [SkipLocalsInit] - public void Insert(long blockNumber, Hash256 blockHash, ReadOnlyBlockAccessList bal) + public void Insert(ulong blockNumber, Hash256 blockHash, ReadOnlyBlockAccessList bal) { using NettyRlpStream rlpStream = _balDecoder.EncodeToNewNettyStream(bal); Span key = stackalloc byte[KeyLength]; @@ -33,7 +33,7 @@ public void Insert(long blockNumber, Hash256 blockHash, ReadOnlyBlockAccessList } [SkipLocalsInit] - public void Insert(long blockNumber, Hash256 blockHash, byte[] encodedBal) + public void Insert(ulong blockNumber, Hash256 blockHash, byte[] encodedBal) { Span key = stackalloc byte[KeyLength]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, key); @@ -41,7 +41,7 @@ public void Insert(long blockNumber, Hash256 blockHash, byte[] encodedBal) } [SkipLocalsInit] - public void Insert(long blockNumber, Hash256 blockHash, ReadOnlySpan encodedBal) + public void Insert(ulong blockNumber, Hash256 blockHash, ReadOnlySpan encodedBal) { Span key = stackalloc byte[KeyLength]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, key); @@ -49,7 +49,7 @@ public void Insert(long blockNumber, Hash256 blockHash, ReadOnlySpan encod } [SkipLocalsInit] - public MemoryManager? GetRlp(long blockNumber, Hash256 blockHash) + public MemoryManager? GetRlp(ulong blockNumber, Hash256 blockHash) { Span key = stackalloc byte[KeyLength]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, key); @@ -57,21 +57,21 @@ public void Insert(long blockNumber, Hash256 blockHash, ReadOnlySpan encod } [SkipLocalsInit] - public bool Exists(long blockNumber, Hash256 blockHash) + public bool Exists(ulong blockNumber, Hash256 blockHash) { Span key = stackalloc byte[KeyLength]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, key); return balDb.KeyExists(key); } - public ReadOnlyBlockAccessList? Get(long blockNumber, Hash256 blockHash) + public ReadOnlyBlockAccessList? Get(ulong blockNumber, Hash256 blockHash) { using MemoryManager? rlp = GetRlp(blockNumber, blockHash); return rlp is null ? null : _balDecoder.Decode(rlp.Memory.Span); } [SkipLocalsInit] - public void Delete(long blockNumber, Hash256 blockHash) + public void Delete(ulong blockNumber, Hash256 blockHash) { Span key = stackalloc byte[KeyLength]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, key); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/IBlockAccessListStore.cs b/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/IBlockAccessListStore.cs index 6280ca2796c2..8459b7418334 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/IBlockAccessListStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockAccessLists/IBlockAccessListStore.cs @@ -32,13 +32,13 @@ void InsertFromBlock(Block block) block.EncodedBlockAccessList = null; } - void Insert(long blockNumber, Hash256 blockHash, byte[] bal); - void Insert(long blockNumber, Hash256 blockHash, ReadOnlySpan bal); - void Insert(long blockNumber, Hash256 blockHash, ReadOnlyBlockAccessList bal); - MemoryManager? GetRlp(long blockNumber, Hash256 blockHash); - ReadOnlyBlockAccessList? Get(long blockNumber, Hash256 blockHash); - bool Exists(long blockNumber, Hash256 blockHash); - void Delete(long blockNumber, Hash256 blockHash); + void Insert(ulong blockNumber, Hash256 blockHash, byte[] bal); + void Insert(ulong blockNumber, Hash256 blockHash, ReadOnlySpan bal); + void Insert(ulong blockNumber, Hash256 blockHash, ReadOnlyBlockAccessList bal); + MemoryManager? GetRlp(ulong blockNumber, Hash256 blockHash); + ReadOnlyBlockAccessList? Get(ulong blockNumber, Hash256 blockHash); + bool Exists(ulong blockNumber, Hash256 blockHash); + void Delete(ulong blockNumber, Hash256 blockHash); [DoesNotReturn, StackTraceHidden] private static Hash256 ThrowMissingBlockHash(string paramName) => diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs index 1102c83812b1..ca6050177e7c 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs @@ -20,9 +20,9 @@ public async Task Accept(IBlockTreeVisitor visitor, CancellationToken cancellati try { - long levelNumber = visitor.StartLevelInclusive; - long blocksToVisit = visitor.EndLevelExclusive - visitor.StartLevelInclusive; - for (long i = 0; i < blocksToVisit; i++) + ulong levelNumber = visitor.StartLevelInclusive; + ulong blocksToVisit = visitor.EndLevelExclusive - visitor.StartLevelInclusive; + for (ulong i = 0; i < blocksToVisit; i++) { if (cancellationToken.IsCancellationRequested) { diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs index 791e1089eeb7..b5d8a8414a30 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs @@ -16,16 +16,16 @@ public void HealCanonicalChain(Hash256 startHash, long maxBlockDepth) using BatchWrite batch = _chainLevelInfoRepository.StartBatch(); - long repairedAbove = ClearStaleMarkersAbove(start.Number, batch); + long repairedAbove = ClearStaleMarkersAbove(start.Number, batch); // start.Number is ulong (BlockHeader) long repairedBelow = RepairMarkersBelow(start, maxBlockDepth, batch); if (Logger.IsInfo) Logger.Info($"Canonical chain heal complete: {repairedAbove + repairedBelow} level(s) repaired ({repairedAbove} stale above head cleared, {repairedBelow} incorrect markers fixed)."); } - private long ClearStaleMarkersAbove(long fromExclusive, BatchWrite batch) + private long ClearStaleMarkersAbove(ulong fromExclusive, BatchWrite batch) { long cleared = 0L; - for (long levelNumber = fromExclusive + 1; ; levelNumber++) + for (ulong levelNumber = fromExclusive + 1; ; levelNumber++) { ChainLevelInfo? level = LoadLevel(levelNumber); if (level is null) break; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs index be6ae86d0b8d..3647ace77c49 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs @@ -24,7 +24,7 @@ public void RecalculateTreeLevels() LoadForkChoiceInfo(); } - public static long? BinarySearchBlockNumber(long left, long right, Func isBlockFound, + public static ulong? BinarySearchBlockNumber(ulong left, ulong right, Func isBlockFound, BinarySearchDirection direction = BinarySearchDirection.Up, bool findBeacon = false) { if (left > right) @@ -32,10 +32,10 @@ public void RecalculateTreeLevels() return null; } - long? result = null; + ulong? result = null; while (left != right) { - long index = direction == BinarySearchDirection.Up + ulong index = direction == BinarySearchDirection.Up ? left + (right - left) / 2 : right - (right - left) / 2; if (isBlockFound(index, findBeacon)) @@ -75,7 +75,7 @@ private void AttemptToFixCorruptionByMovingHeadBackwards() { if (_tryToRecoverFromHeaderBelowBodyCorruption && BestSuggestedHeader is not null) { - long blockNumber = BestPersistedState ?? BestSuggestedHeader.Number; + ulong blockNumber = BestPersistedState ?? BestSuggestedHeader.Number; ChainLevelInfo chainLevelInfo = LoadLevel(blockNumber); BlockInfo? canonicalBlock = chainLevelInfo?.MainChainBlock; if (canonicalBlock is not null && canonicalBlock.WasProcessed) @@ -89,7 +89,7 @@ private void AttemptToFixCorruptionByMovingHeadBackwards() } } - private bool LevelExists(long blockNumber, bool findBeacon = false) + private bool LevelExists(ulong blockNumber, bool findBeacon = false) { ChainLevelInfo? level = LoadLevel(blockNumber); if (findBeacon) @@ -100,7 +100,7 @@ private bool LevelExists(long blockNumber, bool findBeacon = false) return level is not null && level.HasNonBeaconBlocks; } - private bool HeaderExists(long blockNumber, bool findBeacon = false) + private bool HeaderExists(ulong blockNumber, bool findBeacon = false) { ChainLevelInfo level = LoadLevel(blockNumber); if (level is null) @@ -128,7 +128,7 @@ private bool HeaderExists(long blockNumber, bool findBeacon = false) return false; } - private bool BodyExists(long blockNumber, bool findBeacon = false) + private bool BodyExists(ulong blockNumber, bool findBeacon = false) { ChainLevelInfo level = LoadLevel(blockNumber); if (level is null) @@ -183,8 +183,8 @@ private void LoadLowestInsertedHeader() else { // Old style binary search. - long left = 1L; - long right = SyncPivot.BlockNumber; + ulong left = 1UL; + ulong right = SyncPivot.BlockNumber; LowestInsertedHeader = BinarySearchBlockHeader(left, right, LevelExists, BinarySearchDirection.Down); } @@ -194,15 +194,16 @@ private void LoadLowestInsertedHeader() private void LoadBestKnown() { - long left = (Head?.Number ?? 0) == 0 - ? Math.Max(SyncPivot.BlockNumber, LowestInsertedHeader?.Number ?? 0) - 1 + ulong pivotOrLowest = Math.Max(SyncPivot.BlockNumber, LowestInsertedHeader?.Number ?? 0); + ulong left = (Head?.Number ?? 0) == 0 + ? (pivotOrLowest > 0 ? pivotOrLowest - 1 : 0) : Head.Number; - long right = Math.Max(0, left) + BestKnownSearchLimit; + ulong right = left + BestKnownSearchLimit; - long bestKnownNumberFound = BinarySearchBlockNumber(left, right, LevelExists) ?? 0; - long bestSuggestedHeaderNumber = BinarySearchBlockNumber(left, right, HeaderExists) ?? 0; - long bestSuggestedBodyNumber = BinarySearchBlockNumber(left, right, BodyExists) ?? 0; + ulong bestKnownNumberFound = BinarySearchBlockNumber(left, right, LevelExists) ?? 0; + ulong bestSuggestedHeaderNumber = BinarySearchBlockNumber(left, right, HeaderExists) ?? 0; + ulong bestSuggestedBodyNumber = BinarySearchBlockNumber(left, right, BodyExists) ?? 0; if (Logger.IsInfo) Logger.Info("Numbers resolved, " + @@ -210,26 +211,13 @@ private void LoadBestKnown() $"header = {bestSuggestedHeaderNumber}, " + $"body = {bestSuggestedBodyNumber}"); - if (bestKnownNumberFound < 0 || - bestSuggestedHeaderNumber < 0 || - bestSuggestedBodyNumber < 0 || - bestSuggestedHeaderNumber < bestSuggestedBodyNumber) + if (bestSuggestedHeaderNumber < bestSuggestedBodyNumber) { if (Logger.IsWarn) Logger.Warn( $"Detected corrupted block tree data ({bestSuggestedHeaderNumber} < {bestSuggestedBodyNumber}) (possibly due to an unexpected shutdown). Attempting to fix by moving head backwards. This may fail and you may need to resync the node."); - if (bestSuggestedHeaderNumber < bestSuggestedBodyNumber) - { - bestSuggestedBodyNumber = bestSuggestedHeaderNumber; - _tryToRecoverFromHeaderBelowBodyCorruption = true; - } - else - { - throw new InvalidDataException("Invalid initial block tree state loaded - " + - $"best known: {bestKnownNumberFound}|" + - $"best header: {bestSuggestedHeaderNumber}|" + - $"best body: {bestSuggestedBodyNumber}|"); - } + bestSuggestedBodyNumber = bestSuggestedHeaderNumber; + _tryToRecoverFromHeaderBelowBodyCorruption = true; } BestKnownNumber = bestKnownNumberFound; @@ -243,24 +231,23 @@ private void LoadBestKnown() private void LoadBeaconBestKnown() { - long left = Math.Max(Head?.Number ?? 0, LowestInsertedBeaconHeader?.Number ?? 0) - 1; - long right = Math.Max(0, left) + BestKnownSearchLimit; - long bestKnownNumberFound = BinarySearchBlockNumber(left, right, LevelExists, findBeacon: true) ?? 0; + ulong left = Math.Max(Head?.Number ?? 0, LowestInsertedBeaconHeader?.Number ?? 0); + left = left > 0 ? left - 1 : 0; + ulong right = left + BestKnownSearchLimit; + ulong bestKnownNumberFound = BinarySearchBlockNumber(left, right, LevelExists, findBeacon: true) ?? 0; - left = Math.Max( - Math.Max( - Head?.Number ?? 0, - LowestInsertedBeaconHeader?.Number ?? 0), - BestSuggestedHeader?.Number ?? 0 - ) - 1; + ulong maxHeadOrLowest = Math.Max(Head?.Number ?? 0, LowestInsertedBeaconHeader?.Number ?? 0); + left = Math.Max(maxHeadOrLowest, BestSuggestedHeader?.Number ?? 0); + left = left > 0 ? left - 1 : 0; - right = Math.Max(0, left) + BestKnownSearchLimit; - long bestBeaconHeaderNumber = BinarySearchBlockNumber(left, right, HeaderExists, findBeacon: true) ?? 0; + right = left + BestKnownSearchLimit; + ulong bestBeaconHeaderNumber = BinarySearchBlockNumber(left, right, HeaderExists, findBeacon: true) ?? 0; - long? beaconPivotNumber = _metadataDb.Get(MetadataDbKeys.BeaconSyncPivotNumber)?.AsRlpValueContext().DecodeLong(); - left = Math.Max(Head?.Number ?? 0, beaconPivotNumber ?? 0) - 1; - right = Math.Max(0, left) + BestKnownSearchLimit; - long bestBeaconBodyNumber = BinarySearchBlockNumber(left, right, BodyExists, findBeacon: true) ?? 0; + ulong? beaconPivotNumber = _metadataDb.Get(MetadataDbKeys.BeaconSyncPivotNumber)?.AsRlpValueContext().DecodeULong(); + left = Math.Max(Head?.Number ?? 0, beaconPivotNumber ?? 0); + left = left > 0 ? left - 1 : 0; + right = left + BestKnownSearchLimit; + ulong bestBeaconBodyNumber = BinarySearchBlockNumber(left, right, BodyExists, findBeacon: true) ?? 0; if (Logger.IsInfo) Logger.Info("Beacon Numbers resolved, " + @@ -268,26 +255,13 @@ private void LoadBeaconBestKnown() $"header = {bestBeaconHeaderNumber}, " + $"body = {bestBeaconBodyNumber}"); - if (bestKnownNumberFound < 0 || - bestBeaconHeaderNumber < 0 || - bestBeaconBodyNumber < 0 || - bestBeaconHeaderNumber < bestBeaconBodyNumber) + if (bestBeaconHeaderNumber < bestBeaconBodyNumber) { if (Logger.IsWarn) Logger.Warn( $"Detected corrupted block tree data ({bestBeaconHeaderNumber} < {bestBeaconBodyNumber}) (possibly due to an unexpected shutdown). Attempting to fix by moving head backwards. This may fail and you may need to resync the node."); - if (bestBeaconHeaderNumber < bestBeaconBodyNumber) - { - bestBeaconBodyNumber = bestBeaconHeaderNumber; - _tryToRecoverFromHeaderBelowBodyCorruption = true; - } - else - { - throw new InvalidDataException("Invalid initial block tree state loaded - " + - $"best known: {bestKnownNumberFound}|" + - $"best header: {bestBeaconHeaderNumber}|" + - $"best body: {bestBeaconBodyNumber}|"); - } + bestBeaconBodyNumber = bestBeaconHeaderNumber; + _tryToRecoverFromHeaderBelowBodyCorruption = true; } BestKnownBeaconNumber = bestKnownNumberFound; @@ -304,10 +278,10 @@ public enum BinarySearchDirection Down } - private BlockHeader? BinarySearchBlockHeader(long left, long right, Func isBlockFound, + private BlockHeader? BinarySearchBlockHeader(ulong left, ulong right, Func isBlockFound, BinarySearchDirection direction = BinarySearchDirection.Up) { - long? blockNumber = BinarySearchBlockNumber(left, right, isBlockFound, direction); + ulong? blockNumber = BinarySearchBlockNumber(left, right, isBlockFound, direction); if (blockNumber.HasValue) { ChainLevelInfo? level = LoadLevel(blockNumber.Value) ?? throw new InvalidDataException( @@ -323,8 +297,8 @@ private void LoadStartBlock() { Block? startBlock = null; byte[] persistedNumberData = _blockInfoDb.Get(StateHeadHashDbEntryAddress); - BestPersistedState = persistedNumberData is null ? null : new Rlp.ValueDecoderContext(persistedNumberData).DecodeLong(); - long? persistedNumber = BestPersistedState; + BestPersistedState = persistedNumberData is null ? null : new Rlp.ValueDecoderContext(persistedNumberData).DecodeULong(); + ulong? persistedNumber = BestPersistedState; if (persistedNumber is not null) { startBlock = FindBlock(persistedNumber.Value, BlockTreeLookupOptions.None); @@ -372,17 +346,17 @@ private void LoadSyncPivot() byte[]? pivotFromDb = _metadataDb.Get(MetadataDbKeys.UpdatedPivotData); if (pivotFromDb is null) { - _syncPivot = (_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); + _syncPivot = ((ulong)_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); return; } Rlp.ValueDecoderContext pivotStream = new(pivotFromDb!); - long updatedPivotBlockNumber = pivotStream.DecodeLong(); + ulong updatedPivotBlockNumber = pivotStream.DecodeULong(); Hash256 updatedPivotBlockHash = pivotStream.DecodeKeccak()!; if (updatedPivotBlockHash.IsZero) { - _syncPivot = (_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); + _syncPivot = ((ulong)_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); return; } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index e7d011f049fa..09d80bb788d2 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -90,11 +90,11 @@ public BlockHeader? LowestInsertedBeaconHeader private BlockHeader? _lowestInsertedBeaconHeader; - private long? _highestPersistedState; + private ulong? _highestPersistedState; - public long BestKnownNumber { get; private set; } + public ulong BestKnownNumber { get; private set; } - public long BestKnownBeaconNumber { get; private set; } + public ulong BestKnownBeaconNumber { get; private set; } public ulong NetworkId => SpecProvider.NetworkId; @@ -103,11 +103,11 @@ public BlockHeader? LowestInsertedBeaconHeader private int _canAcceptNewBlocksCounter; public bool CanAcceptNewBlocks => _canAcceptNewBlocksCounter == 0; - private long _oldestBlock; + private ulong _oldestBlock; private TaskCompletionSource? _taskCompletionSource; - private readonly long _genesisBlockNumber; + private readonly ulong _genesisBlockNumber; public BlockTree( IBlockStore? blockStore, @@ -121,7 +121,7 @@ public BlockTree( IBloomStorage? bloomStorage, ISyncConfig? syncConfig, ILogManager? logManager, - long genesisBlockNumber = 0) + ulong genesisBlockNumber = 0) { Logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _blockStore = blockStore ?? throw new ArgumentNullException(nameof(blockStore)); @@ -135,7 +135,7 @@ public BlockTree( _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); _chainLevelInfoRepository = chainLevelInfoRepository ?? throw new ArgumentNullException(nameof(chainLevelInfoRepository)); - _oldestBlock = syncConfig.AncientBodiesBarrierCalc; + _oldestBlock = (ulong)syncConfig.AncientBodiesBarrierCalc; _genesisBlockNumber = genesisBlockNumber; @@ -255,7 +255,7 @@ public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions he BestSuggestedBeaconHeader = header; } - if (header.Number < (LowestInsertedBeaconHeader?.Number ?? long.MaxValue)) + if (header.Number < (LowestInsertedBeaconHeader?.Number ?? ulong.MaxValue)) { if (Logger.IsTrace) Logger.Trace( @@ -296,7 +296,7 @@ public void BulkInsertHeader(IReadOnlyList headers, throw new InvalidOperationException("Cannot accept new blocks at the moment."); } - using ArrayPoolList<(long, Bloom)> bloomToStore = new(headers.Count); + using ArrayPoolList<(ulong, Bloom)> bloomToStore = new(headers.Count); foreach (BlockHeader? header in headers) { if (header.Hash is null) @@ -333,7 +333,7 @@ public void BulkInsertHeader(IReadOnlyList headers, bool isOnMainChain = (headerOptions & BlockTreeInsertHeaderOptions.NotOnMainChain) == 0; bool beaconInsert = (headerOptions & BlockTreeInsertHeaderOptions.BeaconHeaderMetadata) != 0; - using ArrayPoolListRef<(long, BlockInfo)> blockInfos = new(headers.Count); + using ArrayPoolListRef<(ulong, BlockInfo)> blockInfos = new(headers.Count); foreach (BlockHeader? header in headers) { @@ -363,7 +363,7 @@ public void BulkInsertHeader(IReadOnlyList headers, BestSuggestedBeaconHeader = header; } - if (header.Number < (LowestInsertedBeaconHeader?.Number ?? long.MaxValue)) + if (header.Number < (LowestInsertedBeaconHeader?.Number ?? ulong.MaxValue)) { if (Logger.IsTrace) Logger.Trace( @@ -555,17 +555,17 @@ public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options return Suggest(block, block.Header, options); } - public BlockHeader? FindHeader(long number, BlockTreeLookupOptions options) + public BlockHeader? FindHeader(ulong number, BlockTreeLookupOptions options) { Hash256 blockHash = GetBlockHashOnMainOrBestDifficultyHash(number); return blockHash is null ? null : FindHeader(blockHash, options, blockNumber: number); } - public Hash256? FindBlockHash(long blockNumber) => GetBlockHashOnMainOrBestDifficultyHash(blockNumber); + public Hash256? FindBlockHash(ulong blockNumber) => GetBlockHashOnMainOrBestDifficultyHash(blockNumber); - public bool HasBlock(long blockNumber, Hash256 blockHash) => _blockStore.HasBlock(blockNumber, blockHash); + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => _blockStore.HasBlock(blockNumber, blockHash); - public BlockHeader? FindHeader(Hash256? blockHash, BlockTreeLookupOptions options, long? blockNumber = null) + public BlockHeader? FindHeader(Hash256? blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) { if (blockHash is null || blockHash == Keccak.Zero) { @@ -634,7 +634,7 @@ public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options /// /// If level has a block on the main chain then returns the block info,otherwise null /// - public BlockInfo? FindCanonicalBlockInfo(long blockNumber) + public BlockInfo? FindCanonicalBlockInfo(ulong blockNumber) { ChainLevelInfo level = LoadLevel(blockNumber); if (level is null) @@ -652,7 +652,7 @@ public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options return null; } - public Hash256? FindHash(long number) => GetBlockHashOnMainOrBestDifficultyHash(number); + public Hash256? FindHash(ulong number) => GetBlockHashOnMainOrBestDifficultyHash(number); public IOwnedReadOnlyList FindHeaders(Hash256? blockHash, int numberOfBlocks, int skip, bool reverse) { @@ -716,7 +716,7 @@ as it does not require the step of resolving number -> hash */ } else { - BlockHeader endHeader = FindHeader(startHeader.Number + numberOfBlocks - 1, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + BlockHeader endHeader = FindHeader(startHeader.Number + (ulong)(numberOfBlocks - 1), BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (endHeader is not null) { return FindHeadersReversedFast(this, endHeader, numberOfBlocks); @@ -732,19 +732,19 @@ as it does not require the step of resolving number -> hash */ { result[responseIndex] = current; responseIndex++; - long nextNumber = startHeader.Number + directionMultiplier * (responseIndex * skip + responseIndex); + long nextNumber = (long)startHeader.Number + directionMultiplier * (responseIndex * skip + responseIndex); if (nextNumber < 0) { break; } - current = FindHeader(nextNumber, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + current = FindHeader((ulong)nextNumber, BlockTreeLookupOptions.TotalDifficultyNotNeeded); } while (current is not null && responseIndex < numberOfBlocks); return result; } - private Hash256? GetBlockHashOnMainOrBestDifficultyHash(long blockNumber) + private Hash256? GetBlockHashOnMainOrBestDifficultyHash(ulong blockNumber) { if (blockNumber < 0) { @@ -787,7 +787,7 @@ bool IsPostMerge(Block? block) => SpecProvider.TerminalTotalDifficulty is { } tt return bestHash; } - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) + public Block? FindBlock(ulong blockNumber, BlockTreeLookupOptions options) { Hash256 hash = GetBlockHashOnMainOrBestDifficultyHash(blockNumber); return FindBlock(hash, options, blockNumber: blockNumber); @@ -821,7 +821,7 @@ public void DeleteInvalidBlock(Block invalidBlock) } } - public void DeleteOldBlock(long blockNumber, Hash256 blockHash) + public void DeleteOldBlock(ulong blockNumber, Hash256 blockHash) => _blockStore.Delete(blockNumber, blockHash); private void DeleteBlocks(Hash256 deletePointer) @@ -839,7 +839,7 @@ private void DeleteBlocks(Hash256 deletePointer) return; } - long currentNumber = deleteHeader.Number; + ulong currentNumber = deleteHeader.Number; Hash256 currentHash = deleteHeader.Hash; Hash256? nextHash = null; ChainLevelInfo? nextLevel = null; @@ -873,7 +873,10 @@ private void DeleteBlocks(Hash256 deletePointer) if (shouldRemoveLevel) { - BestKnownNumber = Math.Min(BestKnownNumber, currentNumber - 1); + // Guard against underflow: currentNumber is ulong, so only subtract if > 0 + BestKnownNumber = currentNumber > 0 + ? Math.Min(BestKnownNumber, currentNumber - 1) + : 0; _chainLevelInfoRepository.Delete(currentNumber, batch); } else if (currentLevel is not null) @@ -934,7 +937,7 @@ public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) public BlockHeader? FindBestSuggestedHeader() => BestSuggestedHeader; - public bool WasProcessed(long number, Hash256 blockHash) + public bool WasProcessed(ulong number, Hash256 blockHash) { ChainLevelInfo? levelInfo = LoadLevel(number) ?? throw new InvalidOperationException($"Not able to find block {blockHash} from an unknown level {number}"); int? index = levelInfo.FindIndex(blockHash) ?? throw new InvalidOperationException($"Not able to find block {blockHash} index on the chain level"); @@ -1001,8 +1004,8 @@ public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, boo } #endif - long lastNumber = ascendingOrder ? blocks[^1].Number : blocks[0].Number; - long previousHeadNumber = Head?.Number ?? 0L; + ulong lastNumber = ascendingOrder ? blocks[^1].Number : blocks[0].Number; + ulong previousHeadNumber = Head?.Number ?? 0UL; using ArrayPoolListRef pendingEvents = new(blocks.Count); @@ -1010,9 +1013,9 @@ public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, boo { if (previousHeadNumber > lastNumber) { - for (long i = 0; i < previousHeadNumber - lastNumber; i++) + for (ulong i = 0; i < previousHeadNumber - lastNumber; i++) { - long levelNumber = previousHeadNumber - i; + ulong levelNumber = previousHeadNumber - i; ChainLevelInfo? level = LoadLevel(levelNumber); if (level is not null) @@ -1070,7 +1073,7 @@ private void TryUpdateSyncPivot() { BlockHeader? newPivotHeader = FinalizedHash is not null ? FindHeader(FinalizedHash, BlockTreeLookupOptions.RequireCanonical) - : FindHeader(Math.Max(0, (Head?.Number ?? 0) - Reorganization.MaxDepth), BlockTreeLookupOptions.RequireCanonical); + : FindHeader((Head?.Number ?? 0UL) > (ulong)Reorganization.MaxDepth ? (Head.Number - (ulong)Reorganization.MaxDepth) : 0UL, BlockTreeLookupOptions.RequireCanonical); if (newPivotHeader is null) { @@ -1078,7 +1081,7 @@ private void TryUpdateSyncPivot() return; } - long? bestPersisted = BestPersistedState; + ulong? bestPersisted = BestPersistedState; if (bestPersisted is null) { if (Logger.IsTrace) Logger.Trace("Did not update sync pivot because no best persisted state"); @@ -1094,18 +1097,18 @@ private void TryUpdateSyncPivot() if (SyncPivot.BlockNumber >= newPivotHeader.Number) return; - (long BlockNumber, Hash256 BlockHash) newSyncPivot = (newPivotHeader.Number, newPivotHeader.Hash); + (ulong BlockNumber, Hash256 BlockHash) newSyncPivot = (newPivotHeader.Number, newPivotHeader.Hash); SyncPivot = newSyncPivot; } - public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint) + public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint) { if (blockInfos is null || blockInfos.Count == 0) return; using BatchWrite batch = _chainLevelInfoRepository.StartBatch(); - for (long j = clearBeaconMainChainStartPoint; j > blockInfos[^1].BlockNumber; --j) + for (ulong j = clearBeaconMainChainStartPoint; j > blockInfos[^1].BlockNumber; --j) { ChainLevelInfo? level = LoadLevel(j); if (level is not null) @@ -1121,7 +1124,7 @@ public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long cle foreach (BlockInfo blockInfo in blockInfos) { - long levelNumber = blockInfo.BlockNumber; + ulong levelNumber = blockInfo.BlockNumber; ChainLevelInfo? level = LoadLevel(levelNumber); if (level is not null) { @@ -1142,8 +1145,8 @@ public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long cle } } - private (long BlockNumber, Hash256 BlockHash) _syncPivot; - public (long BlockNumber, Hash256 BlockHash) SyncPivot + private (ulong BlockNumber, Hash256 BlockHash) _syncPivot; + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get => _syncPivot; set @@ -1269,7 +1272,7 @@ protected virtual bool BestSuggestedImprovementRequirementsSatisfied(BlockHeader return preMergeImprovementRequirementSatisfied || terminalBlockRequirementSatisfied || postMergeImprovementRequirementSatisfied; } - public bool IsKnownBlock(long number, Hash256 blockHash) + public bool IsKnownBlock(ulong number, Hash256 blockHash) { if (number > BestKnownNumber) { @@ -1288,7 +1291,7 @@ public bool IsKnownBlock(long number, Hash256 blockHash) return !blockInfo.IsBeaconInfo; } - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) + public bool IsKnownBeaconBlock(ulong number, Hash256 blockHash) { if (number > BestKnownBeaconNumber) { @@ -1354,7 +1357,7 @@ private BlockEventArgs SetHeadBlock(Block block) return new BlockEventArgs(block); } - private ChainLevelInfo UpdateOrCreateLevel(long number, BlockInfo blockInfo, bool setAsMain = false) + private ChainLevelInfo UpdateOrCreateLevel(ulong number, BlockInfo blockInfo, bool setAsMain = false) { using BatchWrite? batch = _chainLevelInfoRepository.StartBatch(); @@ -1384,11 +1387,11 @@ private ChainLevelInfo UpdateOrCreateLevel(long number, BlockInfo blockInfo, boo return level; } - private void UpdateOrCreateLevel(in ArrayPoolListRef<(long number, BlockInfo blockInfo)> blockInfos, bool setAsMain = false) + private void UpdateOrCreateLevel(in ArrayPoolListRef<(ulong number, BlockInfo blockInfo)> blockInfos, bool setAsMain = false) { using BatchWrite? batch = _chainLevelInfoRepository.StartBatch(); - using ArrayPoolListRef blockNumbers = blockInfos.Select(b => b.number); + using ArrayPoolListRef blockNumbers = blockInfos.Select(b => b.number); // Yes, this is measurably faster using IOwnedReadOnlyList levels = _chainLevelInfoRepository.MultiLoadLevel(blockNumbers); @@ -1396,7 +1399,7 @@ private void UpdateOrCreateLevel(in ArrayPoolListRef<(long number, BlockInfo blo for (int i = 0; i < blockInfos.Count; i++) { - (long number, BlockInfo blockInfo) = blockInfos[i]; + (ulong number, BlockInfo blockInfo) = blockInfos[i]; if (!blockInfo.IsBeaconInfo && number > BestKnownNumber) { @@ -1423,15 +1426,15 @@ private void UpdateOrCreateLevel(in ArrayPoolListRef<(long number, BlockInfo blo } } - public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) => LoadInfo(number, blockHash, true); + public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(ulong number, Hash256 blockHash) => LoadInfo(number, blockHash, true); - private (BlockInfo? Info, ChainLevelInfo? Level) LoadInfo(long number, Hash256 blockHash, bool forceLoad) + private (BlockInfo? Info, ChainLevelInfo? Level) LoadInfo(ulong number, Hash256 blockHash, bool forceLoad) { ChainLevelInfo chainLevelInfo = LoadLevel(number, forceLoad); return chainLevelInfo is null ? (null, null) : (chainLevelInfo.FindBlockInfo(blockHash), chainLevelInfo); } - private ChainLevelInfo? LoadLevel(long number, bool forceLoad = true) => + private ChainLevelInfo? LoadLevel(ulong number, bool forceLoad = true) => number > Math.Max(BestKnownNumber, BestKnownBeaconNumber) && !forceLoad ? null : _chainLevelInfoRepository.LoadLevel(number); @@ -1441,10 +1444,10 @@ private void UpdateOrCreateLevel(in ArrayPoolListRef<(long number, BlockInfo blo /// /// /// - private bool ShouldCache(long number) => - number == _genesisBlockNumber || Head is null || number >= Head.Number - BlockStore.CacheSize; + private bool ShouldCache(ulong number) => + number == _genesisBlockNumber || Head is null || Head.Number < (ulong)BlockStore.CacheSize || number >= Head.Number - (ulong)BlockStore.CacheSize; - public ChainLevelInfo? FindLevel(long number) => _chainLevelInfoRepository.LoadLevel(number); + public ChainLevelInfo? FindLevel(ulong number) => _chainLevelInfoRepository.LoadLevel(number); public Hash256? HeadHash => Head?.Hash; public Hash256? GenesisHash => Genesis?.Hash; @@ -1452,7 +1455,7 @@ private bool ShouldCache(long number) => public Hash256? FinalizedHash { get; private set; } public Hash256? SafeHash { get; private set; } - public Block? FindBlock(Hash256? blockHash, BlockTreeLookupOptions options, long? blockNumber = null) + public Block? FindBlock(Hash256? blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) { if (blockHash is null || blockHash == Keccak.Zero) { @@ -1658,12 +1661,12 @@ void SetTotalDifficultyDeep(BlockHeader current) /// End level of the slice to delete /// Should it force of deletion of valid blocks /// Thrown when ot do not satisfy the slice position rules - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) + public int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false) { int deleted = 0; endNumber ??= BestKnownNumber; - if (endNumber - startNumber < 0) + if (endNumber < startNumber) { throw new ArgumentException("Start number must be equal or greater end number.", nameof(startNumber)); } @@ -1698,7 +1701,7 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo using (_chainLevelInfoRepository.StartBatch()) { - for (long i = endNumber.Value; i >= startNumber; i--) + for (ulong i = endNumber.Value; i >= startNumber; i--) { ChainLevelInfo? chainLevelInfo = _chainLevelInfoRepository.LoadLevel(i); if (chainLevelInfo is null) @@ -1751,7 +1754,7 @@ internal void ReleaseAcceptingNewBlocks() private Task WaitForReadinessToAcceptNewBlock => _taskCompletionSource?.Task ?? Task.CompletedTask; /// - public long? BestPersistedState + public ulong? BestPersistedState { get => _highestPersistedState; set @@ -1783,13 +1786,13 @@ public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockHas this, new( Head, - _headerStore.GetBlockNumber(safeBlockHash) ?? 0, - _headerStore.GetBlockNumber(FinalizedHash) ?? 0) + _headerStore.GetBlockNumber(safeBlockHash) ?? 0UL, + _headerStore.GetBlockNumber(FinalizedHash) ?? 0UL) ); } - public long GetLowestBlock() => _oldestBlock; + public ulong GetLowestBlock() => _oldestBlock; - public void NewOldestBlock(long oldestBlock) => _oldestBlock = oldestBlock; + public void NewOldestBlock(ulong oldestBlock) => _oldestBlock = oldestBlock; } } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeExtensions.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeExtensions.cs index a0f7a2165256..8ed85cb3624c 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeExtensions.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeExtensions.cs @@ -11,11 +11,11 @@ public static class BlockTreeExtensions public static BlockHeader? GetProducedBlockParent(this IBlockTree blockTree, BlockHeader? parentHeader) => parentHeader ?? blockTree.Head?.Header; - public static (bool isSyncing, long headNumber, long bestSuggested) IsSyncing(this IBlockTree blockTree, int maxDistanceForSynced = 0) + public static (bool isSyncing, ulong headNumber, ulong bestSuggested) IsSyncing(this IBlockTree blockTree, int maxDistanceForSynced = 0) { - long bestSuggestedNumber = blockTree.FindBestSuggestedHeader()?.Number ?? 0; - long headNumberOrZero = blockTree.Head?.Number ?? 0; - bool isSyncing = bestSuggestedNumber == 0 || bestSuggestedNumber > headNumberOrZero + maxDistanceForSynced; + ulong bestSuggestedNumber = blockTree.FindBestSuggestedHeader()?.Number ?? 0; + ulong headNumberOrZero = blockTree.Head?.Number ?? 0; + bool isSyncing = bestSuggestedNumber == 0 || bestSuggestedNumber > headNumberOrZero + (ulong)maxDistanceForSynced; return (isSyncing, headNumberOrZero, bestSuggestedNumber); } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs index e97dfd6e8eac..4c8e77d3ec1a 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs @@ -39,15 +39,15 @@ public BlockHeader? LowestInsertedBeaconHeader set => _overlayTree.LowestInsertedBeaconHeader = value; } - public long BestKnownNumber => Math.Max(_overlayTree.BestKnownNumber, _baseTree.BestKnownNumber); - public long BestKnownBeaconNumber => Math.Max(_overlayTree.BestKnownBeaconNumber, _baseTree.BestKnownBeaconNumber); + public ulong BestKnownNumber => Math.Max(_overlayTree.BestKnownNumber, _baseTree.BestKnownNumber); + public ulong BestKnownBeaconNumber => Math.Max(_overlayTree.BestKnownBeaconNumber, _baseTree.BestKnownBeaconNumber); public Hash256 HeadHash => _overlayTree.HeadHash ?? _baseTree.HeadHash; public Hash256 GenesisHash => _baseTree.GenesisHash; public Hash256? PendingHash => _overlayTree.PendingHash ?? _baseTree.PendingHash; public Hash256? FinalizedHash => _overlayTree.FinalizedHash ?? _baseTree.FinalizedHash; public Hash256? SafeHash => _overlayTree.SafeHash ?? _baseTree.SafeHash; public Block? Head => _overlayTree.Head ?? _baseTree.Head; - public long? BestPersistedState { get => _overlayTree.BestPersistedState; set => _overlayTree.BestPersistedState = value; } + public ulong? BestPersistedState { get => _overlayTree.BestPersistedState; set => _overlayTree.BestPersistedState = value; } public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) => _overlayTree.Insert(header, headerOptions); @@ -75,11 +75,11 @@ public ValueTask SuggestBlockAsync(Block block, public AddBlockResult SuggestHeader(BlockHeader header) => _overlayTree.SuggestHeader(header); - public bool IsKnownBlock(long number, Hash256 blockHash) => _overlayTree.IsKnownBlock(number, blockHash) || _baseTree.IsKnownBlock(number, blockHash); + public bool IsKnownBlock(ulong number, Hash256 blockHash) => _overlayTree.IsKnownBlock(number, blockHash) || _baseTree.IsKnownBlock(number, blockHash); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => _overlayTree.IsKnownBeaconBlock(number, blockHash) || _baseTree.IsKnownBeaconBlock(number, blockHash); + public bool IsKnownBeaconBlock(ulong number, Hash256 blockHash) => _overlayTree.IsKnownBeaconBlock(number, blockHash) || _baseTree.IsKnownBeaconBlock(number, blockHash); - public bool WasProcessed(long number, Hash256 blockHash) => _overlayTree.WasProcessed(number, blockHash) || _baseTree.WasProcessed(number, blockHash); + public bool WasProcessed(ulong number, Hash256 blockHash) => _overlayTree.WasProcessed(number, blockHash) || _baseTree.WasProcessed(number, blockHash); public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) => _overlayTree.UpdateMainChain(blocks, wereProcessed, forceHeadBlock); @@ -90,17 +90,17 @@ public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, boo public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) => _overlayTree.Accept(blockTreeVisitor, cancellationToken); - public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) + public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(ulong number, Hash256 blockHash) { (BlockInfo Info, ChainLevelInfo Level) overlayInfo = _overlayTree.GetInfo(number, blockHash); return overlayInfo.Info is not null || overlayInfo.Level is not null ? overlayInfo : _baseTree.GetInfo(number, blockHash); } - public ChainLevelInfo? FindLevel(long number) => _overlayTree.FindLevel(number) ?? _baseTree.FindLevel(number); + public ChainLevelInfo? FindLevel(ulong number) => _overlayTree.FindLevel(number) ?? _baseTree.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _overlayTree.FindCanonicalBlockInfo(blockNumber) ?? _baseTree.FindCanonicalBlockInfo(blockNumber); + public BlockInfo FindCanonicalBlockInfo(ulong blockNumber) => _overlayTree.FindCanonicalBlockInfo(blockNumber) ?? _baseTree.FindCanonicalBlockInfo(blockNumber); - public Hash256 FindHash(long blockNumber) => _overlayTree.FindHash(blockNumber) ?? _baseTree.FindHash(blockNumber); + public Hash256 FindHash(ulong blockNumber) => _overlayTree.FindHash(blockNumber) ?? _baseTree.FindHash(blockNumber); public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) { @@ -229,39 +229,39 @@ public event EventHandler OnForkChoiceUpda } } - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) => + public int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false) => _overlayTree.DeleteChainSlice(startNumber, endNumber, force); public bool IsBetterThanHead(BlockHeader? header) => _overlayTree.IsBetterThanHead(header) || _baseTree.IsBetterThanHead(header); - public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint) => + public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint) => _overlayTree.UpdateBeaconMainChain(blockInfos, clearBeaconMainChainStartPoint); public void RecalculateTreeLevels() => _overlayTree.RecalculateTreeLevels(); - public (long BlockNumber, Hash256 BlockHash) SyncPivot + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get => _baseTree.SyncPivot; set => _baseTree.SyncPivot = value; } public bool IsProcessingBlock { get => _baseTree.IsProcessingBlock; set => _baseTree.IsProcessingBlock = value; } - public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => _overlayTree.FindBlock(blockHash, options, blockNumber) ?? _baseTree.FindBlock(blockHash, options, blockNumber); - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => + public Block? FindBlock(ulong blockNumber, BlockTreeLookupOptions options) => _overlayTree.FindBlock(blockNumber, options) ?? _baseTree.FindBlock(blockNumber, options); - public bool HasBlock(long blockNumber, Hash256 blockHash) => + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => _overlayTree.HasBlock(blockNumber, blockHash) || _baseTree.HasBlock(blockNumber, blockHash); - public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => _overlayTree.FindHeader(blockHash, options, blockNumber) ?? _baseTree.FindHeader(blockHash, options, blockNumber); - public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) => + public BlockHeader? FindHeader(ulong blockNumber, BlockTreeLookupOptions options) => _overlayTree.FindHeader(blockNumber, options) ?? _baseTree.FindHeader(blockNumber, options); - public Hash256? FindBlockHash(long blockNumber) => + public Hash256? FindBlockHash(ulong blockNumber) => _overlayTree.FindBlockHash(blockNumber) ?? _baseTree.FindBlockHash(blockNumber); public bool IsMainChain(BlockHeader blockHeader) => @@ -274,10 +274,10 @@ public BlockHeader FindBestSuggestedHeader() => _overlayTree.FindBestSuggestedHeader() ?? _baseTree.FindBestSuggestedHeader(); - public long GetLowestBlock() => _baseTree.GetLowestBlock(); + public ulong GetLowestBlock() => _baseTree.GetLowestBlock(); - public void NewOldestBlock(long oldestBlock) => _baseTree.NewOldestBlock(oldestBlock); + public void NewOldestBlock(ulong oldestBlock) => _baseTree.NewOldestBlock(oldestBlock); - public void DeleteOldBlock(long blockNumber, Hash256 blockHash) + public void DeleteOldBlock(ulong blockNumber, Hash256 blockHash) => _baseTree.DeleteOldBlock(blockNumber, blockHash); } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs index 162b544be422..4cf4afcc5a16 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs @@ -14,12 +14,12 @@ namespace Nethermind.Blockchain; public class BlockTreeSuggestPacer : IDisposable { private TaskCompletionSource? _dbBatchProcessed; - private long _blockNumberReachedToUnlock = 0; - private readonly long _stopBatchSize; - private readonly long _resumeBatchSize; + private ulong _blockNumberReachedToUnlock = 0; + private readonly ulong _stopBatchSize; + private readonly ulong _resumeBatchSize; private readonly IBlockTree _blockTree; - public BlockTreeSuggestPacer(IBlockTree blockTree, long stopBatchSize = 4096, long resumeBatchSize = 2048) + public BlockTreeSuggestPacer(IBlockTree blockTree, ulong stopBatchSize = 4096, ulong resumeBatchSize = 2048) { blockTree.NewHeadBlock += BlockTreeOnNewHeadBlock; _blockTree = blockTree; @@ -37,9 +37,9 @@ private void BlockTreeOnNewHeadBlock(object sender, BlockEventArgs e) completionSource.SetResult(); } - public async Task WaitForQueue(long currentBlockNumber, CancellationToken token) + public async Task WaitForQueue(ulong currentBlockNumber, CancellationToken token) { - long currentHeadNumber = _blockTree.Head?.Number ?? 0; + ulong currentHeadNumber = _blockTree.Head?.Number ?? 0; if (currentBlockNumber - currentHeadNumber > _stopBatchSize && _dbBatchProcessed is null) { _blockNumberReachedToUnlock = currentBlockNumber - _stopBatchSize + _resumeBatchSize; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs index 1e20b54a2711..1afb5cafd73d 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs @@ -24,7 +24,7 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) private readonly LruCache _flatCache = new(32, nameof(BlockhashCache)); private readonly Lock _lock = new(); public const int MaxDepth = BlockhashProvider.MaxDepth; - private long _minBlock = int.MaxValue; + private ulong _minBlock = ulong.MaxValue; private Task _pruningTask = Task.CompletedTask; public Hash256? GetHash(BlockHeader headBlock, int depth) => @@ -51,7 +51,7 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) { if (!_blocks.TryGetValue(currentHash, out currentNode)) { - BlockHeader? currentHeader = i == 0 ? blockHeader : headerFinder.Get(currentHash, blockHeader.Number - i); + BlockHeader? currentHeader = i == 0 ? blockHeader : headerFinder.Get(currentHash, blockHeader.Number - (ulong)i); if (currentHeader is null) { break; @@ -189,10 +189,10 @@ private void PruneInBackground(BlockHeader blockHeader) bool ShouldPrune() => _minBlock + MaxDepth * 4 < blockHeader.Number && _pruningTask.IsCompleted; } - public int PruneBefore(long blockNumber) + public int PruneBefore(ulong blockNumber) { int removed = 0; - long minBlockNumber = long.MaxValue; + ulong minBlockNumber = ulong.MaxValue; Interlocked.Exchange(ref _minBlock, blockNumber); @@ -254,7 +254,7 @@ public Stats GetStats() private class CacheNode(BlockHeader blockHeader, CacheNode? parent = null) { public Hash256 Hash { get; } = blockHeader.Hash!; - public long Number { get; } = blockHeader.Number; + public ulong Number { get; } = blockHeader.Number; public Hash256 ParentHash { get; } = blockHeader.ParentHash!; public CacheNode? Parent { get; set; } = parent; } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index 4022a418e478..3d6ee1982e86 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -27,7 +27,7 @@ public class BlockhashProvider( private Hash256[]? _hashes; private long _prefetchVersion; - public Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) + public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) { if (number < 0) { @@ -39,7 +39,7 @@ public class BlockhashProvider( return _blockhashStore.GetBlockHashFromState(currentBlock, number, spec); } - long depth = currentBlock.Number - number; + long depth = (long)(currentBlock.Number - number); Hash256[]? hashes = Volatile.Read(ref _hashes); return depth switch @@ -53,7 +53,7 @@ public class BlockhashProvider( }; } - private Hash256? ReturnOutOfBounds(BlockHeader currentBlock, long number) + private Hash256? ReturnOutOfBounds(BlockHeader currentBlock, ulong number) { if (_logger.IsTrace) _logger.Trace($"BLOCKHASH opcode returning null for {currentBlock.Number} -> {number}"); return null; diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BadBlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BadBlockStore.cs index 58d4355636cc..20b25da53eba 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BadBlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BadBlockStore.cs @@ -46,5 +46,5 @@ private void TruncateToMaxSize() } } - private void Delete(long blockNumber, Hash256 blockHash) => blockDb.Delete(blockNumber, blockHash); + private void Delete(ulong blockNumber, Hash256 blockHash) => blockDb.Delete(blockNumber, blockHash); } diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs index 7da0fbbbff3d..4f8b05e8ea56 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs @@ -26,7 +26,7 @@ private readonly AssociativeCache public byte[]? GetMetadata(byte[] key) => _blockDb.Get(key); - public bool HasBlock(long blockNumber, Hash256 blockHash) + public bool HasBlock(ulong blockNumber, Hash256 blockHash) { Span dbKey = stackalloc byte[40]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, dbKey); @@ -47,21 +47,21 @@ public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) _blockDb.Set(block.Number, block.Hash, newRlp.AsSpan(), writeFlags); } - public void Delete(long blockNumber, Hash256 blockHash) + public void Delete(ulong blockNumber, Hash256 blockHash) { _blockCache.Delete(in blockHash.ValueHash256); _blockDb.Delete(blockNumber, blockHash); _blockDb.Remove(blockHash.Bytes); } - public Block? Get(long blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = false) + public Block? Get(ulong blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = false) { Block? b = _blockDb.Get(blockNumber, blockHash, _blockDecoder, _blockCache, rlpBehaviors, shouldCache); if (b is not null) return b; return _blockDb.Get(blockHash, _blockDecoder, _blockCache, rlpBehaviors, shouldCache); } - public byte[]? GetRlp(long blockNumber, Hash256 blockHash) + public byte[]? GetRlp(ulong blockNumber, Hash256 blockHash) { Span dbKey = stackalloc byte[40]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, dbKey); @@ -70,7 +70,7 @@ public void Delete(long blockNumber, Hash256 blockHash) return _blockDb.Get(blockHash); } - public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash) + public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(ulong blockNumber, Hash256 blockHash) { Span keyWithBlockNumber = stackalloc byte[40]; KeyValueStoreExtensions.GetBlockNumPrefixedKey(blockNumber, blockHash, keyWithBlockNumber); diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs index 68a52a5f276a..b9926ca759bd 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs @@ -26,14 +26,15 @@ public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spe if (!worldState.IsContract(eip2935Account)) return; Hash256 parentBlockHash = blockHeader.ParentHash; - UInt256 parentBlockIndex = new((ulong)((blockHeader.Number - 1) % spec.Eip2935RingBufferSize)); + UInt256 parentBlockIndex = new((blockHeader.Number - 1) % (ulong)spec.Eip2935RingBufferSize); StorageCell blockHashStoreCell = new(eip2935Account, parentBlockIndex); worldState.Set(blockHashStoreCell, parentBlockHash!.Bytes.WithoutLeadingZeros().ToArray()); } - public Hash256? GetBlockHashFromState(BlockHeader currentHeader, long requiredBlockNumber, IReleaseSpec spec) + public Hash256? GetBlockHashFromState(BlockHeader currentHeader, ulong requiredBlockNumber, IReleaseSpec spec) { - if (requiredBlockNumber >= currentHeader.Number || + if (requiredBlockNumber < 0 || + requiredBlockNumber >= currentHeader.Number || requiredBlockNumber + spec.Eip2935RingBufferSize < currentHeader.Number) { return null; diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs index eca635bc9d21..bad85ddd3bc7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs @@ -14,10 +14,10 @@ namespace Nethermind.Blockchain.Blocks; public interface IBlockStore { void Insert(Block block, WriteFlags writeFlags = WriteFlags.None); - void Delete(long blockNumber, Hash256 blockHash); - Block? Get(long blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true); - byte[]? GetRlp(long blockNumber, Hash256 blockHash); - ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash); + void Delete(ulong blockNumber, Hash256 blockHash); + Block? Get(ulong blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true); + byte[]? GetRlp(ulong blockNumber, Hash256 blockHash); + ReceiptRecoveryBlock? GetReceiptRecoveryBlock(ulong blockNumber, Hash256 blockHash); void Cache(Block block); - bool HasBlock(long blockNumber, Hash256 blockHash); + bool HasBlock(ulong blockNumber, Hash256 blockHash); } diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockhashStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockhashStore.cs index c26ad9b438e6..641c0c4a7117 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockhashStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockhashStore.cs @@ -10,5 +10,5 @@ namespace Nethermind.Blockchain.Blocks; public interface IBlockhashStore { public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spec); - public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, long requiredBlockNumber, IReleaseSpec spec); + public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, ulong requiredBlockNumber, IReleaseSpec spec); } diff --git a/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs b/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs index fd54740f0721..41d3acfa68b4 100644 --- a/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs @@ -40,9 +40,9 @@ public ChainHeadInfoProvider(IChainHeadSpecProvider specProvider, IBlockTree blo public IReadOnlyStateProvider ReadOnlyStateProvider { get; } - public long HeadNumber { get; private set; } + public ulong HeadNumber { get; private set; } - public long? BlockGasLimit { get; internal set; } + public ulong? BlockGasLimit { get; internal set; } public UInt256 CurrentBaseFee { get; private set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs index 1d97bfce6746..1388809bc0f3 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs @@ -22,12 +22,12 @@ namespace Nethermind.Blockchain.Contracts public abstract class CallableContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) : Contract(abiEncoder, contractAddress) { private readonly ITransactionProcessor _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor)); - public const long UnlimitedGas = long.MaxValue; + public const ulong UnlimitedGas = ulong.MaxValue; /// /// Gas limit used for generated system transactions. /// - public const long SystemTransactionGasLimit = 30_000_000L; + public const ulong SystemTransactionGasLimit = 30_000_000UL; private byte[] Call(BlockHeader header, string functionName, Transaction transaction) => CallCore(_transactionProcessor, header, functionName, transaction); @@ -51,7 +51,7 @@ protected object[] Call(BlockHeader header, string functionName, Address sender, /// Gas limit for generated transaction. /// Arguments to the function. /// Deserialized return value of the based on its definition. - protected object[] Call(BlockHeader header, string functionName, Address sender, long gasLimit, params object[] arguments) + protected object[] Call(BlockHeader header, string functionName, Address sender, ulong gasLimit, params object[] arguments) { AbiFunctionDescription function = AbiDefinition.GetFunction(functionName); Transaction transaction = GenerateTransaction(functionName, sender, gasLimit, header, arguments); @@ -99,7 +99,7 @@ protected bool TryCall(BlockHeader header, string functionName, Address sender, /// Deserialized return value of the based on its definition. /// Arguments to the function. /// true if function was otherwise false. - protected bool TryCall(BlockHeader header, string functionName, Address sender, long gasLimit, out object[] result, params object[] arguments) + protected bool TryCall(BlockHeader header, string functionName, Address sender, ulong gasLimit, out object[] result, params object[] arguments) { AbiFunctionDescription function = AbiDefinition.GetFunction(functionName); Transaction transaction = GenerateTransaction(functionName, sender, gasLimit, header, arguments); diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.ConstantContract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.ConstantContract.cs index 8c628ecabc2a..f42924762500 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.ConstantContract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.ConstantContract.cs @@ -10,7 +10,7 @@ namespace Nethermind.Blockchain.Contracts { public partial class Contract { - private const long DefaultConstantContractGasLimit = 50_000_000L; + private const ulong DefaultConstantContractGasLimit = 50_000_000UL; /// /// Gets constant version of the contract. Allowing to call contract methods without state modification. diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs index 4fbf22cf2c5b..52a767f95d7b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs @@ -31,7 +31,7 @@ public abstract partial class Contract /// /// Default gas limit of transactions generated from contract. /// - public const long DefaultContractGasLimit = 1_600_000L; + public const ulong DefaultContractGasLimit = 1_600_000UL; protected IAbiEncoder AbiEncoder { get; } public AbiDefinition AbiDefinition { get; } @@ -50,20 +50,20 @@ protected Contract(IAbiEncoder? abiEncoder = null, Address? contractAddress = nu AbiDefinition = abiDefinition ?? new AbiDefinitionParser().Parse(GetType()); } - protected virtual Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address sender, long gasLimit = DefaultContractGasLimit, BlockHeader header = null) + protected virtual Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address sender, ulong gasLimit = DefaultContractGasLimit, BlockHeader header = null) where T : Transaction, new() => GenerateTransaction(contractAddress, transactionData, sender, gasLimit); - protected Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address? sender, long gasLimit = DefaultContractGasLimit) where T : Transaction, new() + protected Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address? sender, ulong gasLimit = DefaultContractGasLimit) where T : Transaction, new() { T transaction = new() { - Value = UInt256.Zero, + Value = 0, Data = transactionData, To = (contractAddress ?? ContractAddress) ?? throw new ArgumentNullException(nameof(contractAddress)), SenderAddress = sender ?? Address.SystemUser, GasLimit = gasLimit, - GasPrice = UInt256.Zero, + GasPrice = 0, }; transaction.Hash = transaction.CalculateHash(); @@ -98,7 +98,7 @@ protected virtual Transaction GenerateTransaction(Address? contractAddress, b /// Arguments to the function. /// Type of . /// Transaction. - protected Transaction GenerateTransaction(Address? contractAddress, string functionName, Address sender, long gasLimit, BlockHeader header, params object[] arguments) where T : Transaction, new() + protected Transaction GenerateTransaction(Address? contractAddress, string functionName, Address sender, ulong gasLimit, BlockHeader header, params object[] arguments) where T : Transaction, new() => GenerateTransaction(contractAddress, AbiEncoder.Encode(AbiDefinition.GetFunction(functionName).GetCallInfo(), arguments), sender, gasLimit, header); /// @@ -113,7 +113,7 @@ protected virtual Transaction GenerateTransaction(Address? contractAddress, b /// Arguments to the function. /// Type of . /// Transaction. - protected Transaction GenerateTransaction(Address? contractAddress, string functionName, Address sender, long gasLimit, params object[] arguments) where T : Transaction, new() + protected Transaction GenerateTransaction(Address? contractAddress, string functionName, Address sender, ulong gasLimit, params object[] arguments) where T : Transaction, new() => GenerateTransaction(contractAddress, AbiEncoder.Encode(AbiDefinition.GetFunction(functionName).GetCallInfo(), arguments), sender, gasLimit); /// @@ -141,7 +141,7 @@ protected virtual Transaction GenerateTransaction(Address? contractAddress, b /// Arguments to the function. /// Type of . /// Transaction. - protected Transaction GenerateTransaction(string functionName, Address sender, long gasLimit, BlockHeader header, params object[] arguments) where T : Transaction, new() + protected Transaction GenerateTransaction(string functionName, Address sender, ulong gasLimit, BlockHeader header, params object[] arguments) where T : Transaction, new() => GenerateTransaction(ContractAddress, AbiEncoder.Encode(AbiDefinition.GetFunction(functionName).GetCallInfo(), arguments), sender, gasLimit, header); /// @@ -155,7 +155,7 @@ protected virtual Transaction GenerateTransaction(Address? contractAddress, b /// Arguments to the function. /// Type of . /// Transaction. - protected Transaction GenerateTransaction(string functionName, Address sender, long gasLimit, params object[] arguments) where T : Transaction, new() + protected Transaction GenerateTransaction(string functionName, Address sender, ulong gasLimit, params object[] arguments) where T : Transaction, new() => GenerateTransaction(ContractAddress, AbiEncoder.Encode(AbiDefinition.GetFunction(functionName).GetCallInfo(), arguments), sender, gasLimit); /// diff --git a/src/Nethermind/Nethermind.Blockchain/ExitOnBlockNumberHandler.cs b/src/Nethermind/Nethermind.Blockchain/ExitOnBlockNumberHandler.cs index add118f56c6e..10177779b802 100644 --- a/src/Nethermind/Nethermind.Blockchain/ExitOnBlockNumberHandler.cs +++ b/src/Nethermind/Nethermind.Blockchain/ExitOnBlockNumberHandler.cs @@ -14,7 +14,7 @@ public class ExitOnBlockNumberHandler public ExitOnBlockNumberHandler( IBlockTree blockTree, IProcessExitSource processExitSource, - long initConfigExitOnBlockNumber, + ulong initConfigExitOnBlockNumber, ILogManager logManager) { ILogger logger = logManager.GetClassLogger(); diff --git a/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs b/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs index 6439f1001ee8..9e2d00ea65a2 100644 --- a/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs +++ b/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs @@ -32,7 +32,7 @@ public class BlockParameter : IEquatable public static BlockParameter Safe = new(BlockParameterType.Safe); public BlockParameterType Type { get; } - public long? BlockNumber { get; } + public ulong? BlockNumber { get; } public Hash256? BlockHash { get; } @@ -40,7 +40,7 @@ public class BlockParameter : IEquatable public BlockParameter(BlockParameterType type) => Type = type; - public BlockParameter(long number) + public BlockParameter(ulong number) { RequireCanonical = true; Type = BlockParameterType.BlockNumber; @@ -146,7 +146,7 @@ public override void Write(Utf8JsonWriter writer, BlockParameter value, JsonSeri ReadStringFormatValueSequence(ref reader, options), JsonTokenType.StartObject => ReadObjectFormat(ref reader, typeToConvert, options), JsonTokenType.Null => BlockParameter.Latest, - JsonTokenType.Number when !EthereumJsonSerializer.StrictHexFormat => new BlockParameter(reader.GetInt64()), + JsonTokenType.Number when !EthereumJsonSerializer.StrictHexFormat => new BlockParameter(reader.GetUInt64()), _ => throw new FormatException("unknown block parameter type") }; @@ -255,12 +255,12 @@ private static BlockParameter ReadStringFormatOther(ReadOnlySpan span) } // Parse as block number - long value = ParseHexNumber(span); + ulong value = ParseHexNumber(span); return new BlockParameter(value); } // Try decimal format (if not strict) - if (!EthereumJsonSerializer.StrictHexFormat && Utf8Parser.TryParse(span, out long decimalValue, out _)) + if (!EthereumJsonSerializer.StrictHexFormat && Utf8Parser.TryParse(span, out ulong decimalValue, out _)) { return new BlockParameter(decimalValue); } @@ -270,14 +270,14 @@ private static BlockParameter ReadStringFormatOther(ReadOnlySpan span) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long ParseHexNumber(ReadOnlySpan span) + private static ulong ParseHexNumber(ReadOnlySpan span) { int oddMod = span.Length % 2; int length = (span.Length >> 1) + oddMod; - long value = 0; + ulong value = 0; Span output = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref value, 1)); - Bytes.FromUtf8HexString(span, output[(sizeof(long) - length)..]); + Bytes.FromUtf8HexString(span, output[(sizeof(ulong) - length)..]); return BitConverter.IsLittleEndian switch { @@ -300,7 +300,7 @@ not null when value.Equals("pending", StringComparison.OrdinalIgnoreCase) => Blo not null when value.Equals("finalized", StringComparison.OrdinalIgnoreCase) => BlockParameter.Finalized, not null when value.Equals("safe", StringComparison.OrdinalIgnoreCase) => BlockParameter.Safe, { Length: 66 } when value.StartsWith("0x") => new BlockParameter(new Hash256(value)), - _ => new BlockParameter(LongConverter.FromString(value)) + _ => new BlockParameter(ULongConverter.FromString(value)) }; } } diff --git a/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs b/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs index fdaf7e2474e8..7127d57ed925 100644 --- a/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs +++ b/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs @@ -21,18 +21,18 @@ public interface IBlockFinder Block? Head { get; } - Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null); + Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null); - Block? FindBlock(long blockNumber, BlockTreeLookupOptions options); + Block? FindBlock(ulong blockNumber, BlockTreeLookupOptions options); - bool HasBlock(long blockNumber, Hash256 blockHash); + bool HasBlock(ulong blockNumber, Hash256 blockHash); /// Find a header. blockNumber is optional, but specifying it can improve performance. - BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null); + BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null); - BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options); + BlockHeader? FindHeader(ulong blockNumber, BlockTreeLookupOptions options); - Hash256? FindBlockHash(long blockNumber); + Hash256? FindBlockHash(ulong blockNumber); /// /// Checks if the block is currently in the canonical chain @@ -49,9 +49,9 @@ public interface IBlockFinder /// True if part of the canonical chain, otherwise False bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true); - public Block? FindBlock(Hash256 blockHash, long? blockNumber = null) => FindBlock(blockHash, BlockTreeLookupOptions.None, blockNumber); + public Block? FindBlock(Hash256 blockHash, ulong? blockNumber = null) => FindBlock(blockHash, BlockTreeLookupOptions.None, blockNumber); - public Block? FindBlock(long blockNumber) => FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical); + public Block? FindBlock(ulong blockNumber) => FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical); public Block? FindGenesisBlock() => FindBlock(GenesisHash, BlockTreeLookupOptions.RequireCanonical); @@ -67,9 +67,9 @@ public interface IBlockFinder public Block? FindSafeBlock() => SafeHash is null ? null : FindBlock(SafeHash, BlockTreeLookupOptions.None); - public BlockHeader? FindHeader(Hash256 blockHash, long? blockNumber = null) => FindHeader(blockHash, BlockTreeLookupOptions.None, blockNumber: blockNumber); + public BlockHeader? FindHeader(Hash256 blockHash, ulong? blockNumber = null) => FindHeader(blockHash, BlockTreeLookupOptions.None, blockNumber: blockNumber); - public BlockHeader? FindHeader(long blockNumber) => FindHeader(blockNumber, BlockTreeLookupOptions.RequireCanonical); + public BlockHeader? FindHeader(ulong blockNumber) => FindHeader(blockNumber, BlockTreeLookupOptions.RequireCanonical); public BlockHeader FindGenesisHeader() => FindHeader(GenesisHash, BlockTreeLookupOptions.RequireCanonical) ?? throw new Exception("Genesis header could not be found"); @@ -142,11 +142,11 @@ public interface IBlockFinder }; } - public long GetLowestBlock(); + public ulong GetLowestBlock(); /// /// Highest state persisted /// - long? BestPersistedState { get; set; } + ulong? BestPersistedState { get; set; } } } diff --git a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs index b6b3f75b067a..89c29b68c2f2 100644 --- a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs +++ b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs @@ -142,7 +142,7 @@ protected virtual async Task RunFullPruning(CancellationToken cancellationToken) private async Task RunFullPruning(IPruningContext pruningContext, CancellationToken cancellationToken) { - long blockToWaitFor = 0; + ulong blockToWaitFor = 0; await WaitForMainChainChange((e) => { if (e.Blocks.Count == 0) return false; @@ -160,8 +160,8 @@ await WaitForMainChainChange((e) => return false; }, cancellationToken); - long stateToCopy = _blockTree.BestPersistedState.Value; - long blockToPruneAfter = stateToCopy + _pruningConfig.PruningBoundary; + ulong stateToCopy = _blockTree.BestPersistedState.Value; + ulong blockToPruneAfter = stateToCopy + (ulong)_pruningConfig.PruningBoundary; await WaitForMainChainChange((e) => { diff --git a/src/Nethermind/Nethermind.Blockchain/Headers/HeaderStore.cs b/src/Nethermind/Nethermind.Blockchain/Headers/HeaderStore.cs index 3de4ee63b37c..33f72648634e 100644 --- a/src/Nethermind/Nethermind.Blockchain/Headers/HeaderStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Headers/HeaderStore.cs @@ -51,7 +51,7 @@ public void BulkInsert(IReadOnlyList headers) } } - public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, long? blockNumber = null) + public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, ulong? blockNumber = null) { blockNumber ??= GetBlockNumberFromBlockNumberDb(blockHash); @@ -67,30 +67,30 @@ public void BulkInsert(IReadOnlyList headers) public void Delete(Hash256 blockHash) { - long? blockNumber = GetBlockNumberFromBlockNumberDb(blockHash); + ulong? blockNumber = GetBlockNumberFromBlockNumberDb(blockHash); if (blockNumber is not null) headerDb.Delete(blockNumber.Value, blockHash); blockNumberDb.Delete(blockHash); headerDb.Delete(blockHash); _headerCache.Delete(in blockHash.ValueHash256); } - public void InsertBlockNumber(Hash256 blockHash, long blockNumber) + public void InsertBlockNumber(Hash256 blockHash, ulong blockNumber) { Span blockNumberSpan = stackalloc byte[8]; blockNumber.WriteBigEndian(blockNumberSpan); blockNumberDb.Set(blockHash, blockNumberSpan); } - public long? GetBlockNumber(Hash256 blockHash) + public ulong? GetBlockNumber(Hash256 blockHash) { - long? blockNumber = GetBlockNumberFromBlockNumberDb(blockHash); + ulong? blockNumber = GetBlockNumberFromBlockNumberDb(blockHash); if (blockNumber is not null) return blockNumber.Value; // Probably still hash based return Get(blockHash)?.Number; } - private long? GetBlockNumberFromBlockNumberDb(Hash256 blockHash) + private ulong? GetBlockNumberFromBlockNumberDb(Hash256 blockHash) { Span numberSpan = blockNumberDb.GetSpan(blockHash); if (numberSpan.IsNullOrEmpty()) return null; @@ -101,7 +101,7 @@ public void InsertBlockNumber(Hash256 blockHash, long blockNumber) throw new InvalidDataException($"Unexpected number span length: {numberSpan.Length}"); } - return BinaryPrimitives.ReadInt64BigEndian(numberSpan); + return BinaryPrimitives.ReadUInt64BigEndian(numberSpan); } finally { @@ -109,7 +109,7 @@ public void InsertBlockNumber(Hash256 blockHash, long blockNumber) } } - public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, Hash256 endBlockHash, int count) + public IOwnedReadOnlyList FindReversedHeaders(ulong endBlockNumber, Hash256 endBlockHash, int count) { Dictionary prefetched = new(count); @@ -117,7 +117,8 @@ public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, { Span startKey = stackalloc byte[40]; Span endKey = stackalloc byte[40]; - KeyValueStoreExtensions.GetBlockNumPrefixedKey(Math.Max(0L, endBlockNumber - count + 1), default, startKey); + ulong startBlockNumber = endBlockNumber + 1 > (ulong)count ? endBlockNumber - (ulong)count + 1 : 0UL; + KeyValueStoreExtensions.GetBlockNumPrefixedKey(startBlockNumber, default, startKey); KeyValueStoreExtensions.GetBlockNumPrefixedKey(endBlockNumber + 1, default, endKey); using ISortedView view = sorted.GetViewBetween(startKey, endKey); @@ -139,7 +140,7 @@ public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, ArrayPoolList result = new(count) { cursor }; while (result.Count < count && cursor.ParentHash is not null) { - long parentNumber = cursor.Number - 1; + ulong parentNumber = cursor.Number - 1; cursor = prefetched.TryGetValue(cursor.ParentHash.ValueHash256, out BlockHeader? dictHeader) ? dictHeader : Get(cursor.ParentHash, shouldCache: false, blockNumber: parentNumber); @@ -151,7 +152,7 @@ public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, return result; } - BlockHeader? IHeaderFinder.Get(Hash256 blockHash, long? blockNumber) => Get(blockHash, true, blockNumber); + BlockHeader? IHeaderFinder.Get(Hash256 blockHash, ulong? blockNumber) => Get(blockHash, true, blockNumber); void IClearableCache.ClearCache() => _headerCache.Clear(); } diff --git a/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderFinder.cs b/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderFinder.cs index cb964c6ebdc3..1ed5bf64cee2 100644 --- a/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderFinder.cs +++ b/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderFinder.cs @@ -8,5 +8,5 @@ namespace Nethermind.Blockchain.Headers; public interface IHeaderFinder { - BlockHeader? Get(Hash256 blockHash, long? blockNumber = null); + BlockHeader? Get(Hash256 blockHash, ulong? blockNumber = null); } diff --git a/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderStore.cs b/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderStore.cs index e1f54ca4b56c..5890315e5707 100644 --- a/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Headers/IHeaderStore.cs @@ -12,11 +12,11 @@ public interface IHeaderStore : IHeaderFinder { void Insert(BlockHeader header); void BulkInsert(IReadOnlyList headers); - BlockHeader? Get(Hash256 blockHash, bool shouldCache, long? blockNumber = null); + BlockHeader? Get(Hash256 blockHash, bool shouldCache, ulong? blockNumber = null); void Cache(BlockHeader header); void Delete(Hash256 blockHash); - void InsertBlockNumber(Hash256 blockHash, long blockNumber); - long? GetBlockNumber(Hash256 blockHash); + void InsertBlockNumber(Hash256 blockHash, ulong blockNumber); + ulong? GetBlockNumber(Hash256 blockHash); /// /// Returns up to consecutive headers ending at , @@ -25,5 +25,5 @@ public interface IHeaderStore : IHeaderFinder /// The returned list is ordered oldest-first. If the chain breaks, the returned list is shorter. /// Returns an empty list when is not found. /// - IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, Hash256 endBlockHash, int count); + IOwnedReadOnlyList FindReversedHeaders(ulong endBlockNumber, Hash256 endBlockHash, int count); } diff --git a/src/Nethermind/Nethermind.Blockchain/IBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Blockchain/IBlockFinalizationManager.cs index 818afbb2857b..f6fa930b3abf 100644 --- a/src/Nethermind/Nethermind.Blockchain/IBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Blockchain/IBlockFinalizationManager.cs @@ -10,9 +10,9 @@ public interface IBlockFinalizationManager : IDisposable /// /// Current finalized level tracked by the active finalization manager. /// - long LastFinalizedBlockLevel { get; } + ulong LastFinalizedBlockLevel { get; } event EventHandler BlocksFinalized; - public bool IsFinalized(long level) => LastFinalizedBlockLevel >= level; + public bool IsFinalized(ulong level) => LastFinalizedBlockLevel >= level; } } diff --git a/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs index 5a49336734fd..e21f5381bbf6 100644 --- a/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs @@ -55,9 +55,9 @@ public interface IBlockTree : IBlockFinder /// /// Best downloaded block number (highest number of chain level on the chain) /// - long BestKnownNumber { get; } + ulong BestKnownNumber { get; } - long BestKnownBeaconNumber { get; } + ulong BestKnownBeaconNumber { get; } /// /// Inserts a disconnected block header (without body) @@ -85,7 +85,7 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption void UpdateHeadBlock(Hash256 blockHash); - void NewOldestBlock(long oldestBlock); + void NewOldestBlock(ulong oldestBlock); /// /// Suggests block for inclusion in the block tree. @@ -116,7 +116,7 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption /// Number of the block to check (needed for faster lookup) /// Hash of the block to check /// True if known, otherwise False - bool IsKnownBlock(long number, Hash256 blockHash); + bool IsKnownBlock(ulong number, Hash256 blockHash); /// /// Checks if beacon block was inserted and the block RLP is in the DB @@ -124,7 +124,7 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption /// Number of the block to check (needed for faster lookup) /// Hash of the block to check /// True if known, otherwise False - bool IsKnownBeaconBlock(long number, Hash256 blockHash); + bool IsKnownBeaconBlock(ulong number, Hash256 blockHash); /// /// Checks if the state changes of the block can be found in the state tree. @@ -132,7 +132,7 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption /// Number of the block to check (needed for faster lookup) /// Hash of the block to check /// True if processed, otherwise False - bool WasProcessed(long number, Hash256 blockHash); + bool WasProcessed(ulong number, Hash256 blockHash); /// /// Marks all as processed, changes chain head to the last of them and updates all the chain levels./> @@ -148,18 +148,18 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken); - (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash); + (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(ulong number, Hash256 blockHash); - ChainLevelInfo? FindLevel(long number); + ChainLevelInfo? FindLevel(ulong number); - BlockInfo FindCanonicalBlockInfo(long blockNumber); + BlockInfo FindCanonicalBlockInfo(ulong blockNumber); - Hash256? FindHash(long blockNumber); + Hash256? FindHash(ulong blockNumber); IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse); void DeleteInvalidBlock(Block invalidBlock); - void DeleteOldBlock(long blockNumber, Hash256 blockHash); + void DeleteOldBlock(ulong blockNumber, Hash256 blockHash); void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash); @@ -183,11 +183,11 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption event EventHandler OnUpdateMainChain; event EventHandler OnForkChoiceUpdated; - int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false); + int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false); bool IsBetterThanHead(BlockHeader? header); - void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint); + void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint); void RecalculateTreeLevels(); @@ -198,13 +198,13 @@ AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOption /// for blocks before sync pivot. /// Before sync pivot, there is no guarantee that blocks and receipts are available or continuous. /// - (long BlockNumber, Hash256 BlockHash) SyncPivot { get; set; } + (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get; set; } - public readonly struct ForkChoiceUpdateEventArgs(Block? head, long safe, long finalized) + public readonly struct ForkChoiceUpdateEventArgs(Block? head, ulong safe, ulong finalized) { public Block? Head => head; - public long Safe => safe; - public long Finalized => finalized; + public ulong Safe => safe; + public ulong Finalized => finalized; } bool IsProcessingBlock { get; set; } } diff --git a/src/Nethermind/Nethermind.Blockchain/ManualFinalizationManager.cs b/src/Nethermind/Nethermind.Blockchain/ManualFinalizationManager.cs index 20db8cb27f58..ecae5c4f56a5 100644 --- a/src/Nethermind/Nethermind.Blockchain/ManualFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Blockchain/ManualFinalizationManager.cs @@ -10,7 +10,7 @@ namespace Nethermind.Blockchain public class ManualBlockFinalizationManager : IManualBlockFinalizationManager { // We could save in DB, but its not really needed yet - public long LastFinalizedBlockLevel { get; private set; } = 0; + public ulong LastFinalizedBlockLevel { get; private set; } = 0; // We could save in DB, but its not really needed yet public Hash256 LastFinalizedHash { get; private set; } = Keccak.Zero; diff --git a/src/Nethermind/Nethermind.Blockchain/Metrics.cs b/src/Nethermind/Nethermind.Blockchain/Metrics.cs index 97832e0abd71..0c13b2085e5a 100644 --- a/src/Nethermind/Nethermind.Blockchain/Metrics.cs +++ b/src/Nethermind/Nethermind.Blockchain/Metrics.cs @@ -51,11 +51,11 @@ public static class Metrics [GaugeMetric] [Description("Gas Used in processed blocks")] - public static long GasUsed { get; set; } + public static ulong GasUsed { get; set; } [GaugeMetric] [Description("Gas Limit for processed blocks")] - public static long GasLimit { get; set; } + public static ulong GasLimit { get; set; } [GaugeMetric] [Description("Total difficulty on the chain")] @@ -83,7 +83,7 @@ public static class Metrics [GaugeMetric] [Description("The estimated highest block available.")] [DataMember(Name = "ethereum_best_known_block_number")] - public static long BestKnownBlockNumber { get; set; } + public static ulong BestKnownBlockNumber { get; set; } [GaugeMetric] [Description("Number of invalid blocks.")] diff --git a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs index 7759ef28a562..6bc261b058d8 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs @@ -31,7 +31,7 @@ public BlockHeader? LowestInsertedHeader set { } } - public long? BestPersistedState + public ulong? BestPersistedState { get => _wrapped.BestPersistedState; set => _wrapped.BestPersistedState = value; @@ -45,18 +45,18 @@ public BlockHeader? LowestInsertedBeaconHeader } public Block BestSuggestedBody => _wrapped.BestSuggestedBody; - public long BestKnownNumber => _wrapped.BestKnownNumber; - public long BestKnownBeaconNumber => _wrapped.BestKnownBeaconNumber; + public ulong BestKnownNumber => _wrapped.BestKnownNumber; + public ulong BestKnownBeaconNumber => _wrapped.BestKnownBeaconNumber; public Block Head => _wrapped.Head; public void MarkChainAsProcessed(IReadOnlyList blocks) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(MarkChainAsProcessed)} calls"); - public (BlockInfo Info, ChainLevelInfo Level) GetInfo(long number, Hash256 blockHash) => _wrapped.GetInfo(number, blockHash); + public (BlockInfo Info, ChainLevelInfo Level) GetInfo(ulong number, Hash256 blockHash) => _wrapped.GetInfo(number, blockHash); public bool CanAcceptNewBlocks { get; } = false; public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) => _wrapped.Accept(blockTreeVisitor, cancellationToken); - public ChainLevelInfo FindLevel(long number) => _wrapped.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _wrapped.FindCanonicalBlockInfo(blockNumber); + public ChainLevelInfo FindLevel(ulong number) => _wrapped.FindLevel(number); + public BlockInfo FindCanonicalBlockInfo(ulong blockNumber) => _wrapped.FindCanonicalBlockInfo(blockNumber); public void BulkInsertHeader(IReadOnlyList headers, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) => @@ -85,22 +85,22 @@ public void UpdateHeadBlock(Hash256 blockHash) => public Hash256 FinalizedHash => _wrapped.FinalizedHash; public Hash256 SafeHash => _wrapped.SafeHash; - public Block FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindBlock(blockHash, options, blockNumber); + public Block FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => _wrapped.FindBlock(blockHash, options, blockNumber); - public bool HasBlock(long blockNumber, Hash256 blockHash) => _wrapped.HasBlock(blockNumber, blockHash); + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => _wrapped.HasBlock(blockNumber, blockHash); - public BlockHeader FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); + public BlockHeader FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => _wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); - public BlockHeader FindHeader(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindHeader(blockNumber, options); - public Hash256 FindBlockHash(long blockNumber) => _wrapped.FindBlockHash(blockNumber); + public BlockHeader FindHeader(ulong blockNumber, BlockTreeLookupOptions options) => _wrapped.FindHeader(blockNumber, options); + public Hash256 FindBlockHash(ulong blockNumber) => _wrapped.FindBlockHash(blockNumber); public bool IsMainChain(BlockHeader blockHeader) => _wrapped.IsMainChain(blockHeader); - public Hash256 FindHash(long blockNumber) => _wrapped.FindHash(blockNumber); + public Hash256 FindHash(ulong blockNumber) => _wrapped.FindHash(blockNumber); public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => _wrapped.FindHeaders(hash, numberOfBlocks, skip, reverse); - public Block FindBlock(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindBlock(blockNumber, options); + public Block FindBlock(ulong blockNumber, BlockTreeLookupOptions options) => _wrapped.FindBlock(blockNumber, options); public void DeleteInvalidBlock(Block invalidBlock) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(DeleteInvalidBlock)} calls"); @@ -108,11 +108,11 @@ public void UpdateHeadBlock(Hash256 blockHash) => public BlockHeader FindBestSuggestedHeader() => _wrapped.FindBestSuggestedHeader(); - public bool IsKnownBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBlock(number, blockHash); + public bool IsKnownBlock(ulong number, Hash256 blockHash) => _wrapped.IsKnownBlock(number, blockHash); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBeaconBlock(number, blockHash); + public bool IsKnownBeaconBlock(ulong number, Hash256 blockHash) => _wrapped.IsKnownBeaconBlock(number, blockHash); - public bool WasProcessed(long number, Hash256 blockHash) => _wrapped.WasProcessed(number, blockHash); + public bool WasProcessed(ulong number, Hash256 blockHash) => _wrapped.WasProcessed(number, blockHash); public event EventHandler NewBestSuggestedBlock { @@ -150,21 +150,21 @@ event EventHandler IBlockTree.OnForkChoice remove { } } - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) + public int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false) { - long bestKnownNumber = BestKnownNumber; + ulong bestKnownNumber = BestKnownNumber; if (endNumber is null || endNumber == bestKnownNumber) { if (Head?.Number > 0) { if (Head.Number < startNumber) { - const long searchLimit = 2; - long endSearch = Math.Min(bestKnownNumber, startNumber + searchLimit - 1); + const ulong searchLimit = 2; + ulong endSearch = Math.Min(bestKnownNumber, startNumber + searchLimit - 1); - IEnumerable GetPotentiallyCorruptedBlocks(long start) + IEnumerable GetPotentiallyCorruptedBlocks(ulong start) { - for (long i = start; i <= endSearch; i++) + for (ulong i = start; i <= endSearch; i++) { yield return _wrapped.FindHeader(i, BlockTreeLookupOptions.None); } @@ -189,9 +189,9 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo } public bool IsBetterThanHead(BlockHeader? header) => _wrapped.IsBetterThanHead(header); - public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(UpdateBeaconMainChain)} calls"); + public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(UpdateBeaconMainChain)} calls"); public void RecalculateTreeLevels() => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(RecalculateTreeLevels)} calls"); - public (long BlockNumber, Hash256 BlockHash) SyncPivot + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get => _wrapped.SyncPivot; set { } @@ -203,10 +203,10 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(ForkChoiceUpdated)} calls"); - public long GetLowestBlock() => _wrapped.GetLowestBlock(); + public ulong GetLowestBlock() => _wrapped.GetLowestBlock(); - public void NewOldestBlock(long oldestBlock) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(NewOldestBlock)} calls"); + public void NewOldestBlock(ulong oldestBlock) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(NewOldestBlock)} calls"); - public void DeleteOldBlock(long blockNumber, Hash256 blockHash) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(DeleteOldBlock)} calls"); + public void DeleteOldBlock(ulong blockNumber, Hash256 blockHash) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(DeleteOldBlock)} calls"); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/FullInfoReceiptFinder.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/FullInfoReceiptFinder.cs index c20d68dbad2a..d7c33d3ec1f7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/FullInfoReceiptFinder.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/FullInfoReceiptFinder.cs @@ -43,7 +43,7 @@ public TxReceipt[] Get(Hash256 blockHash, bool recover = true) return receipts; } - public bool CanGetReceiptsByHash(long blockNumber) => _receiptStorage.CanGetReceiptsByHash(blockNumber); - public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) => _receiptStorage.TryGetReceiptsIterator(blockNumber, blockHash, out iterator); + public bool CanGetReceiptsByHash(ulong blockNumber) => _receiptStorage.CanGetReceiptsByHash(blockNumber); + public bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) => _receiptStorage.TryGetReceiptsIterator(blockNumber, blockHash, out iterator); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptFinder.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptFinder.cs index 8ac067a8dc1b..2440f4fa3d68 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptFinder.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptFinder.cs @@ -11,7 +11,7 @@ public interface IReceiptFinder Hash256? FindBlockHash(Hash256 txHash); TxReceipt[] Get(Block block, bool recover = true, bool recoverSender = true); TxReceipt[] Get(Hash256 blockHash, bool recover = true); - bool CanGetReceiptsByHash(long blockNumber); - bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator); + bool CanGetReceiptsByHash(ulong blockNumber); + bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptStorage.cs index dd7caa7366b7..2c3f6c13d9df 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptStorage.cs @@ -11,10 +11,10 @@ namespace Nethermind.Blockchain.Receipts public interface IReceiptStorage : IReceiptFinder { void Insert(Block block, params TxReceipt[]? txReceipts) => Insert(block, txReceipts, true); - void Insert(Block block, TxReceipt[]? txReceipts, bool ensureCanonical, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null); - void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool ensureCanonical, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null); - long MigratedBlockNumber { get; set; } - bool HasBlock(long blockNumber, Hash256 hash); + void Insert(Block block, TxReceipt[]? txReceipts, bool ensureCanonical, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null); + void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool ensureCanonical, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null); + ulong MigratedBlockNumber { get; set; } + bool HasBlock(ulong blockNumber, Hash256 hash); void EnsureCanonical(Block block); void RemoveReceipts(Block block); diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptsMigration.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptsMigration.cs index d4e46d012b6c..367178647ab3 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptsMigration.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptsMigration.cs @@ -7,6 +7,6 @@ namespace Nethermind.Blockchain.Receipts { public interface IReceiptsMigration { - Task Run(long from, long to); + Task Run(ulong from, ulong to); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/InMemoryReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/InMemoryReceiptStorage.cs index 15d3fe8bd950..e71be8d53d7f 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/InMemoryReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/InMemoryReceiptStorage.cs @@ -47,8 +47,8 @@ public Hash256 FindBlockHash(Hash256 txHash) public TxReceipt[] Get(Hash256 blockHash, bool recover = true) => _receipts.TryGetValue(blockHash, out TxReceipt[] receipts) ? receipts : []; - public bool CanGetReceiptsByHash(long blockNumber) => true; - public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) + public bool CanGetReceiptsByHash(ulong blockNumber) => true; + public bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) { if (_allowReceiptIterator && _receipts.TryGetValue(blockHash, out TxReceipt[] receipts)) { @@ -64,10 +64,10 @@ public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out Rece } } - public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null) + public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null) => Insert(block, txReceipts, null, ensureCanonical, writeFlags, lastBlockNumber); - public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null) + public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null) { _receipts[block.Hash] = txReceipts; if (ensureCanonical) @@ -78,7 +78,7 @@ public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ReceiptsInserted?.Invoke(this, new(block.Header, txReceipts)); } - public bool HasBlock(long blockNumber, Hash256 hash) + public bool HasBlock(ulong blockNumber, Hash256 hash) => _receipts.ContainsKey(hash); public void EnsureCanonical(Block block) @@ -101,7 +101,7 @@ public void RemoveReceipts(Block block) } } - public long MigratedBlockNumber { get; set; } + public ulong MigratedBlockNumber { get; set; } public int Count => _transactions.Count; } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/NullReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/NullReceiptStorage.cs index de1143091a02..5b567b187051 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/NullReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/NullReceiptStorage.cs @@ -23,22 +23,22 @@ private NullReceiptStorage() { } - public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null) { } - public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical, WriteFlags writeFlags, long? lastBlockNumber = null) { } + public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null) { } + public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical, WriteFlags writeFlags, ulong? lastBlockNumber = null) { } public TxReceipt[] Get(Block block, bool recover = true, bool recoverSender = false) => []; public TxReceipt[] Get(Hash256 blockHash, bool recover = true) => []; - public bool CanGetReceiptsByHash(long blockNumber) => true; + public bool CanGetReceiptsByHash(ulong blockNumber) => true; - public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) + public bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) { iterator = new ReceiptsIterator(); return false; } - public long MigratedBlockNumber { get; set; } = 0; + public ulong MigratedBlockNumber { get; set; } = 0; - public bool HasBlock(long blockNumber, Hash256 hash) => false; + public bool HasBlock(ulong blockNumber, Hash256 hash) => false; public void EnsureCanonical(Block block) { diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs index 15fbaa7a9c8d..8de7749a55f7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs @@ -28,7 +28,7 @@ public class PersistentReceiptStorage : IReceiptStorage private readonly IDb _defaultColumn; private readonly IDb _transactionDb; private static readonly Hash256 MigrationBlockNumberKey = Keccak.Compute(nameof(MigratedBlockNumber)); - private long _migratedBlockNumber; + private ulong _migratedBlockNumber; private readonly ReceiptArrayStorageDecoder _storageDecoder; private readonly IBlockTree _blockTree; private readonly IBlockStore _blockStore; @@ -52,7 +52,7 @@ public PersistentReceiptStorage( { _database = receiptsDb ?? throw new ArgumentNullException(nameof(receiptsDb)); _defaultColumn = _database.GetColumnDb(ReceiptsColumns.Default); - long Get(Hash256 key, long defaultValue) => _defaultColumn.Get(key)?.ToLongFromBigEndianByteArrayWithoutLeadingZeros() ?? defaultValue; + ulong Get(Hash256 key, ulong defaultValue) => _defaultColumn.Get(key)?.ToULongFromBigEndianByteArrayWithoutLeadingZeros() ?? defaultValue; _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _receiptsRecovery = receiptsRecovery ?? throw new ArgumentNullException(nameof(receiptsRecovery)); @@ -63,7 +63,7 @@ public PersistentReceiptStorage( _storageDecoder = storageDecoder ?? ReceiptArrayStorageDecoder.Instance; _receiptConfig = receiptConfig ?? throw new ArgumentNullException(nameof(receiptConfig)); - _migratedBlockNumber = Get(MigrationBlockNumberKey, long.MaxValue); + _migratedBlockNumber = Get(MigrationBlockNumberKey, ulong.MaxValue); KeyValuePair? firstValue = _receiptsDb.GetAll().FirstOrDefault(); _legacyHashKey = firstValue.HasValue && firstValue.Value.Key is not null && firstValue.Value.Key.Length == Hash256.Size; @@ -82,9 +82,9 @@ private void BlockTreeOnBlockAddedToMain(object? sender, BlockReplacementEventAr Block newMain = e.Block; // Delete old tx index - if (_receiptConfig.TxLookupLimit > 0 && newMain.Number > _receiptConfig.TxLookupLimit.Value) + if (_receiptConfig.TxLookupLimit > 0 && newMain.Number > (ulong)_receiptConfig.TxLookupLimit.Value) { - Block newOldTx = _blockTree.FindBlock(newMain.Number - _receiptConfig.TxLookupLimit.Value); + Block newOldTx = _blockTree.FindBlock(newMain.Number - (ulong)_receiptConfig.TxLookupLimit.Value); if (newOldTx is not null) { RemoveBlockTx(newOldTx); @@ -100,7 +100,7 @@ public Hash256 FindBlockHash(Hash256 txHash) if (blockHashData.Length == Hash256.Size) return new Hash256(blockHashData); - long blockNum = new Rlp.ValueDecoderContext(blockHashData).DecodeLong(); + ulong blockNum = new Rlp.ValueDecoderContext(blockHashData).DecodeULong(); return _blockTree.FindBlockHash(blockNum); } @@ -169,7 +169,7 @@ public TxReceipt[] Get(Block block, bool recover = true, bool recoverSender = tr } [SkipLocalsInit] - private unsafe Span GetReceiptData(long blockNumber, Hash256 blockHash) + private unsafe Span GetReceiptData(ulong blockNumber, Hash256 blockHash) { Span blockNumPrefixed = stackalloc byte[40]; if (_legacyHashKey) @@ -200,7 +200,7 @@ private unsafe Span GetReceiptData(long blockNumber, Hash256 blockHash) } } - private static void GetBlockNumPrefixedKey(long blockNumber, Hash256 blockHash, Span output) + private static void GetBlockNumPrefixedKey(ulong blockNumber, Hash256 blockHash, Span output) { blockNumber.WriteBigEndian(output); blockHash!.Bytes.CopyTo(output[8..]); @@ -213,9 +213,9 @@ public TxReceipt[] Get(Hash256 blockHash, bool recover = true) return Get(block, recover, false); } - public bool CanGetReceiptsByHash(long blockNumber) => blockNumber >= MigratedBlockNumber; + public bool CanGetReceiptsByHash(ulong blockNumber) => blockNumber >= MigratedBlockNumber; - public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) + public bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) { if (_receiptsCache.TryGet(blockHash, out TxReceipt[] receipts)) { @@ -254,11 +254,11 @@ public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out Rece return true; } - public void Insert(Block block, TxReceipt[]? txReceipts, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null) + public void Insert(Block block, TxReceipt[]? txReceipts, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null) => Insert(block, txReceipts, _specProvider.GetSpec(block.Header), ensureCanonical, writeFlags, lastBlockNumber); [SkipLocalsInit] - public void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, long? lastBlockNumber = null) + public void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool ensureCanonical = true, WriteFlags writeFlags = WriteFlags.None, ulong? lastBlockNumber = null) { txReceipts ??= []; int txReceiptsLength = txReceipts.Length; @@ -272,7 +272,7 @@ public void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool _receiptsRecovery.TryRecover(block, txReceipts, false); - long blockNumber = block.Number; + ulong blockNumber = block.Number; RlpBehaviors behaviors = spec.IsEip658Enabled ? RlpBehaviors.Eip658Receipts | RlpBehaviors.Storage : RlpBehaviors.Storage; using (NettyRlpStream stream = _storageDecoder.EncodeToNewNettyStream(txReceipts, behaviors)) @@ -298,7 +298,7 @@ public void Insert(Block block, TxReceipt[]? txReceipts, IReleaseSpec spec, bool ReceiptsInserted?.Invoke(this, new(block.Header, txReceipts)); } - public long MigratedBlockNumber + public ulong MigratedBlockNumber { get => _migratedBlockNumber; set @@ -311,7 +311,7 @@ public long MigratedBlockNumber internal void ClearCache() => _receiptsCache.Clear(); [SkipLocalsInit] - public bool HasBlock(long blockNumber, Hash256 blockHash) + public bool HasBlock(ulong blockNumber, Hash256 blockHash) { if (_receiptsCache.Contains(blockHash)) return true; @@ -352,14 +352,14 @@ private void RemoveBlockTx(Block block) } } - private void EnsureCanonical(Block block, long? lastBlockNumber) + private void EnsureCanonical(Block block, ulong? lastBlockNumber) { using IWriteBatch writeBatch = _transactionDb.StartWriteBatch(); - lastBlockNumber ??= _blockTree.FindBestSuggestedHeader()?.Number ?? 0; + lastBlockNumber ??= _blockTree.FindBestSuggestedHeader()?.Number ?? 0UL; if (_receiptConfig.TxLookupLimit == -1) return; - if (_receiptConfig.TxLookupLimit != 0 && block.Number <= lastBlockNumber - _receiptConfig.TxLookupLimit) return; + if (_receiptConfig.TxLookupLimit != 0 && lastBlockNumber.Value >= (ulong)_receiptConfig.TxLookupLimit && block.Number <= lastBlockNumber.Value - (ulong)_receiptConfig.TxLookupLimit) return; if (_receiptConfig.CompactTxIndex) { byte[] blockNumber = Rlp.Encode(block.Number).Bytes; diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptsRecovery.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptsRecovery.cs index 88a7ff9e73da..1d9a181e7685 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptsRecovery.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptsRecovery.cs @@ -70,7 +70,7 @@ private class RecoveryContext(IReleaseSpec releaseSpec, ReceiptRecoveryBlock blo private readonly bool _forceRecoverSender = forceRecoverSender; private readonly IEthereumEcdsa _ecdsa = ecdsa; - private long _gasUsedBefore = 0; + private ulong _gasUsedBefore = 0; private int _transactionIndex = 0; public void RecoverReceiptData(TxReceipt receipt) @@ -137,7 +137,7 @@ public void RecoverReceiptData(ref TxReceiptStructRef receipt) IncrementContext(receipt.GasUsedTotal); } - private void IncrementContext(long gasUsedTotal) + private void IncrementContext(ulong gasUsedTotal) { _transactionIndex++; _gasUsedBefore = gasUsedTotal; diff --git a/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs b/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs index fda29ae09107..50630c519a02 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs @@ -10,9 +10,9 @@ namespace Nethermind.Blockchain; public class ReorgDepthFinalizedStateProvider(IBlockTree blockTree) : IFinalizedStateProvider { - public long FinalizedBlockNumber => Math.Max(0, blockTree.BestKnownNumber - Reorganization.MaxDepth); + public ulong FinalizedBlockNumber => blockTree.BestKnownNumber >= Reorganization.MaxDepth ? blockTree.BestKnownNumber - Reorganization.MaxDepth : 0UL; - public Hash256? GetFinalizedStateRootAt(long blockNumber) + public Hash256? GetFinalizedStateRootAt(ulong blockNumber) { if (FinalizedBlockNumber < blockNumber) return null; return blockTree.FindHeader(blockNumber, BlockTreeLookupOptions.RequireCanonical)?.StateRoot; diff --git a/src/Nethermind/Nethermind.Blockchain/Spec/ChainHeadSpecProvider.cs b/src/Nethermind/Nethermind.Blockchain/Spec/ChainHeadSpecProvider.cs index b200ac5b2172..e3c0de8ab770 100644 --- a/src/Nethermind/Nethermind.Blockchain/Spec/ChainHeadSpecProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/Spec/ChainHeadSpecProvider.cs @@ -16,7 +16,7 @@ public class ChainHeadSpecProvider(ISpecProvider specProvider, IBlockFinder bloc private readonly IBlockFinder _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); private CachedSpec? _cache; - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) => + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => _specProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public ForkActivation? MergeBlockNumber => _specProvider.MergeBlockNumber; @@ -29,7 +29,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public IReleaseSpec GetSpec(ForkActivation forkActivation) => _specProvider.GetSpec(forkActivation); - public long? DaoBlockNumber => _specProvider.DaoBlockNumber; + public ulong? DaoBlockNumber => _specProvider.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => _specProvider.BeaconChainGenesisTimestamp; @@ -42,7 +42,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public IReleaseSpec GetCurrentHeadSpec() { BlockHeader? header = _blockFinder.FindBestSuggestedHeader(); - long headerNumber = header?.Number ?? 0; + ulong headerNumber = header?.Number ?? 0; // Reference-type record keeps the (number, spec) publication atomic. // Don't change to a record struct — 16-byte writes are not atomic. @@ -60,6 +60,6 @@ public IReleaseSpec GetCurrentHeadSpec() return spec; } - private sealed record CachedSpec(long Number, IReleaseSpec Spec); + private sealed record CachedSpec(ulong Number, IReleaseSpec Spec); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs index 7592b47ce5c6..aefa7c26d554 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs @@ -51,7 +51,7 @@ public interface ISyncConfig : IConfig string PivotTotalDifficulty { get; } [ConfigItem(Description = "The number of the pivot block for the Fast sync mode.", DefaultValue = "0")] - long PivotNumber { get; set; } + ulong PivotNumber { get; set; } [ConfigItem(Description = "The hash of the pivot block for the Fast sync mode.", DefaultValue = "null")] string? PivotHash { get; set; } @@ -71,10 +71,10 @@ public interface ISyncConfig : IConfig """, DefaultValue = "0")] - public long AncientBodiesBarrier { get; set; } + public ulong AncientBodiesBarrier { get; set; } [ConfigItem(DisabledForCli = true, HiddenFromDocs = true, DefaultValue = "1")] - public long AncientBodiesBarrierCalc => Math.Max(1, Math.Min(PivotNumber, AncientBodiesBarrier)); + public ulong AncientBodiesBarrierCalc => Math.Max(1, Math.Min(PivotNumber, AncientBodiesBarrier)); [ConfigItem(Description = $$""" The earliest receipt downloaded with fast sync when `{{nameof(DownloadReceiptsInFastSync)}}` is set to `true`. The actual value is determined as follows: @@ -85,10 +85,10 @@ public interface ISyncConfig : IConfig """, DefaultValue = "0")] - public long AncientReceiptsBarrier { get; set; } + public ulong AncientReceiptsBarrier { get; set; } [ConfigItem(DisabledForCli = true, HiddenFromDocs = true, DefaultValue = "1")] - public long AncientReceiptsBarrierCalc => Math.Max(1, Math.Min(PivotNumber, Math.Max(AncientBodiesBarrier, AncientReceiptsBarrier))); + public ulong AncientReceiptsBarrierCalc => Math.Max(1, Math.Min(PivotNumber, Math.Max(AncientBodiesBarrier, AncientReceiptsBarrier))); [ConfigItem(Description = $$""" The earliest block access list downloaded with fast sync when `{{nameof(DownloadBlockAccessListsInFastSync)}}` is set to `true`. @@ -100,10 +100,10 @@ public interface ISyncConfig : IConfig """, DefaultValue = "0")] - public long AncientBlockAccessListsBarrier { get; set; } + public ulong AncientBlockAccessListsBarrier { get; set; } [ConfigItem(DisabledForCli = true, HiddenFromDocs = true, DefaultValue = "1")] - public long AncientBlockAccessListsBarrierCalc => Math.Max(1, Math.Min(PivotNumber, AncientBlockAccessListsBarrier)); + public ulong AncientBlockAccessListsBarrierCalc => Math.Max(1, Math.Min(PivotNumber, AncientBlockAccessListsBarrier)); [ConfigItem(Description = "Whether to use the Snap sync mode.", DefaultValue = "false")] public bool SnapSync { get; set; } @@ -118,10 +118,10 @@ public interface ISyncConfig : IConfig public bool FixTotalDifficulty { get; set; } [ConfigItem(Description = "The first block to recalculate the total difficulty for.", DefaultValue = "1")] - public long FixTotalDifficultyStartingBlock { get; set; } + public ulong FixTotalDifficultyStartingBlock { get; set; } [ConfigItem(Description = "The last block to recalculate the total difficulty for. If not specified, the best known block is used.\n", DefaultValue = "null")] - public long? FixTotalDifficultyLastBlock { get; set; } + public ulong? FixTotalDifficultyLastBlock { get; set; } [ConfigItem(Description = "Whether to disable some optimizations and do a more extensive sync. Useful when sync state is corrupted.", DefaultValue = "false")] public bool StrictMode { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncPeer.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncPeer.cs index f8e09243c9d0..f4b6025976f5 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncPeer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncPeer.cs @@ -35,7 +35,7 @@ public interface ISyncPeer : ITxPoolPeer, IPeerWithSatelliteProtocol void Disconnect(DisconnectReason reason, string details); Task GetBlockBodies(IReadOnlyList blockHashes, CancellationToken token); - Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token); + Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token); Task?> GetBlockHeaders(Hash256 startHash, int maxBlocks, int skip, CancellationToken token); Task GetHeadBlockHeader(Hash256? hash, CancellationToken token); void NotifyOfNewBlock(Block block, SendBlockMode mode); diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index 1e8e7689dfeb..6fd2367e843e 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -34,12 +34,12 @@ public bool SynchronizationEnabled public bool DownloadBodiesInFastSync { get; set; } = true; public bool DownloadReceiptsInFastSync { get; set; } = true; public bool DownloadBlockAccessListsInFastSync { get; set; } = true; - public long AncientBodiesBarrier { get; set; } - public long AncientReceiptsBarrier { get; set; } - public long AncientBlockAccessListsBarrier { get; set; } + public ulong AncientBodiesBarrier { get; set; } + public ulong AncientReceiptsBarrier { get; set; } + public ulong AncientBlockAccessListsBarrier { get; set; } public string PivotTotalDifficulty { get; set; } - private long _pivotNumber = 0; - public long PivotNumber + private ulong _pivotNumber = 0; + public ulong PivotNumber { get => FastSync || SnapSync ? _pivotNumber : 0; set => _pivotNumber = value; @@ -56,8 +56,8 @@ public string? PivotHash public int SnapSyncAccountRangePartitionCount { get; set; } = 8; public bool FixReceipts { get; set; } = false; public bool FixTotalDifficulty { get; set; } = false; - public long FixTotalDifficultyStartingBlock { get; set; } = 1; - public long? FixTotalDifficultyLastBlock { get; set; } = null; + public ulong FixTotalDifficultyStartingBlock { get; set; } = 1; + public ulong? FixTotalDifficultyLastBlock { get; set; } = null; public bool StrictMode { get; set; } = false; public bool BlockGossipEnabled { get; set; } = true; public bool NonValidatorNode { get; set; } = false; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/AccessTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/AccessTxTracer.cs index 595d9b35f6ff..56fac120a0fc 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/AccessTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/AccessTxTracer.cs @@ -62,7 +62,7 @@ public override void ReportAccess(IEnumerable
accessedAddresses, IEnume AccessList = builder.Build(); } - public long GasSpent { get; set; } + public ulong GasSpent { get; set; } public AccessList? AccessList { get; private set; } public void Reset() diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/AlwaysCancelTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/AlwaysCancelTxTracer.cs index 6d61ad0d7a46..6e02fe86c4eb 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/AlwaysCancelTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/AlwaysCancelTxTracer.cs @@ -50,11 +50,11 @@ public static AlwaysCancelTxTracer Instance public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] output, string? error, Hash256? stateRoot = null) => throw new OperationCanceledException(ErrorMessage); - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) => throw new OperationCanceledException(ErrorMessage); + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => throw new OperationCanceledException(ErrorMessage); public void ReportOperationError(EvmExceptionType error) => throw new OperationCanceledException(ErrorMessage); - public void ReportOperationRemainingGas(long gas) => throw new OperationCanceledException(ErrorMessage); + public void ReportOperationRemainingGas(ulong gas) => throw new OperationCanceledException(ErrorMessage); public void ReportLog(LogEntry log) => throw new OperationCanceledException(ErrorMessage); @@ -91,19 +91,19 @@ public static AlwaysCancelTxTracer Instance public void ReportStorageRead(in StorageCell storageCell) => throw new OperationCanceledException(ErrorMessage); - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new OperationCanceledException(ErrorMessage); + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new OperationCanceledException(ErrorMessage); - public void ReportActionEnd(long gas, ReadOnlyMemory output) => throw new OperationCanceledException(ErrorMessage); + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) => throw new OperationCanceledException(ErrorMessage); public void ReportActionError(EvmExceptionType exceptionType) => throw new OperationCanceledException(ErrorMessage); - public void ReportActionRevert(long gas, ReadOnlyMemory output) => throw new OperationCanceledException(ErrorMessage); + public void ReportActionRevert(ulong gas, ReadOnlyMemory output) => throw new OperationCanceledException(ErrorMessage); - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new OperationCanceledException(ErrorMessage); + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new OperationCanceledException(ErrorMessage); public void ReportBlockHash(Hash256 blockHash) => throw new OperationCanceledException(ErrorMessage); public void ReportByteCode(ReadOnlyMemory byteCode) => throw new OperationCanceledException(ErrorMessage); - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) => throw new OperationCanceledException(ErrorMessage); + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) => throw new OperationCanceledException(ErrorMessage); public void ReportRefund(long refund) => throw new OperationCanceledException(ErrorMessage); - public void ReportExtraGasPressure(long extraGasPressure) => throw new OperationCanceledException(ErrorMessage); + public void ReportExtraGasPressure(ulong extraGasPressure) => throw new OperationCanceledException(ErrorMessage); public void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) => throw new OperationCanceledException(ErrorMessage); public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); public void Dispose() { } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/BlockReceiptsTracer.cs index 492c48205dd0..0fd1a2dce8b0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/BlockReceiptsTracer.cs @@ -79,12 +79,12 @@ protected TxReceipt BuildFailedReceipt(Address recipient, in GasConsumed gasSpen /// while receipt gas uses post-refund values (what users actually pay). ///
/// The cumulative post-refund gas for receipts - protected long UpdateCumulativeGasTracking(in GasConsumed gasConsumed) + protected ulong UpdateCumulativeGasTracking(in GasConsumed gasConsumed) { // Track cumulative block gas for restore (regular + EIP-8037 state) - (long prevRegular, long prevState) = _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1] : (0, 0); - long cumulativeBlockGas = prevRegular + gasConsumed.EffectiveBlockGas; - long cumulativeBlockStateGas = prevState + gasConsumed.BlockStateGas; + (ulong prevRegular, ulong prevState) = _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1] : (0, 0); + ulong cumulativeBlockGas = prevRegular + gasConsumed.EffectiveBlockGas; + ulong cumulativeBlockStateGas = prevState + gasConsumed.BlockStateGas; _cumulativeBlockGasPerTx.Add((cumulativeBlockGas, cumulativeBlockStateGas)); // EIP-8037: block gasUsed = max(sum_regular, sum_state). Override header accumulation. @@ -104,7 +104,7 @@ protected long UpdateCumulativeGasTracking(in GasConsumed gasConsumed) protected virtual TxReceipt BuildReceipt(Address recipient, in GasConsumed gasConsumed, byte statusCode, LogEntry[] logEntries, Hash256? stateRoot) { - long cumulativeReceiptGas = UpdateCumulativeGasTracking(gasConsumed); + ulong cumulativeReceiptGas = UpdateCumulativeGasTracking(gasConsumed); Transaction transaction = CurrentTx!; // Diagnostic-only: effective gas price after EIP-1559 baseFee adjustment. @@ -150,14 +150,14 @@ protected virtual TxReceipt BuildReceipt(Address recipient, in GasConsumed gasCo return txReceipt; } - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) => + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => _currentTxTracer.StartOperation(pc, opcode, gas, env); public void ReportOperationError(EvmExceptionType error) => _currentTxTracer.ReportOperationError(error); - public void ReportOperationRemainingGas(long gas) => + public void ReportOperationRemainingGas(ulong gas) => _currentTxTracer.ReportOperationRemainingGas(gas); public void ReportLog(LogEntry log) => @@ -199,31 +199,31 @@ public void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[ public void ReportStorageRead(in StorageCell storageCell) => _currentTxTracer.ReportStorageRead(storageCell); - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => _currentTxTracer.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - public void ReportActionEnd(long gas, ReadOnlyMemory output) => + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) => _currentTxTracer.ReportActionEnd(gas, output); public void ReportActionError(EvmExceptionType exceptionType) => _currentTxTracer.ReportActionError(exceptionType); - public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) => + public void ReportActionRevert(ulong gasLeft, ReadOnlyMemory output) => _currentTxTracer.ReportActionRevert(gasLeft, output); - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => _currentTxTracer.ReportActionEnd(gas, deploymentAddress, deployedCode); public void ReportByteCode(ReadOnlyMemory byteCode) => _currentTxTracer.ReportByteCode(byteCode); - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) => + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) => _currentTxTracer.ReportGasUpdateForVmTrace(refund, gasAvailable); public void ReportRefund(long refund) => _currentTxTracer.ReportRefund(refund); - public void ReportExtraGasPressure(long extraGasPressure) => + public void ReportExtraGasPressure(ulong extraGasPressure) => _currentTxTracer.ReportExtraGasPressure(extraGasPressure); public void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) => @@ -252,8 +252,8 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) private ITxTracer _currentTxTracer = NullTxTracer.Instance; protected int _currentIndex { get; private set; } private readonly List _txReceipts = []; - private readonly List<(long Regular, long State)> _cumulativeBlockGasPerTx = []; // Track pre-refund block gas for restore (regular + EIP-8037 state) - private long _cumulativeReceiptGas; // Track cumulative post-refund gas for receipts + private readonly List<(ulong Regular, ulong State)> _cumulativeBlockGasPerTx = []; // Track pre-refund block gas for restore (regular + EIP-8037 state) + private ulong _cumulativeReceiptGas; // Track cumulative post-refund gas for receipts protected Transaction? CurrentTx; public ReadOnlySpan TxReceipts => CollectionsMarshal.AsSpan(_txReceipts); public TxReceipt LastReceipt => _txReceipts[^1]; @@ -279,9 +279,9 @@ public void SetReceipt(int index, TxReceipt receipt) /// EIP-8037: cumulative state gas for the last tracked tx. /// Used by parallel execution to pass state gas back for 2D block gas accounting. ///
- public long BlockStateGasUsed => _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1].State : 0; + public ulong BlockStateGasUsed => _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1].State : 0; public bool IsTracingRewards => _otherTracer.IsTracingRewards; - public long CumulativeRegularGasUsed => _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1].Regular : 0; + public ulong CumulativeRegularGasUsed => _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1].Regular : 0; public ITxTracer InnerTracer => _currentTxTracer; @@ -300,7 +300,7 @@ public void Restore(int snapshot) "Receipt and gas tracking lists must remain synchronized after restore"); // Restore block gas from tracking: max(cumulative_regular, cumulative_state) for EIP-8037 - (long cumulativeRegular, long cumulativeState) = _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1] : (0, 0); + (ulong cumulativeRegular, ulong cumulativeState) = _cumulativeBlockGasPerTx.Count > 0 ? _cumulativeBlockGasPerTx[^1] : (0, 0); Block.Header.GasUsed = Math.Max(cumulativeRegular, cumulativeState); // Restore receipt gas from remaining receipts (post-refund) diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/CallOutputTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/CallOutputTracer.cs index 0f850ceec596..41d38cef9182 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/CallOutputTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/CallOutputTracer.cs @@ -13,8 +13,8 @@ public class CallOutputTracer : TxTracer public override bool IsTracingReceipt => true; public byte[]? ReturnValue { get; set; } - public long GasSpent { get; set; } - public long OperationGas { get; set; } + public ulong GasSpent { get; set; } + public ulong OperationGas { get; set; } public string? Error { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/EstimateGasTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/EstimateGasTracer.cs index b5a0bf8b2520..86ae3520b73b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/EstimateGasTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/EstimateGasTracer.cs @@ -23,13 +23,13 @@ public class EstimateGasTracer : TxTracer public byte[]? ReturnValue { get; set; } - private long NonIntrinsicGasSpentBeforeRefund { get; set; } + private ulong NonIntrinsicGasSpentBeforeRefund { get; set; } - internal long GasSpent { get; set; } + internal ulong GasSpent { get; set; } - internal long IntrinsicGasAt { get; set; } + internal ulong IntrinsicGasAt { get; set; } - internal long TotalRefund { get; private set; } + internal ulong TotalRefund { get; private set; } public string? Error { get; set; } @@ -56,34 +56,34 @@ public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, by StatusCode = Evm.StatusCode.Failure; } - private class GasAndNesting(long gasOnStart, int nestingLevel) + private class GasAndNesting(ulong gasOnStart, int nestingLevel) { - public long GasOnStart { get; set; } = gasOnStart; - public long GasUsageFromChildren { get; set; } - public long GasLeft { get; set; } + public ulong GasOnStart { get; set; } = gasOnStart; + public ulong GasUsageFromChildren { get; set; } + public ulong GasLeft { get; set; } public int NestingLevel { get; set; } = nestingLevel; - private long MaxGasNeeded + private ulong MaxGasNeeded { get { - long maxGasNeeded = GasOnStart + ExtraGasPressure - GasLeft + GasUsageFromChildren; + ulong maxGasNeeded = GasOnStart + ExtraGasPressure - GasLeft + GasUsageFromChildren; for (int i = 0; i < NestingLevel; i++) { - maxGasNeeded = (long)Math.Ceiling(maxGasNeeded * 64m / 63); + maxGasNeeded = (ulong)Math.Ceiling(maxGasNeeded * 64m / 63); } return maxGasNeeded; } } - public long AdditionalGasRequired => MaxGasNeeded - (GasOnStart - GasLeft); - public long ExtraGasPressure { get; set; } + public ulong AdditionalGasRequired => MaxGasNeeded - (GasOnStart - GasLeft); + public ulong ExtraGasPressure { get; set; } } - internal long CalculateAdditionalGasRequired(Transaction tx, IReleaseSpec releaseSpec) + internal ulong CalculateAdditionalGasRequired(Transaction tx, IReleaseSpec releaseSpec) { - long intrinsicGas = tx.GasLimit - IntrinsicGasAt; + ulong intrinsicGas = tx.GasLimit - IntrinsicGasAt; return _currentGasAndNesting.Peek().AdditionalGasRequired + RefundHelper.CalculateClaimableRefund(intrinsicGas + NonIntrinsicGasSpentBeforeRefund, TotalRefund, releaseSpec); @@ -95,7 +95,7 @@ internal long CalculateAdditionalGasRequired(Transaction tx, IReleaseSpec releas private readonly Stack _currentGasAndNesting = new(); - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { if (_currentNestingLevel == -1) @@ -116,9 +116,9 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address } } - public override void ReportActionEnd(long gas, ReadOnlyMemory output) => UpdateAdditionalGas(gas); + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) => UpdateAdditionalGas(gas); - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => UpdateAdditionalGas(gas); public override void ReportActionError(EvmExceptionType exceptionType) @@ -127,7 +127,7 @@ public override void ReportActionError(EvmExceptionType exceptionType) UpdateAdditionalGas(); } - public void ReportActionError(EvmExceptionType exceptionType, long gasLeft) + public void ReportActionError(EvmExceptionType exceptionType, ulong gasLeft) { ReportOperationError(exceptionType); UpdateAdditionalGas(gasLeft); @@ -146,7 +146,7 @@ public override void ReportOperationError(EvmExceptionType error) } } - private void UpdateAdditionalGas(long? gasLeft = null) + private void UpdateAdditionalGas(ulong? gasLeft = null) { if (_isInPrecompile) { @@ -171,9 +171,9 @@ private void UpdateAdditionalGas(long? gasLeft = null) } } - public override void ReportRefund(long refund) => TotalRefund += refund; + public override void ReportRefund(long refund) => TotalRefund += (ulong)refund; - public override void ReportExtraGasPressure(long extraGasPressure) => + public override void ReportExtraGasPressure(ulong extraGasPressure) => _currentGasAndNesting.Peek().ExtraGasPressure = Math.Max(_currentGasAndNesting.Peek().ExtraGasPressure, extraGasPressure); } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs index 34585505aa19..893f8ca83a09 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs @@ -34,7 +34,7 @@ public class GasEstimator( public const string InsufficientFundsForGas = "insufficient sender balance for gas * price + value"; private const int MaxErrorMargin = 10000; - private const double BasisPointsDivisor = 10000d; + private const ulong BasisPointsDivisor = 10000UL; private const string InvalidErrorMarginNegative = "Invalid error margin, cannot be negative."; private static readonly string InvalidErrorMarginTooHigh = $"Invalid error margin, must be lower than {MaxErrorMargin}."; @@ -43,12 +43,12 @@ public class GasEstimator( private const string CannotEstimateGasExceeded = "Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap"; private const string ExecutionReverted = "execution reverted"; - public long Estimate( + public ulong Estimate( Transaction tx, BlockHeader header, EstimateGasTracer gasTracer, out string? err, - int errorMargin = DefaultErrorMargin, + ulong errorMargin = DefaultErrorMargin, CancellationToken token = default) { EstimationResult result = EstimateInternal(tx, header, gasTracer, errorMargin, token); @@ -60,7 +60,7 @@ private EstimationResult EstimateInternal( Transaction tx, BlockHeader header, EstimateGasTracer gasTracer, - int errorMargin, + ulong errorMargin, CancellationToken token) { if (ValidateErrorMargin(errorMargin) is { } validationError) @@ -74,9 +74,9 @@ private EstimationResult EstimateInternal( if (CheckFunds(tx, spec, gasTracer, senderBalance, out UInt256 available) is { } fundsResult) return fundsResult; - long intrinsicGas = IntrinsicGasCalculator.Calculate(tx, spec, header.GasLimit).MinimalGas; - long leftBound = Math.Max(gasTracer.GasSpent - 1, intrinsicGas - 1); - long rightBound = Math.Min( + ulong intrinsicGas = IntrinsicGasCalculator.Calculate(tx, spec, header.GasLimit).MinimalGas; + ulong leftBound = Math.Max(gasTracer.GasSpent > 0 ? gasTracer.GasSpent - 1 : 0, intrinsicGas > 0 ? intrinsicGas - 1 : 0); + ulong rightBound = Math.Min( tx.GasLimit != 0 && tx.GasLimit >= intrinsicGas ? tx.GasLimit : header.GasLimit, spec.GetTxGasLimitCap()); @@ -89,10 +89,9 @@ private EstimationResult EstimateInternal( return BinarySearchEstimate(tx, header, gasTracer, bounds, errorMargin, token); } - private static EstimationResult? ValidateErrorMargin(int errorMargin) => + private static EstimationResult? ValidateErrorMargin(ulong errorMargin) => errorMargin switch { - < 0 => EstimationResult.Failure(InvalidErrorMarginNegative), >= MaxErrorMargin => EstimationResult.Failure(InvalidErrorMarginTooHigh), _ => null }; @@ -103,9 +102,9 @@ private EstimationResult EstimateInternal( { available = UInt256.Zero; - if (tx.ValueRef > senderBalance) + if (senderBalance < tx.ValueRef) { - long additionalGas = gasTracer.CalculateAdditionalGasRequired(tx, spec); + ulong additionalGas = gasTracer.CalculateAdditionalGasRequired(tx, spec); return additionalGas > 0 ? EstimationResult.Success(additionalGas) : EstimationResult.Failure(GetError(gasTracer, InsufficientBalance)); @@ -124,13 +123,13 @@ private static EstimationBounds CapByAllowance(EstimationBounds bounds, UInt256 if (feeCap == UInt256.Zero) return bounds; - long allowance = (long)UInt256.Min(available / feeCap, (UInt256)long.MaxValue); + ulong allowance = (ulong)UInt256.Min(available / feeCap, (UInt256)ulong.MaxValue); return bounds with { RightBound = Math.Min(bounds.RightBound, allowance) }; } private EstimationResult BinarySearchEstimate( Transaction tx, BlockHeader header, EstimateGasTracer gasTracer, - EstimationBounds bounds, int errorMargin, CancellationToken token) + EstimationBounds bounds, ulong errorMargin, CancellationToken token) { // Short-circuit: simple ETH transfers need exactly the intrinsic gas. if (IsSimpleTransfer(tx) && TryExecute(tx, header, bounds.IntrinsicGas, gasTracer, token, out _)) @@ -145,14 +144,14 @@ private EstimationResult BinarySearchEstimate( return EstimationResult.Failure(error); } - double marginMultiplier = errorMargin == 0 ? 1d : errorMargin / BasisPointsDivisor + 1d; - long cap = bounds.RightBound; - (long leftBound, long rightBound) = TryOptimisticEstimate(tx, header, gasTracer, bounds, marginMultiplier, token); + ulong marginMultiplier = errorMargin == 0 ? 1UL : errorMargin / BasisPointsDivisor + 1UL; + ulong cap = bounds.RightBound; + (ulong leftBound, ulong rightBound) = TryOptimisticEstimate(tx, header, gasTracer, bounds, marginMultiplier, token); // Narrow bounds until within the error margin (Geth approach). while (ShouldContinueSearch(leftBound, rightBound, marginMultiplier - 1d)) { - long mid = leftBound + (rightBound - leftBound) / 2; + ulong mid = leftBound + (rightBound - leftBound) / 2; if (TryExecute(tx, header, mid, gasTracer, token, out _)) rightBound = mid; else @@ -165,15 +164,16 @@ private EstimationResult BinarySearchEstimate( return EstimationResult.Success(rightBound); } - private (long Left, long Right) TryOptimisticEstimate( + private (ulong Left, ulong Right) TryOptimisticEstimate( Transaction tx, BlockHeader header, EstimateGasTracer gasTracer, - EstimationBounds bounds, double marginMultiplier, CancellationToken token) + EstimationBounds bounds, ulong marginMultiplier, CancellationToken token) { - long leftBound = bounds.LeftBound; - long rightBound = bounds.RightBound; + ulong leftBound = bounds.LeftBound; + ulong rightBound = bounds.RightBound; // Optimistic first guess (Geth approach): reduces binary search iterations in most cases. - long optimistic = (long)((gasTracer.GasSpent + gasTracer.TotalRefund + GasCostOf.CallStipend) * marginMultiplier); + // GasSpent, TotalRefund, CallStipend are ulong; cast to long is safe as values fit within long.MaxValue + ulong optimistic = (gasTracer.GasSpent + gasTracer.TotalRefund + GasCostOf.CallStipend) * marginMultiplier; if (optimistic > leftBound && optimistic < rightBound) { if (TryExecute(tx, header, optimistic, gasTracer, token, out _)) @@ -185,7 +185,7 @@ private EstimationResult BinarySearchEstimate( return (leftBound, rightBound); } - private bool TryExecute(Transaction transaction, BlockHeader header, long gasLimit, + private bool TryExecute(Transaction transaction, BlockHeader header, ulong gasLimit, EstimateGasTracer gasTracer, CancellationToken token, out bool isGasRelatedFailure) { Transaction txClone = new(); @@ -210,7 +210,7 @@ private static bool IsGasRelatedFailure(TransactionResult result) => result.Error is TransactionResult.ErrorType.GasLimitBelowIntrinsicGas or TransactionResult.ErrorType.BlockGasLimitExceeded; - private static bool ShouldContinueSearch(long leftBound, long rightBound, double threshold) => + private static bool ShouldContinueSearch(ulong leftBound, ulong rightBound, double threshold) => (rightBound - leftBound) / (double)leftBound > threshold && leftBound + 1 < rightBound; private static bool IsSimpleTransfer(Transaction tx) => @@ -230,11 +230,11 @@ private static string GetRevertError(EstimateGasTracer gasTracer) => ? $"{ExecutionReverted}: {gasTracer.ReturnValue.ToHexString(true)}" : ExecutionReverted); - private readonly record struct EstimationBounds(long LeftBound, long RightBound, long IntrinsicGas); + private readonly record struct EstimationBounds(ulong LeftBound, ulong RightBound, ulong IntrinsicGas); - private readonly record struct EstimationResult(long GasEstimate, string? Error) + private readonly record struct EstimationResult(ulong GasEstimate, string? Error) { - public static EstimationResult Success(long gasEstimate) => new(gasEstimate, null); + public static EstimationResult Success(ulong gasEstimate) => new(gasEstimate, null); public static EstimationResult Failure(string error) => new(0, error); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/CallFrame.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/CallFrame.cs index bbf061d8b3ca..e65408b882ca 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/CallFrame.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/CallFrame.cs @@ -43,7 +43,7 @@ public ReadOnlyMemory Input } } - public long Gas { get; set; } + public ulong Gas { get; set; } public UInt256? Value { @@ -69,7 +69,7 @@ public UInt256? Value public ITypedArray getFrom() => _fromConverted ??= From.Bytes.ToArray().ToTypedScriptArray(); public ITypedArray getTo() => _toConverted ??= To.Bytes.ToArray().ToTypedScriptArray(); public ITypedArray getInput() => _inputConverted ??= Input.ToTypedScriptArray(); - public long getGas() => Gas; + public ulong getGas() => Gas; public dynamic getValue() => (_valueConverted ??= Value?.ToBigInteger()) ?? Undefined.Value; // ReSharper restore InconsistentNaming } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Context.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Context.cs index 2c1dfa92778e..eb9a421d57e7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Context.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Context.cs @@ -113,11 +113,11 @@ public UInt256 GasPrice public ITypedArray? from => _fromConverted ??= From?.Bytes.ToArray().ToTypedScriptArray(); public ITypedArray? to => _toConverted ??= To?.Bytes.ToArray().ToTypedScriptArray(); public ITypedArray? input => _inputConverted ??= Input.ToArray().ToTypedScriptArray(); - public long gas { get; set; } - public long gasUsed { get; set; } + public ulong gas { get; set; } + public ulong gasUsed { get; set; } public IJavaScriptObject gasPrice => _gasPriceConverted ??= GasPrice.ToBigInteger(); public IJavaScriptObject value => _valueConverted ??= Value.ToBigInteger(); - public long block { get; set; } + public ulong block { get; set; } public ITypedArray? output => _outputConverted ??= Output?.ToTypedScriptArray(); public ITypedArray? blockHash => _blockHashConverted ??= BlockHash?.BytesToArray().ToTypedScriptArray(); public int? txIndex { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/FrameResult.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/FrameResult.cs index 6a1a10299d35..155538bd7582 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/FrameResult.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/FrameResult.cs @@ -10,7 +10,7 @@ public class FrameResult { private ITypedArray? _outputConverted; private byte[] _output; - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public byte[] Output { @@ -23,7 +23,7 @@ public byte[] Output } public string? Error { get; set; } - public long getGasUsed() => GasUsed; + public ulong getGasUsed() => GasUsed; public ITypedArray getOutput() => _outputConverted ??= Output.ToTypedScriptArray(); public dynamic getError() => !string.IsNullOrEmpty(Error) ? Error : Undefined.Value; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/GethLikeJavaScriptTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/GethLikeJavaScriptTxTracer.cs index 9b130176193e..25012b493a6b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/GethLikeJavaScriptTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/GethLikeJavaScriptTxTracer.cs @@ -30,7 +30,7 @@ public sealed class GethLikeJavaScriptTxTracer : GethLikeTxTracer private readonly CancellationTokenSource _cts; private readonly IDisposable _ctsRegistration; private bool _resultConstructed; - private Stack? _frameGas; + private Stack? _frameGas; private Stack? _contracts; private int _depth = -1; @@ -83,7 +83,7 @@ public override GethLikeTxTrace BuildResult() return result; } - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { _depth++; @@ -109,7 +109,7 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address _frame.Gas = gas; _frame.Type = callType.FastToString(); _tracer.enter(_frame); - _frameGas ??= new Stack(); + _frameGas ??= new Stack(); _frameGas.Push(gas); } @@ -118,7 +118,7 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address : new Log.Contract(from, to, value, isAnyCreate ? null : input); } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { _log.pc = pc; _log.op = new Log.Opcode(opcode); @@ -128,7 +128,7 @@ public override void StartOperation(int pc, Instruction opcode, long gas, in Exe _log.gasCost = null; } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { _log.gasCost ??= _log.gas - gas; if (_functions.HasFlag(TracerFunctions.postStep)) @@ -144,7 +144,7 @@ public override void ReportOperationError(EvmExceptionType error) _tracer.fault(_log, _db); } - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { base.ReportActionEnd(gas, deploymentAddress, deployedCode); @@ -152,13 +152,13 @@ public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOn InvokeExit(gas, deployedCode); } - public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) { base.ReportActionEnd(gas, output); InvokeExit(gas, output); } - public override void ReportActionRevert(long gasLeft, ReadOnlyMemory output) + public override void ReportActionRevert(ulong gasLeft, ReadOnlyMemory output) { base.ReportActionError(EvmExceptionType.Revert); InvokeExit(gasLeft, output, EvmExceptionType.Revert.GetEvmExceptionDescription()); @@ -170,7 +170,7 @@ public override void ReportActionError(EvmExceptionType evmExceptionType) InvokeExit(0, Array.Empty(), evmExceptionType.GetEvmExceptionDescription()); } - private void InvokeExit(long gas, ReadOnlyMemory output, string? error = null) + private void InvokeExit(ulong gas, ReadOnlyMemory output, string? error = null) { if (_contracts?.TryPop(out Log.Contract contract) == true) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Log.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Log.cs index feb17581eb82..4b3d7dc53eb8 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Log.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Log.cs @@ -22,15 +22,15 @@ public class Log public Contract contract { get; set; } public long pc { get; set; } - public long gas { get; set; } - public long? gasCost { get; set; } + public ulong gas { get; set; } + public ulong? gasCost { get; set; } public int depth { get; set; } public long refund { get; set; } public string? error { get; set; } public ulong getPC() => (ulong)pc; - public ulong getGas() => (ulong)gas; - public ulong getCost() => (ulong)(gasCost ?? 0); + public ulong getGas() => gas; + public ulong getCost() => gasCost ?? 0; public int getDepth() => depth; public ulong getRefund() => (ulong)refund; public dynamic getError() => !string.IsNullOrEmpty(error) ? error : Undefined.Value; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracer.cs index 914d27514789..b2f3e75ef18c 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracer.cs @@ -26,14 +26,14 @@ public sealed class NativeCallTracer : GethLikeNativeTxTracer { public const string CallTracer = "callTracer"; - private readonly long _gasLimit; + private readonly ulong _gasLimit; private readonly Hash256? _txHash; private readonly NativeCallTracerConfig _config; private readonly ArrayPoolList _callStack = new(1024); private readonly CompositeDisposable _disposables = []; private EvmExceptionType? _error; - private long _remainingGas; + private ulong _remainingGas; private bool _resultBuilt = false; public NativeCallTracer( @@ -87,7 +87,7 @@ public override void Dispose() _callStack.Dispose(); } - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); @@ -126,19 +126,19 @@ public override void ReportLog(LogEntry log) callFrame.Logs.Add(callLog); } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { base.ReportOperationRemainingGas(gas); _remainingGas = gas > 0 ? gas : 0; } - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { OnExit(gas, deployedCode); base.ReportActionEnd(gas, deploymentAddress, deployedCode); } - public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) { OnExit(gas, output); base.ReportActionEnd(gas, output); @@ -151,7 +151,7 @@ public override void ReportActionError(EvmExceptionType evmExceptionType) base.ReportActionError(evmExceptionType); } - public override void ReportActionRevert(long gas, ReadOnlyMemory output) + public override void ReportActionRevert(ulong gas, ReadOnlyMemory output) { _error = EvmExceptionType.Revert; OnExit(gas, output, _error); @@ -210,7 +210,7 @@ public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, by } } - private void OnExit(long gas, ReadOnlyMemory? output, EvmExceptionType? error = null) + private void OnExit(ulong gas, ReadOnlyMemory? output, EvmExceptionType? error = null) { if (!_config.OnlyTopCall && Depth > 0) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracerCallFrame.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracerCallFrame.cs index 421d6650ef85..b6988aaa7fe1 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracerCallFrame.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Call/NativeCallTracerCallFrame.cs @@ -22,9 +22,9 @@ public class NativeCallTracerCallFrame : IDisposable public Address? From { get; set; } - public long Gas { get; set; } + public ulong Gas { get; set; } - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public Address? To { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/FourByte/Native4ByteTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/FourByte/Native4ByteTracer.cs index baf174168b56..86673cf90b8d 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/FourByte/Native4ByteTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/FourByte/Native4ByteTracer.cs @@ -50,7 +50,7 @@ public override GethLikeTxTrace BuildResult() return result; } - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); @@ -64,7 +64,7 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address } } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) => + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => _op = opcode; private void CaptureStart(ReadOnlyMemory input) diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/GethLikeNativeTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/GethLikeNativeTxTracer.cs index 300201c390eb..9ef1bef0a400 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/GethLikeNativeTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/GethLikeNativeTxTracer.cs @@ -11,19 +11,19 @@ public abstract class GethLikeNativeTxTracer(GethTraceOptions options) : GethLik { protected int Depth { get; private set; } = -1; - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); Depth++; } - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { base.ReportActionEnd(gas, deploymentAddress, deployedCode); Depth--; } - public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) { base.ReportActionEnd(gas, output); Depth--; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Prestate/NativePrestateTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Prestate/NativePrestateTracer.cs index f1fd0a4abdd5..75cdb55bcda5 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Prestate/NativePrestateTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/Native/Prestate/NativePrestateTracer.cs @@ -94,7 +94,7 @@ public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, by ProcessDiffState(); } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { base.StartOperation(pc, opcode, gas, env); @@ -174,7 +174,7 @@ public override void SetOperationStack(TraceStack stack) } break; case Instruction.CREATE: - UInt256 nonce = _worldState!.GetNonce(_executingAccount!); + ulong nonce = _worldState!.GetNonce(_executingAccount!); address = ContractAddress.From(_executingAccount, nonce); LookupAccount(address!); if (_diffMode) diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxDirectStreamingTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxDirectStreamingTracer.cs index 995d71d81468..d2ba3a78c5e0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxDirectStreamingTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxDirectStreamingTracer.cs @@ -41,8 +41,8 @@ public sealed class GethLikeTxDirectStreamingTracer : GethLikeTxTracer private bool _hasPendingOpcode; private int _pendingPc; private Instruction _pendingOpcode; - private long _pendingGas; - private long _pendingGasCost; + private ulong _pendingGas; + private ulong _pendingGasCost; private int _pendingDepth; private string? _pendingError; private bool _gasCostAlreadySet; @@ -108,7 +108,7 @@ public override void MarkAsSuccess(Address recipient, in GasConsumed gasSpent, b Trace.Gas = gasSpent.SpentGas; } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { FinalizePendingOpcode(); @@ -127,7 +127,7 @@ public override void StartOperation(int pc, Instruction opcode, long gas, in Exe _memoryByteCount = 0; } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { if (_gasCostAlreadySet || !_hasPendingOpcode) return; _pendingGasCost = _pendingGas - gas; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxFileTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxFileTracer.cs index 1ea67c180e24..2db49627b97b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxFileTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxFileTracer.cs @@ -9,7 +9,7 @@ namespace Nethermind.Blockchain.Tracing.GethStyle; public class GethLikeTxFileTracer : GethLikeTxTracer { private readonly Action _dumpCallback; - private long? _startGas; + private ulong? _startGas; public GethLikeTxFileTracer(Action dumpCallback, GethTraceOptions options) : base(options) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxMemoryTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxMemoryTracer.cs index 8dc9e80ed431..27235be96801 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxMemoryTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxMemoryTracer.cs @@ -51,7 +51,7 @@ public override void SetOperationStorage(Address address, UInt256 storageIndex, .ToHexString(false); } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { GethTxMemoryTraceEntry previousTraceEntry = CurrentTraceEntry; int previousDepth = CurrentTraceEntry?.Depth ?? 0; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTrace.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTrace.cs index d09e6e9171f7..7edf284de0e0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTrace.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTrace.cs @@ -20,7 +20,7 @@ public GethLikeTxTrace() { } public Stack> StoragesByDepth { get; } = new(); - public long Gas { get; set; } + public ulong Gas { get; set; } public bool Failed { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTraceConverter.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTraceConverter.cs index 5e6475422631..bfd926ff784c 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTraceConverter.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTraceConverter.cs @@ -38,7 +38,7 @@ public override GethLikeTxTrace Read( ForcedNumberConversion.Value = NumberConversion.Raw; try { - trace.Gas = JsonSerializer.Deserialize(ref reader, options); + trace.Gas = JsonSerializer.Deserialize(ref reader, options); } finally { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTracer.cs index 32ede63a1121..3170664d40a7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethLikeTxTracer.cs @@ -66,7 +66,7 @@ public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, by private bool _gasCostAlreadySetForCurrentOp; - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { if (CurrentTraceEntry is not null) { @@ -87,7 +87,7 @@ public override void ReportOperationError(EvmExceptionType error) CurrentTraceEntry.Error = GetErrorDescription(error); } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { if (!_gasCostAlreadySetForCurrentOp && CurrentTraceEntry is not null) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethTxTraceEntry.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethTxTraceEntry.cs index fa2872dfe357..a345b743e109 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethTxTraceEntry.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/GethTxTraceEntry.cs @@ -20,11 +20,11 @@ public GethTxTraceEntry() [JsonPropertyName("op")] public string? Opcode { get; set; } - [JsonConverter(typeof(LongRawJsonConverter))] - public long Gas { get; set; } + [JsonConverter(typeof(ULongRawJsonConverter))] + public ulong Gas { get; set; } - [JsonConverter(typeof(LongRawJsonConverter))] - public long GasCost { get; set; } + [JsonConverter(typeof(ULongRawJsonConverter))] + public ulong GasCost { get; set; } public int Depth { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTrace.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTrace.cs index cc79cb5be9ee..ae5020c6e0db 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTrace.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTrace.cs @@ -15,8 +15,8 @@ public class ParityLikeTxTrace public Hash256? BlockHash { get; set; } - [JsonConverter(typeof(LongRawJsonConverter))] - public long BlockNumber { get; set; } + [JsonConverter(typeof(ULongRawJsonConverter))] + public ulong BlockNumber { get; set; } public int? TransactionPosition { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTracer.cs index d075d0ff6663..33497b62d549 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -269,7 +269,7 @@ public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, by } } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { ParityVmOperationTrace operationTrace = new(); _gasAlreadySetForCurrentOp = false; @@ -289,18 +289,18 @@ public override void ReportOperationError(EvmExceptionType error) } } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { if (!_gasAlreadySetForCurrentOp) { _gasAlreadySetForCurrentOp = true; - _currentOperation!.Cost -= (_treatGasParityStyle ? 0 : gas); + _currentOperation!.Cost -= (_treatGasParityStyle ? 0UL : gas); // based on Parity behaviour - adding stipend to the gas cost - if (_currentOperation.Cost == 7400) + if (_currentOperation.Cost == 7400UL) { - _currentOperation.Cost = 9700; + _currentOperation.Cost = 9700UL; } _currentOperation.Push = _currentPushList.ToArray(); @@ -401,7 +401,7 @@ public override void ReportStorageChange(in StorageCell storageCell, byte[] befo change = RentByteStateChange(before, after); } - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { ParityTraceAction action = RentAction(); @@ -444,7 +444,7 @@ public override void ReportSelfDestruct(Address address, UInt256 balance, Addres PopAction(); } - public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) { if (_currentAction!.Result is null) { @@ -464,7 +464,7 @@ public override void ReportActionError(EvmExceptionType evmExceptionType) PopAction(); } - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { if (_currentAction!.Result is null) { @@ -482,6 +482,6 @@ public override void ReportByteCode(ReadOnlyMemory byteCode) => // TODO: use memory pool? _currentVmTrace.VmTrace.Code = byteCode.ToArray(); - public override void ReportGasUpdateForVmTrace(long refund, long gasAvailable) => + public override void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) => _currentOperation!.Used = gasAvailable; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceAction.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceAction.cs index 31beb601f008..869ffdae28b8 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceAction.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceAction.cs @@ -19,7 +19,7 @@ public class ParityTraceAction public string? CreationMethod { get; set; } public Address? From { get; set; } public Address? To { get; set; } - public long Gas { get; set; } + public ulong Gas { get; set; } public UInt256 Value { get; set; } public CappedArray Input { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceActionConverter.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceActionConverter.cs index 2cc518e4cf3f..731d51d98bc6 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceActionConverter.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceActionConverter.cs @@ -73,7 +73,7 @@ public override ParityTraceAction Read( else if (reader.ValueTextEquals("gas"u8)) { reader.Read(); - value.Gas = JsonSerializer.Deserialize(ref reader, options); + value.Gas = JsonSerializer.Deserialize(ref reader, options); } else if (reader.ValueTextEquals("value"u8)) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResult.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResult.cs index 82ae384155a0..ba5dd44ba5ec 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResult.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResult.cs @@ -9,7 +9,7 @@ namespace Nethermind.Blockchain.Tracing.ParityStyle; [JsonConverter(typeof(ParityTraceResultConverter))] public class ParityTraceResult { - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public byte[]? Output { get; set; } public Address? Address { get; set; } public byte[]? Code { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResultConverter.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResultConverter.cs index ca05a267dda3..c9260674bdd0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResultConverter.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityTraceResultConverter.cs @@ -34,7 +34,7 @@ public override ParityTraceResult Read( if (reader.ValueTextEquals("gasUsed"u8)) { reader.Read(); - value.GasUsed = JsonSerializer.Deserialize(ref reader, options); + value.GasUsed = JsonSerializer.Deserialize(ref reader, options); } else if (reader.ValueTextEquals("output"u8)) { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityVmOperationTrace.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityVmOperationTrace.cs index 018845fe7869..2fbe57737904 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityVmOperationTrace.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/ParityVmOperationTrace.cs @@ -19,11 +19,11 @@ namespace Nethermind.Blockchain.Tracing.ParityStyle; [JsonConverter(typeof(ParityVmOperationTraceConverter))] public class ParityVmOperationTrace { - public long Cost { get; set; } + public ulong Cost { get; set; } public ParityMemoryChangeTrace Memory { get; set; } public byte[][] Push { get; set; } public ParityStorageChangeTrace Store { get; set; } - public long Used { get; set; } + public ulong Used { get; set; } public int Pc { get; set; } public ParityVmTrace Sub { get; set; } } diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/StreamingParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/StreamingParityLikeTxTracer.cs index e80b41e0f256..b15eea7d4e51 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/StreamingParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/ParityStyle/StreamingParityLikeTxTracer.cs @@ -30,8 +30,8 @@ public class StreamingParityLikeTxTracer : ParityLikeTxTracer { private const int DefaultFlushIntervalEntries = 8192; private const int InitialFrameStackCapacity = 8; - private const long ParityCallCostBeforeStipend = 7400; - private const long ParityCallCostAfterStipend = 9700; + private const ulong ParityCallCostBeforeStipend = 7400UL; + private const ulong ParityCallCostAfterStipend = 9700UL; private readonly Utf8JsonWriter _writer; private readonly PipeWriter? _pipeWriter; @@ -43,8 +43,8 @@ public class StreamingParityLikeTxTracer : ParityLikeTxTracer private bool _hasPendingOp; private bool _pushAssigned; private int _pendingPc; - private long _pendingCost; - private long _pendingUsed; + private ulong _pendingCost; + private ulong _pendingUsed; private byte[]? _memoryBuffer; private int _memoryByteCount; @@ -281,7 +281,7 @@ private void ReturnStateChanges(Dictionary ch } } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { if (!_streamVmTrace) { base.StartOperation(pc, opcode, gas, env); return; } @@ -302,14 +302,14 @@ public override void StartOperation(int pc, Instruction opcode, long gas, in Exe ReleaseOpBuffers(); } - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { if (!_streamVmTrace) { base.ReportOperationRemainingGas(gas); return; } if (_gasAlreadySetForCurrentOp || !_hasPendingOp) return; _gasAlreadySetForCurrentOp = true; - _pendingCost -= _treatGasParityStyle ? 0 : gas; + _pendingCost -= _treatGasParityStyle ? 0UL : gas; if (_pendingCost == ParityCallCostBeforeStipend) _pendingCost = ParityCallCostAfterStipend; _pendingUsed = gas; _pushAssigned = true; @@ -383,7 +383,7 @@ public override void ReportByteCode(ReadOnlyMemory byteCode) frame.CodeLength = codeSpan.Length; } - public override void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public override void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { if (!_streamVmTrace) { base.ReportGasUpdateForVmTrace(refund, gasAvailable); return; } @@ -442,7 +442,7 @@ protected override void OnLeaveVmFrame(ParityTraceAction action) bool hadPendingParent = frame.HasPendingParentOpToClose; int outerPc = frame.OuterPendingPc; - long outerCost = frame.OuterPendingCost; + ulong outerCost = frame.OuterPendingCost; ReturnFrame(frame); if (hadPendingParent) @@ -699,7 +699,7 @@ private sealed class VmFrame public bool JsonObjectOpened; public bool HasPendingParentOpToClose; public int OuterPendingPc; - public long OuterPendingCost; + public ulong OuterPendingCost; public void Reset() { diff --git a/src/Nethermind/Nethermind.Blockchain/Visitors/DbBlocksLoader.cs b/src/Nethermind/Nethermind.Blockchain/Visitors/DbBlocksLoader.cs index 085a42476551..7a37e9f348bf 100644 --- a/src/Nethermind/Nethermind.Blockchain/Visitors/DbBlocksLoader.cs +++ b/src/Nethermind/Nethermind.Blockchain/Visitors/DbBlocksLoader.cs @@ -15,8 +15,8 @@ public class DbBlocksLoader : IBlockTreeVisitor, IDisposable { public const int DefaultBatchSize = 4000; - private readonly long _batchSize; - private readonly long _blocksToLoad; + private readonly ulong _batchSize; + private readonly ulong _blocksToLoad; private readonly IBlockTree _blockTree; private readonly ILogger _logger; @@ -24,17 +24,20 @@ public class DbBlocksLoader : IBlockTreeVisitor, IDisposable public DbBlocksLoader(IBlockTree blockTree, ILogger logger, - long? startBlockNumber = null, - long batchSize = DefaultBatchSize, - long maxBlocksToLoad = long.MaxValue) + ulong? startBlockNumber = null, + ulong batchSize = DefaultBatchSize, + ulong maxBlocksToLoad = ulong.MaxValue) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); _blockTreeSuggestPacer = new BlockTreeSuggestPacer(_blockTree, batchSize, batchSize / 2); _logger = logger; _batchSize = batchSize; - StartLevelInclusive = Math.Max(0L, startBlockNumber ?? (_blockTree.Head?.Number + 1) ?? 0L); - _blocksToLoad = Math.Min(maxBlocksToLoad, _blockTree.BestKnownNumber - StartLevelInclusive); + StartLevelInclusive = startBlockNumber ?? (_blockTree.Head?.Number + 1) ?? 0UL; + ulong bestKnown = _blockTree.BestKnownNumber; + _blocksToLoad = bestKnown >= StartLevelInclusive + ? Math.Min(maxBlocksToLoad, bestKnown - StartLevelInclusive) + : 0UL; EndLevelExclusive = StartLevelInclusive + _blocksToLoad + 1; LogPlannedOperation(); @@ -42,11 +45,11 @@ public DbBlocksLoader(IBlockTree blockTree, public bool PreventsAcceptingNewBlocks => true; public bool CalculateTotalDifficultyIfMissing => true; - public long StartLevelInclusive { get; } + public ulong StartLevelInclusive { get; } - public long EndLevelExclusive { get; } + public ulong EndLevelExclusive { get; } - Task IBlockTreeVisitor.VisitLevelStart(ChainLevelInfo? chainLevelInfo, long levelNumber, CancellationToken cancellationToken) + Task IBlockTreeVisitor.VisitLevelStart(ChainLevelInfo? chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { if (chainLevelInfo is null) { @@ -66,7 +69,7 @@ Task IBlockTreeVisitor.VisitLevelStart(ChainLevelInfo? chainL Task IBlockTreeVisitor.VisitHeader(BlockHeader header, CancellationToken cancellationToken) { - long i = header.Number - StartLevelInclusive; + ulong i = header.Number - StartLevelInclusive; if (i % _batchSize == _batchSize - 1 && i != _blocksToLoad - 1 && _blockTree.Head.Number + _batchSize < header.Number) { if (_logger.IsInfo) _logger.Info($"Loaded {i + 1} out of {_blocksToLoad} headers from DB."); @@ -80,7 +83,7 @@ async Task IBlockTreeVisitor.VisitBlock(Block block, Cancella // this will hang Task waitTask = _blockTreeSuggestPacer.WaitForQueue(block.Number, cancellationToken); - long i = block.Number - StartLevelInclusive; + ulong i = block.Number - StartLevelInclusive; if (!waitTask.IsCompleted) { if (_logger.IsInfo) @@ -94,7 +97,7 @@ async Task IBlockTreeVisitor.VisitBlock(Block block, Cancella return BlockVisitOutcome.Suggest; } - Task IBlockTreeVisitor.VisitLevelEnd(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken) => Task.FromResult(LevelVisitOutcome.None); + Task IBlockTreeVisitor.VisitLevelEnd(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) => Task.FromResult(LevelVisitOutcome.None); private void LogPlannedOperation() { diff --git a/src/Nethermind/Nethermind.Blockchain/Visitors/IBlockTreeVisitor.cs b/src/Nethermind/Nethermind.Blockchain/Visitors/IBlockTreeVisitor.cs index c69f824b2e7b..f5962de56cf1 100644 --- a/src/Nethermind/Nethermind.Blockchain/Visitors/IBlockTreeVisitor.cs +++ b/src/Nethermind/Nethermind.Blockchain/Visitors/IBlockTreeVisitor.cs @@ -23,12 +23,12 @@ public interface IBlockTreeVisitor /// /// First block tree level to visit /// - long StartLevelInclusive { get; } + ulong StartLevelInclusive { get; } /// /// Last block tree level to visit /// - long EndLevelExclusive { get; } + ulong EndLevelExclusive { get; } /// /// When new chain level is visited (and before its blocks are enumerated) @@ -37,7 +37,7 @@ public interface IBlockTreeVisitor /// Level (block) number /// /// false if the visitor wants to stop visiting remaining levels, otherwise true - Task VisitLevelStart(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken); + Task VisitLevelStart(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken); /// /// If the block hash is defined on the chain level but is missing from the database. @@ -70,6 +70,6 @@ public interface IBlockTreeVisitor /// Level (block) number /// /// - Task VisitLevelEnd(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken); + Task VisitLevelEnd(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken); } } diff --git a/src/Nethermind/Nethermind.Blockchain/Visitors/ReceiptsVerificationVisitor.cs b/src/Nethermind/Nethermind.Blockchain/Visitors/ReceiptsVerificationVisitor.cs index e6bd0824c943..7c183b13c1dd 100644 --- a/src/Nethermind/Nethermind.Blockchain/Visitors/ReceiptsVerificationVisitor.cs +++ b/src/Nethermind/Nethermind.Blockchain/Visitors/ReceiptsVerificationVisitor.cs @@ -19,10 +19,10 @@ public class ReceiptsVerificationVisitor : IBlockTreeVisitor private int _good = 0; private int _bad = 0; private ChainLevelInfo _currentLevel; - private long _checked = 0; - private readonly long _toCheck; + private ulong _checked = 0; + private readonly ulong _toCheck; - public ReceiptsVerificationVisitor(long startLevel, long endLevel, IReceiptStorage receiptStorage, ILogManager logManager) + public ReceiptsVerificationVisitor(ulong startLevel, ulong endLevel, IReceiptStorage receiptStorage, ILogManager logManager) { _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); @@ -32,11 +32,11 @@ public ReceiptsVerificationVisitor(long startLevel, long endLevel, IReceiptStora } public bool PreventsAcceptingNewBlocks => false; - public long StartLevelInclusive { get; } + public ulong StartLevelInclusive { get; } - public long EndLevelExclusive { get; } + public ulong EndLevelExclusive { get; } - public Task VisitLevelStart(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken) + public Task VisitLevelStart(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { _currentLevel = chainLevelInfo; return Task.FromResult(LevelVisitOutcome.None); @@ -108,7 +108,7 @@ private int GetTxReceiptsLength(Block block, bool useIterator) } } - public Task VisitLevelEnd(ChainLevelInfo chainLevelInfo, long levelNumber, CancellationToken cancellationToken) + public Task VisitLevelEnd(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { _checked++; if (_checked % 1000 == 0) diff --git a/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs b/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs index e7d4edf78a9f..d67336f9666b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs @@ -21,17 +21,17 @@ public class StartupBlockTreeFixer : IBlockTreeVisitor, IDisposable private readonly IBlockTree _blockTree; private readonly IStateReader _stateReader; private readonly ILogger _logger; - private readonly long _startNumber; - private readonly long _blocksToLoad; + private readonly ulong _startNumber; + private readonly ulong _blocksToLoad; private ChainLevelInfo _currentLevel; - private long _currentLevelNumber; - private long _blocksCheckedInCurrentLevel; - private long _bodiesInCurrentLevel; + private ulong _currentLevelNumber; + private ulong _blocksCheckedInCurrentLevel; + private ulong _bodiesInCurrentLevel; - private long? _gapStart; - private long? _lastProcessedLevel; - private long? _processingGapStart; + private ulong? _gapStart; + private ulong? _lastProcessedLevel; + private ulong? _processingGapStart; private bool _firstBlockVisited = true; private bool _suggestBlocks = true; @@ -42,14 +42,14 @@ public StartupBlockTreeFixer( IBlockTree blockTree, IStateReader stateReader, ILogger logger, - long batchSize = DefaultBatchSize) + ulong batchSize = DefaultBatchSize) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); _blockTreeSuggestPacer = new BlockTreeSuggestPacer(_blockTree, batchSize, batchSize / 2); _stateReader = stateReader; _logger = logger; - long assumedHead = _blockTree.Head?.Number ?? 0; + ulong assumedHead = _blockTree.Head?.Number ?? 0; _startNumber = Math.Max(_blockTree.SyncPivot.BlockNumber, assumedHead + 1); _blocksToLoad = (assumedHead + 1) >= _startNumber ? (_blockTree.BestKnownNumber - _startNumber + 1) : 0; @@ -59,11 +59,11 @@ public StartupBlockTreeFixer( public bool PreventsAcceptingNewBlocks => true; public bool CalculateTotalDifficultyIfMissing => true; - public long StartLevelInclusive => _startNumber; + public ulong StartLevelInclusive => _startNumber; - public long EndLevelExclusive => _startNumber + _blocksToLoad; + public ulong EndLevelExclusive => _startNumber + _blocksToLoad; - Task IBlockTreeVisitor.VisitLevelStart(ChainLevelInfo chainLevelInfo, long levelNumber, + Task IBlockTreeVisitor.VisitLevelStart(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { if (_currentLevelNumber >= EndLevelExclusive - 1) @@ -150,7 +150,7 @@ async Task IBlockTreeVisitor.VisitBlock(Block block, Cancella Task waitSuggestQueue = _blockTreeSuggestPacer.WaitForQueue(block.Number, cancellationToken); - long i = block.Number - StartLevelInclusive; + ulong i = block.Number - StartLevelInclusive; if (!waitSuggestQueue.IsCompleted) { if (_logger.IsInfo) @@ -166,17 +166,17 @@ async Task IBlockTreeVisitor.VisitBlock(Block block, Cancella } - Task IBlockTreeVisitor.VisitLevelEnd(ChainLevelInfo chainLevelInfo, long levelNumber, + Task IBlockTreeVisitor.VisitLevelEnd(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { int expectedVisitedBlocksCount = _currentLevel?.BlockInfos.Length ?? 0; - if (_blocksCheckedInCurrentLevel != expectedVisitedBlocksCount) + if (_blocksCheckedInCurrentLevel != (ulong)expectedVisitedBlocksCount) { throw new InvalidDataException( $"Some blocks have not been visited at level {_currentLevelNumber}: {_blocksCheckedInCurrentLevel}/{expectedVisitedBlocksCount}"); } - if (_bodiesInCurrentLevel > expectedVisitedBlocksCount) + if (_bodiesInCurrentLevel > (ulong)expectedVisitedBlocksCount) { throw new InvalidOperationException( $"Invalid bodies count at level {_currentLevelNumber}: {_bodiesInCurrentLevel}/{expectedVisitedBlocksCount}"); diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index a4e4410d6f0a..26e524fe4150 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -192,8 +192,8 @@ private Block GetGenesis(int validatorsCount = 2) Hash256 unclesHash = Keccak.OfAnEmptySequenceRlp; Address beneficiary = Address.Zero; UInt256 difficulty = new(1); - long number = 0L; - int gasLimit = 4700000; + ulong number = 0L; + ulong gasLimit = 4700000; ulong timestamp = _timestamper.UnixTime.Seconds - _cliqueConfig.BlockPeriod; string extraDataHex = "0x2249276d20646f6e652077616974696e672e2e2e20666f7220626c6f636b2066"; extraDataHex += TestItem.PrivateKeyA.Address.ToString(false).Replace("0x", string.Empty); @@ -323,7 +323,7 @@ public On AssertHeadBlockParentIs(PrivateKey nodeKey, Hash256 hash) return this; } - public On AssertHeadBlockIs(PrivateKey nodeKey, long number) + public On AssertHeadBlockIs(PrivateKey nodeKey, ulong number) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING HEAD BLOCK IS BLOCK {number} ON {nodeKey.Address}"); @@ -331,7 +331,7 @@ public On AssertHeadBlockIs(PrivateKey nodeKey, long number) return this; } - public On AssertTransactionCount(PrivateKey nodeKey, long number, int transactionCount) + public On AssertTransactionCount(PrivateKey nodeKey, ulong number, int transactionCount) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING HEAD BLOCK IS BLOCK {number} ON {nodeKey.Address}"); @@ -348,7 +348,7 @@ public On AssertHeadBlockTimestamp(PrivateKey nodeKey) return this; } - public On AssertVote(PrivateKey nodeKey, long number, Address address, bool vote) + public On AssertVote(PrivateKey nodeKey, ulong number, Address address, bool vote) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING {vote} VOTE ON {address} AT BLOCK {number}"); @@ -357,7 +357,7 @@ public On AssertVote(PrivateKey nodeKey, long number, Address address, bool vote return this; } - public On AssertSignersCount(PrivateKey nodeKey, long number, int count) + public On AssertSignersCount(PrivateKey nodeKey, ulong number, int count) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING {count} SIGNERS AT BLOCK {number}"); @@ -367,7 +367,7 @@ public On AssertSignersCount(PrivateKey nodeKey, long number, int count) } - public On AssertTallyEmpty(PrivateKey nodeKey, long number, PrivateKey privateKeyB) + public On AssertTallyEmpty(PrivateKey nodeKey, ulong number, PrivateKey privateKeyB) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING EMPTY TALLY FOR {privateKeyB.Address} EMPTY AT {number}"); @@ -376,7 +376,7 @@ public On AssertTallyEmpty(PrivateKey nodeKey, long number, PrivateKey privateKe return this; } - public On AssertOutOfTurn(PrivateKey nodeKey, long number) + public On AssertOutOfTurn(PrivateKey nodeKey, ulong number) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING OUT TURN ON AT {nodeKey.Address} EMPTY AT BLOCK {number}"); @@ -384,7 +384,7 @@ public On AssertOutOfTurn(PrivateKey nodeKey, long number) return this; } - public On AssertInTurn(PrivateKey nodeKey, long number) + public On AssertInTurn(PrivateKey nodeKey, ulong number) { WaitForNumber(nodeKey, number); if (_logger.IsInfo) _logger.Info($"ASSERTING IN TURN ON AT {nodeKey.Address} EMPTY AT BLOCK {number}"); @@ -392,7 +392,7 @@ public On AssertInTurn(PrivateKey nodeKey, long number) return this; } - private void WaitForNumber(PrivateKey nodeKey, long number) + private void WaitForNumber(PrivateKey nodeKey, ulong number) { if (_logger.IsInfo) _logger.Info($"WAITING ON {nodeKey.Address} FOR BLOCK {number}"); SpinWait spinWait = new(); @@ -407,7 +407,7 @@ private void WaitForNumber(PrivateKey nodeKey, long number) } } - public Block GetBlock(PrivateKey privateKey, long number) + public Block GetBlock(PrivateKey privateKey, ulong number) { Block block = _blockTrees[privateKey].FindBlock(number, BlockTreeLookupOptions.None) ?? throw new InvalidOperationException($"Cannot find block {number}"); return block; @@ -421,7 +421,7 @@ public async Task StopNode(PrivateKey privateKeyA, bool dontDispose = false) return this; } - private readonly UInt256 _currentNonce = 0; + private readonly ulong _currentNonce = 0; public On AddPendingTransaction(PrivateKey nodeKey) { @@ -866,13 +866,13 @@ public async Task Many_validators_can_process_blocks() PrivateKey nodeKey = keys[j]; if (!nodeKey.Equals(inTurnKey)) { - goerli.Process(nodeKey, goerli.GetBlock(inTurnKey, i)); - goerli.AssertHeadBlockIs(keys[j], i + 1); + goerli.Process(nodeKey, goerli.GetBlock(inTurnKey, (ulong)i)); + goerli.AssertHeadBlockIs(keys[j], (ulong)(i + 1)); goerli.AssertHeadBlockTimestamp(keys[j]); } else { - goerli.AssertHeadBlockIs(keys[j], i); + goerli.AssertHeadBlockIs(keys[j], (ulong)i); goerli.AssertHeadBlockTimestamp(keys[j]); } } diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueSealEngineTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueSealEngineTests.cs index 61c109b6d1d6..67934c56ad6b 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueSealEngineTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueSealEngineTests.cs @@ -125,8 +125,8 @@ private Block GetGenesis() Hash256 unclesHash = Keccak.OfAnEmptySequenceRlp; Address beneficiary = Address.Zero; UInt256 difficulty = new(1); - long number = 0L; - int gasLimit = 4700000; + ulong number = 0; + ulong gasLimit = 4700000; ulong timestamp = 1492009146UL; byte[] extraData = Bytes.FromHexString(GetGenesisExtraData()); BlockHeader header = new(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData); @@ -154,14 +154,14 @@ private string GetGenesisExtraData() private static void MineBlock(BlockTree tree, Block block) => tree.SuggestBlock(block); - private Block CreateBlock(int blockDifficulty, int blockNumber, Block lastBlock) + private Block CreateBlock(int blockDifficulty, uint blockNumber, Block lastBlock) { Hash256 parentHash = lastBlock.Hash; Hash256 unclesHash = Keccak.OfAnEmptySequenceRlp; Address beneficiary = Address.Zero; UInt256 difficulty = (UInt256)blockDifficulty; - long number = blockNumber; - int gasLimit = 4700000; + ulong number = blockNumber; + ulong gasLimit = 4700000; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); byte[] extraData = Bytes.FromHexString("d883010812846765746888676f312e31312e31856c696e75780000000000000028eb026ab5355b45499053382886754f1db544618d45edc979de1864d83a626b77513bd34d7f21059e79e303c3ab210e1424e71bcb8347835cbd378a785a06f800"); BlockHeader header = new(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData); diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueTests.cs index 6822d72e0eea..0a6f4a2cc24b 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueTests.cs @@ -131,8 +131,8 @@ public static Block GetGenesis() Hash256 unclesHash = Keccak.OfAnEmptySequenceRlp; Address beneficiary = Address.Zero; UInt256 difficulty = new(1); - long number = 0L; - int gasLimit = 4700000; + ulong number = 0; + ulong gasLimit = 4700000; ulong timestamp = 1492009146UL; byte[] extraData = Bytes.FromHexString("52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); BlockHeader header = new(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData); diff --git a/src/Nethermind/Nethermind.Clique.Test/SnapshotDecoderTests.cs b/src/Nethermind/Nethermind.Clique.Test/SnapshotDecoderTests.cs index 4e57d9a33404..4274377ca0f1 100644 --- a/src/Nethermind/Nethermind.Clique.Test/SnapshotDecoderTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/SnapshotDecoderTests.cs @@ -24,7 +24,7 @@ public void Encodes() SnapshotDecoder decoder = new(); // Prepare snapshot Hash256 hash = new("0xa33ea6f6c0f1c80a6c7af308a30cb7a7affa4d0d51e6639b739727af0518b50e"); - long number = 3305206L; + ulong number = 3305206UL; Address candidate = new("0xbe1085bc3e0812f3df63deced87e29b3bc2db524"); Snapshot expected = GenerateSnapshot(hash, number, candidate); // Encode snapshot @@ -52,19 +52,19 @@ public void Encodes() } } - private Snapshot GenerateSnapshot(Hash256 hash, long number, Address candidate) + private Snapshot GenerateSnapshot(Hash256 hash, ulong number, Address candidate) { - SortedList signers = new(GenericComparer.GetOptimized
()) + SortedList signers = new(GenericComparer.GetOptimized
()) { - { _signer1, number - 2 }, - { _signer2, number - 1 }, - { _signer3, number - 3 } + { _signer1, number - 2UL }, + { _signer2, number - 1UL }, + { _signer3, number - 3UL } }; List votes = [ - new Vote(_signer1, number - 2, candidate, true), - new Vote(_signer3, number - 3, candidate, true), - new Vote(_signer3, number - 6, _signer2, false), + new Vote(_signer1, number - 2UL, candidate, true), + new Vote(_signer3, number - 3UL, candidate, true), + new Vote(_signer3, number - 6UL, _signer2, false), ]; Dictionary tally = new() { diff --git a/src/Nethermind/Nethermind.Clique.Test/WiggleRandomizerTests.cs b/src/Nethermind/Nethermind.Clique.Test/WiggleRandomizerTests.cs index e1e538fc0264..ea8d43a7ac31 100644 --- a/src/Nethermind/Nethermind.Clique.Test/WiggleRandomizerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/WiggleRandomizerTests.cs @@ -23,15 +23,15 @@ public void Wiggle_is_fine() ICryptoRandom cryptoRandom = Substitute.For(); cryptoRandom.NextInt(Arg.Any()).Returns(ci => randoms.Dequeue()); - Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) + Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) { - {TestItem.AddressA, 1}, - {TestItem.AddressB, 2}, - {TestItem.AddressC, 3}, - {TestItem.AddressD, 4} + {TestItem.AddressA, 1UL}, + {TestItem.AddressB, 2UL}, + {TestItem.AddressC, 3UL}, + {TestItem.AddressD, 4UL} }); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); WiggleRandomizer randomizer = new(cryptoRandom, snapshotManager); BlockHeader header1 = Build.A.BlockHeader.WithNumber(1).TestObject; @@ -48,16 +48,16 @@ public void Wiggle_has_no_min_value() ICryptoRandom cryptoRandom = Substitute.For(); cryptoRandom.NextInt(Arg.Any()).Returns(ci => randoms.Dequeue()); - Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) + Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) { - {TestItem.AddressA, 1}, - {TestItem.AddressB, 2}, - {TestItem.AddressC, 3}, - {TestItem.AddressD, 4} + {TestItem.AddressA, 1UL}, + {TestItem.AddressB, 2UL}, + {TestItem.AddressC, 3UL}, + {TestItem.AddressD, 4UL} }); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); WiggleRandomizer randomizer = new(cryptoRandom, snapshotManager); BlockHeader header1 = Build.A.BlockHeader.WithNumber(1).TestObject; @@ -80,16 +80,16 @@ public void Returns_zero_for_in_turn_blocks() ICryptoRandom cryptoRandom = Substitute.For(); cryptoRandom.NextInt(Arg.Any()).Returns(ci => randoms.Dequeue()); - Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) + Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) { - {TestItem.AddressA, 1}, - {TestItem.AddressB, 2}, - {TestItem.AddressC, 3}, - {TestItem.AddressD, 4} + {TestItem.AddressA, 1UL}, + {TestItem.AddressB, 2UL}, + {TestItem.AddressC, 3UL}, + {TestItem.AddressD, 4UL} }); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); WiggleRandomizer randomizer = new(cryptoRandom, snapshotManager); BlockHeader header1 = Build.A.BlockHeader.WithNumber(1).WithDifficulty(Consensus.Clique.Clique.DifficultyInTurn).TestObject; @@ -105,12 +105,12 @@ public void Minimum_Wiggle_is_set_and_used(int delay, int minDelay) { ICryptoRandom cryptoRandom = Substitute.For(); cryptoRandom.NextInt(Arg.Any()).Returns(ci => delay); - Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) + Snapshot snapshot = new(1, Keccak.Zero, new SortedList(GenericComparer.GetOptimized
()) { - {TestItem.AddressA, 1}, + {TestItem.AddressA, 1UL}, }); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetOrCreateSnapshot(Arg.Any(), Arg.Any()).Returns(snapshot); WiggleRandomizer randomizer = new(cryptoRandom, snapshotManager, minDelay); BlockHeader header1 = Build.A.BlockHeader.WithNumber(1).TestObject; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBetterPeerStrategy.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBetterPeerStrategy.cs index 4fdf6d3d29c4..a90de65204e0 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBetterPeerStrategy.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBetterPeerStrategy.cs @@ -12,13 +12,13 @@ public class AuRaBetterPeerStrategy(IBetterPeerStrategy betterPeerStrategy, ILog private readonly IBetterPeerStrategy _betterPeerStrategy = betterPeerStrategy; private readonly ILogger _logger = logManager.GetClassLogger(); - public int Compare(in (UInt256? TotalDifficulty, long Number) valueX, in (UInt256? TotalDifficulty, long Number) valueY) + public int Compare(in (UInt256? TotalDifficulty, ulong Number) valueX, in (UInt256? TotalDifficulty, ulong Number) valueY) => _betterPeerStrategy.Compare(valueX, valueY); - public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestBlock) => + public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestBlock) => _betterPeerStrategy.IsBetterThanLocalChain(bestPeerInfo, bestBlock); - public bool IsDesiredPeer(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestHeader) + public bool IsDesiredPeer(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestHeader) { if (_betterPeerStrategy.IsDesiredPeer(bestPeerInfo, bestHeader)) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs index 63eb266efc3d..576eeb9e0938 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs @@ -22,7 +22,7 @@ public class AuRaBlockFinalizationManager( IChainLevelInfoRepository chainLevelInfoRepository, IValidatorStore validatorStore, ILogManager logManager, - long twoThirdsMajorityTransition = long.MaxValue) : IAuRaBlockFinalizationManager + ulong twoThirdsMajorityTransition = ulong.MaxValue) : IAuRaBlockFinalizationManager { private static readonly List Empty = []; private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); @@ -39,7 +39,7 @@ public class AuRaBlockFinalizationManager( // to pick the active validator. Reading 0 produces state-root divergence on archive sync when // crossing a validator-contract transition. This scan only reads ChainLevelInfo metadata and // does not allocate BlockHeaders — cheap even on long post-merge chains. - private long _lastFinalizedBlockLevel = LoadInitialLastFinalizedBlockLevel(blockTree, chainLevelInfoRepository); + private ulong _lastFinalizedBlockLevel = LoadInitialLastFinalizedBlockLevel(blockTree, chainLevelInfoRepository); public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor) { @@ -65,19 +65,19 @@ public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor) } } - private static long LoadInitialLastFinalizedBlockLevel(IBlockTree blockTree, IChainLevelInfoRepository chainLevelInfoRepository) + private static ulong LoadInitialLastFinalizedBlockLevel(IBlockTree blockTree, IChainLevelInfoRepository chainLevelInfoRepository) { bool hasHead = blockTree.Head is not null; - long level = hasHead ? blockTree.Head!.Number + 1 : 0; + long level = hasHead ? (long)blockTree.Head!.Number + 1 : 0; ChainLevelInfo chainLevel; do { level--; - chainLevel = chainLevelInfoRepository.LoadLevel(level); + chainLevel = chainLevelInfoRepository.LoadLevel((ulong)level); } while (chainLevel?.MainChainBlock?.IsFinalized != true && level >= 0); - return level; + return level >= 0 ? (ulong)level : 0UL; } private void OnBlocksProcessing(object? sender, BlocksProcessingEventArgs e) @@ -288,7 +288,7 @@ private IReadOnlyList GetFinalizedBlocks(BlockHeader block) public event EventHandler? BlocksFinalized; - public long GetLastLevelFinalizedBy(Hash256 blockHash) + public ulong GetLastLevelFinalizedBy(Hash256 blockHash) { BlockHeader block = _blockTree.FindHeader(blockHash, BlockTreeLookupOptions.None)!; HashSet
validators = []; @@ -307,7 +307,7 @@ public long GetLastLevelFinalizedBy(Hash256 blockHash) return 0; } - public long? GetFinalizationLevel(long level) + public ulong? GetFinalizationLevel(ulong level) { BlockHeader? block = _blockTree.FindHeader(level, BlockTreeLookupOptions.None); HashSet
validators = []; @@ -318,10 +318,10 @@ public long GetLastLevelFinalizedBy(Hash256 blockHash) { // in that case check if it has enough blocks to best known to be finalized // as everything before pivot should be finalized - long blocksAfter = _blockTree.BestKnownNumber - level + 1; + long blocksAfter = (long)_blockTree.BestKnownNumber - (long)level + 1; if (blocksAfter >= minSealersForFinalization) { - return level + minSealersForFinalization - 1; + return level + (ulong)minSealersForFinalization - 1; } } @@ -339,12 +339,12 @@ public long GetLastLevelFinalizedBy(Hash256 blockHash) return null; } - private int GetMinSealersForFinalization(long blockNumber) => + private int GetMinSealersForFinalization(ulong blockNumber) => blockNumber == 0 ? 1 - : _validatorStore.GetValidators(blockNumber).MinSealersForFinalization(blockNumber >= twoThirdsMajorityTransition); + : _validatorStore.GetValidators(blockNumber).MinSealersForFinalization(blockNumber >= (ulong)twoThirdsMajorityTransition); - public long LastFinalizedBlockLevel + public ulong LastFinalizedBlockLevel { get => _lastFinalizedBlockLevel; private set @@ -393,7 +393,7 @@ public void Add(BlockHeader blockHeader) } } - public void RemoveAncestors(long blockNumber) + public void RemoveAncestors(ulong blockNumber) { for (int i = _blocks.Count - 1; i >= 0; i--) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProcessor.cs index de8f67445d45..57ed15da57f2 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProcessor.cs @@ -132,7 +132,7 @@ private BlockHeader GetParentHeader(Block block) => private void ValidateGasLimit(Block block) { BlockHeader parentHeader = GetParentHeader(block); - if (_gasLimitOverride?.IsGasLimitValid(parentHeader, block.GasLimit, out long? expectedGasLimit) == false) + if (_gasLimitOverride?.IsGasLimitValid(parentHeader, block.GasLimit, out ulong? expectedGasLimit) == false) { string reason = $"Invalid gas limit, expected value from contract {expectedGasLimit}, but found {block.GasLimit}"; if (_logger.IsWarn) _logger.Warn($"Proposed block is not valid {block.ToString(Block.Format.FullHashAndNumber)}. {reason}."); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs index d3faa4aa7ea8..9628d95d00d1 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs @@ -37,11 +37,11 @@ private static UInt256 MinimalContractGasLimit private readonly IGasLimitCalculator _innerCalculator = innerCalculator ?? throw new ArgumentNullException(nameof(innerCalculator)); private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - public long GetGasLimit(BlockHeader parentHeader) => GetGasLimitFromContract(parentHeader) ?? _innerCalculator.GetGasLimit(parentHeader); + public ulong GetGasLimit(BlockHeader parentHeader) => GetGasLimitFromContract(parentHeader) ?? _innerCalculator.GetGasLimit(parentHeader); - private long? GetGasLimitFromContract(BlockHeader parentHeader) + private ulong? GetGasLimitFromContract(BlockHeader parentHeader) { - if (_cache.GasLimitCache.TryGet(parentHeader.Hash, out long? gasLimit)) + if (_cache.GasLimitCache.TryGet(parentHeader.Hash, out ulong? gasLimit)) { return gasLimit; } @@ -49,7 +49,7 @@ private static UInt256 MinimalContractGasLimit if (_contracts.TryGetForBlock(parentHeader.Number + 1, out IBlockGasLimitContract contract)) { UInt256? contractLimit = GetContractGasLimit(parentHeader, contract); - gasLimit = contractLimit.HasValue ? (long)contractLimit.Value : (long?)null; + gasLimit = contractLimit.HasValue ? (ulong)contractLimit.Value : null; _cache.GasLimitCache.Set(parentHeader.Hash, gasLimit); if (gasLimit.HasValue) { @@ -89,10 +89,10 @@ public class Cache { private const int MaxCacheSize = 10; - internal LruCache GasLimitCache { get; } = new(MaxCacheSize, "BlockGasLimit"); + internal LruCache GasLimitCache { get; } = new(MaxCacheSize, "BlockGasLimit"); } - public bool IsGasLimitValid(BlockHeader parentHeader, in long gasLimit, out long? expectedGasLimit) + public bool IsGasLimitValid(BlockHeader parentHeader, in ulong gasLimit, out ulong? expectedGasLimit) { expectedGasLimit = GetGasLimitFromContract(parentHeader); return expectedGasLimit is null || expectedGasLimit == gasLimit; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaHeaderValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaHeaderValidator.cs index e2b1f84a0a44..565c48371f8a 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaHeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaHeaderValidator.cs @@ -15,7 +15,7 @@ namespace Nethermind.Consensus.AuRa { public class AuRaHeaderValidator : HeaderValidator { - private readonly IList _blockGasLimitContractTransitions; + private readonly IList _blockGasLimitContractTransitions; public AuRaHeaderValidator( IBlockTree blockTree, @@ -25,7 +25,7 @@ public AuRaHeaderValidator( AuRaChainSpecEngineParameters param) : base(blockTree, sealValidator, specProvider, logManager) { - long[] blockGasLimitContractTransitions = param.BlockGasLimitContractTransitions.Keys.ToArray(); + ulong[] blockGasLimitContractTransitions = param.BlockGasLimitContractTransitions.Keys.ToArray(); _blockGasLimitContractTransitions = blockGasLimitContractTransitions; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index 5b51e29e1f38..3b384a47813f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -143,7 +143,7 @@ protected override void Load(ContainerBuilder builder) { ITxFilter txFilter = txAuRaFilterBuilders.CreateAuRaTxFilter(new ServiceTxFilter()); - IDictionary> rewriteBytecode = parameters.RewriteBytecode; + IDictionary> rewriteBytecode = parameters.RewriteBytecode; (ulong, Address, byte[])[] rewriteBytecodeTimestamp = [.. parameters.RewriteBytecodeTimestampParsed]; ContractRewriter? contractRewriter = rewriteBytecode?.Count > 0 || rewriteBytecodeTimestamp?.Length > 0 ? new(rewriteBytecode, rewriteBytecodeTimestamp) : null; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs index dbf4529b65c5..ad3aae6c7b06 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs @@ -60,7 +60,7 @@ private Block Seal(Block block) return block; } - public bool CanSeal(long blockNumber, Hash256 parentHash) + public bool CanSeal(ulong blockNumber, Hash256 parentHash) { bool StepNotYetProduced(long step) => !_blockTree.Head.Header.AuRaStep.HasValue ? throw new InvalidOperationException("Head block doesn't have AuRaStep specified.'") diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs index 2d07bb15081f..e1bfa43e93ac 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs @@ -15,7 +15,7 @@ public class AuRaStepCalculator : IAuRaStepCalculator private readonly ITimestamper _timestamper; private readonly ILogger _logger; - public AuRaStepCalculator(IDictionary stepDurations, ITimestamper timestamper, ILogManager logManager) + public AuRaStepCalculator(IDictionary stepDurations, ITimestamper timestamper, ILogManager logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); ValidateStepDurations(stepDurations); @@ -27,8 +27,8 @@ public long CurrentStep { get { - long timestampSeconds = _timestamper.UnixTime.SecondsLong; - return GetStepInfo(timestampSeconds).GetCurrentStep(timestampSeconds); + ulong timestampSeconds = _timestamper.UnixTime.Seconds; + return (long)GetStepInfo(timestampSeconds).GetCurrentStep(timestampSeconds); } } @@ -37,8 +37,8 @@ public long CurrentStep public TimeSpan TimeToStep(long step) { UnixTime epoch = _timestamper.UnixTime; - StepDurationInfo currentStepInfo = GetStepInfo(epoch.SecondsLong); - long currentStep = currentStepInfo.GetCurrentStep(epoch.SecondsLong); + StepDurationInfo currentStepInfo = GetStepInfo(epoch.Seconds); + long currentStep = (long)currentStepInfo.GetCurrentStep(epoch.Seconds); if (step <= currentStep) { return TimeSpan.Zero; @@ -46,9 +46,9 @@ public TimeSpan TimeToStep(long step) else { TimeSpan timeToNextStep = new(GetTimeToNextStepInTicks(epoch, currentStepInfo)); - return timeToNextStep + TimeSpan.FromSeconds(currentStepInfo.StepDuration * (step - currentStep - 1)); + // Safe cast: StepDuration is capped at UInt16.MaxValue (65535) so fits in long + return timeToNextStep + TimeSpan.FromSeconds((long)currentStepInfo.StepDuration * (step - currentStep - 1)); } - } public long CurrentStepDuration @@ -56,7 +56,7 @@ public long CurrentStepDuration get { UnixTime epoch = _timestamper.UnixTime; - return GetStepInfo(epoch.SecondsLong).StepDuration; + return (long)GetStepInfo(epoch.Seconds).StepDuration; } } @@ -65,7 +65,7 @@ private long TimeToNextStepInTicks get { UnixTime unixTime = _timestamper.UnixTime; - StepDurationInfo currentStepInfo = GetStepInfo(unixTime.SecondsLong); + StepDurationInfo currentStepInfo = GetStepInfo(unixTime.Seconds); return GetTimeToNextStepInTicks(unixTime, currentStepInfo); } } @@ -77,12 +77,12 @@ private static long GetTimeToNextStepInTicks(UnixTime unixTime, StepDurationInfo return (currentStepInfo.StepDurationMilliseconds - timeAlreadyPassedToNextStep) * TimeSpan.TicksPerMillisecond; } - private StepDurationInfo GetStepInfo(long timestampInSeconds) => + private StepDurationInfo GetStepInfo(ulong timestampInSeconds) => _stepDurations.TryGetForActivation(timestampInSeconds, out StepDurationInfo currentStepInfo) ? currentStepInfo : throw new InvalidOperationException($"Couldn't find state step duration information at timestamp {timestampInSeconds}"); - private void ValidateStepDurations(IDictionary stepDurations) + private void ValidateStepDurations(IDictionary stepDurations) { if (stepDurations?.ContainsKey(0) != true) { @@ -94,7 +94,7 @@ private void ValidateStepDurations(IDictionary stepDurations) throw new ArgumentException("Authority Round step duration cannot be 0."); } - foreach (long key in stepDurations.Keys.ToArray()) + foreach (ulong key in stepDurations.Keys.ToArray()) { const ushort maxValue = UInt16.MaxValue; @@ -106,44 +106,44 @@ private void ValidateStepDurations(IDictionary stepDurations) } } - private static IList CreateStepDurations(IDictionary stepDurations) + private static IList CreateStepDurations(IDictionary stepDurations) { StepDurationInfo[] result = new StepDurationInfo[stepDurations.Count]; - KeyValuePair firstStep = stepDurations.First(); + KeyValuePair firstStep = stepDurations.First(); int index = 0; - StepDurationInfo previousStep = result[index++] = new StepDurationInfo(0, firstStep.Key, firstStep.Value); - foreach (KeyValuePair currentStep in stepDurations.Skip(1)) + StepDurationInfo previousStep = result[index++] = new StepDurationInfo(0, firstStep.Key, (ulong)firstStep.Value); + foreach (KeyValuePair currentStep in stepDurations.Skip(1)) { - long previousStepLength = currentStep.Key - previousStep.TransitionTimestamp; - long previousStepCount = previousStepLength / previousStep.StepDuration + (previousStepLength % previousStep.StepDuration > 0 ? 1 : 0); - long currentTransitionStep = previousStep.TransitionStep + previousStepCount; - long currentTransitionTimestamp = previousStep.TransitionTimestamp + previousStepCount * previousStep.StepDuration; - previousStep = result[index++] = new StepDurationInfo(currentTransitionStep, currentTransitionTimestamp, currentStep.Value); + ulong previousStepLength = currentStep.Key - previousStep.TransitionTimestamp; + ulong previousStepCount = previousStepLength / previousStep.StepDuration + (previousStepLength % previousStep.StepDuration > 0 ? 1UL : 0UL); + ulong currentTransitionStep = previousStep.TransitionStep + previousStepCount; + ulong currentTransitionTimestamp = previousStep.TransitionTimestamp + previousStepCount * previousStep.StepDuration; + previousStep = result[index++] = new StepDurationInfo(currentTransitionStep, currentTransitionTimestamp, (ulong)currentStep.Value); } return result; } - private class StepDurationInfo : IActivatedAt + private class StepDurationInfo : IActivatedAt { - public StepDurationInfo(long transitionStep, long transitionTimestamp, long stepDuration) + public StepDurationInfo(ulong transitionStep, ulong transitionTimestamp, ulong stepDuration) { const long millisecondsInSecond = 1000; TransitionStep = transitionStep; TransitionTimestamp = transitionTimestamp; StepDuration = stepDuration; - StepDurationMilliseconds = stepDuration * millisecondsInSecond; - TransitionTimestampMilliseconds = transitionTimestamp * millisecondsInSecond; + StepDurationMilliseconds = (long)stepDuration * millisecondsInSecond; + TransitionTimestampMilliseconds = (long)transitionTimestamp * millisecondsInSecond; } - public long TransitionStep { get; } - public long TransitionTimestamp { get; } + public ulong TransitionStep { get; } + public ulong TransitionTimestamp { get; } public long TransitionTimestampMilliseconds { get; } - public long StepDuration { get; } + public ulong StepDuration { get; } public long StepDurationMilliseconds { get; } - long IActivatedAt.Activation => TransitionTimestamp; + ulong IActivatedAt.Activation => TransitionTimestamp; - public long GetCurrentStep(in long timestampSeconds) => TransitionStep + (timestampSeconds - TransitionTimestamp) / StepDuration; + public ulong GetCurrentStep(in ulong timestampSeconds) => TransitionStep + (timestampSeconds - TransitionTimestamp) / StepDuration; } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs index cdb5f94b83a6..2053bb742f2f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaValidatorFactory.cs @@ -34,7 +34,7 @@ public class AuRaValidatorFactory(IAbiEncoder abiEncoder, ISpecProvider specProvider, IGasPriceOracle gasPriceOracle, ReportingContractBasedValidator.Cache reportingValidatorCache, - long posdaoTransition, bool forSealing = false) : IAuRaValidatorFactory + ulong posdaoTransition, bool forSealing = false) : IAuRaValidatorFactory { private readonly IWorldState _stateProvider = stateProvider; private readonly IAbiEncoder _abiEncoder = abiEncoder; @@ -52,16 +52,16 @@ public class AuRaValidatorFactory(IAbiEncoder abiEncoder, private readonly ISpecProvider _specProvider = specProvider; private readonly IGasPriceOracle _gasPriceOracle = gasPriceOracle; private readonly ReportingContractBasedValidator.Cache _reportingValidatorCache = reportingValidatorCache; - private readonly long _posdaoTransition = posdaoTransition; + private readonly ulong _posdaoTransition = posdaoTransition; private readonly bool _forSealing = forSealing; - public IAuRaValidator CreateValidatorProcessor(AuRaParameters.Validator validator, BlockHeader parentHeader = null, long? startBlock = null) + public IAuRaValidator CreateValidatorProcessor(AuRaParameters.Validator validator, BlockHeader parentHeader = null, ulong? startBlock = null) { IValidatorContract GetValidatorContract() => new ValidatorContract(_transactionProcessor, _abiEncoder, validator.GetContractAddress(), _stateProvider, _readOnlyTxProcessorSource, _signer); IReportingValidatorContract GetReportingValidatorContract() => new ReportingValidatorContract(_abiEncoder, validator.GetContractAddress(), _signer); ValidSealerStrategy validSealerStrategy = new(); - long startBlockNumber = startBlock ?? AuRaValidatorBase.DefaultStartBlockNumber; + ulong startBlockNumber = startBlock ?? AuRaValidatorBase.DefaultStartBlockNumber; ContractBasedValidator GetContractBasedValidator() => new( diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Config/AuRaChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Config/AuRaChainSpecEngineParameters.cs index 8808a739294e..473e25e04adb 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Config/AuRaChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Config/AuRaChainSpecEngineParameters.cs @@ -19,42 +19,42 @@ namespace Nethermind.Consensus.AuRa.Config; public class AuRaChainSpecEngineParameters : IChainSpecEngineParameters { - public const long TransitionDisabled = long.MaxValue; + public const ulong TransitionDisabled = ulong.MaxValue; public string? EngineName => "AuthorityRound"; public string? SealEngineType => Core.SealEngineType.AuRa; [JsonConverter(typeof(StepDurationJsonConverter))] - public SortedDictionary StepDuration { get; set; } = []; + public SortedDictionary StepDuration { get; set; } = []; [JsonConverter(typeof(BlockRewardConverter))] - public SortedDictionary? BlockReward { get; set; } + public SortedDictionary? BlockReward { get; set; } - public long? MaximumUncleCountTransition { get; set; } + public ulong? MaximumUncleCountTransition { get; set; } - public long? MaximumUncleCount { get; set; } + public ulong? MaximumUncleCount { get; set; } public Address? BlockRewardContractAddress { get; set; } - public long? BlockRewardContractTransition { get; set; } + public ulong? BlockRewardContractTransition { get; set; } - public IDictionary BlockRewardContractTransitions { get; set; } = new Dictionary(); + public IDictionary BlockRewardContractTransitions { get; set; } = new Dictionary(); - public long ValidateScoreTransition { get; set; } + public ulong ValidateScoreTransition { get; set; } - public long ValidateStepTransition { get; set; } + public ulong ValidateStepTransition { get; set; } [JsonPropertyName("Validators")] public AuRaValidatorJson ValidatorsJson { get; set; } - public IDictionary RandomnessContractAddress { get; set; } = new Dictionary(); + public IDictionary RandomnessContractAddress { get; set; } = new Dictionary(); - public IDictionary BlockGasLimitContractTransitions { get; set; } = new Dictionary(); + public IDictionary BlockGasLimitContractTransitions { get; set; } = new Dictionary(); - public long TwoThirdsMajorityTransition { get; set; } = TransitionDisabled; + public ulong TwoThirdsMajorityTransition { get; set; } = TransitionDisabled; - public long PosdaoTransition { get; set; } = TransitionDisabled; + public ulong PosdaoTransition { get; set; } = TransitionDisabled; - public IDictionary> RewriteBytecode { get; set; } = new Dictionary>(); + public IDictionary> RewriteBytecode { get; set; } = new Dictionary>(); public IDictionary> RewriteBytecodeTimestamp { get; set; } = new Dictionary>(); public IEnumerable<(ulong, Address, byte[])> RewriteBytecodeTimestampParsed @@ -81,13 +81,13 @@ public AuRaParameters.Validator Validators get => _validators ??= LoadValidator(ValidatorsJson); } - public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) + public void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) { - spec.MaximumUncleCount = (int)(startBlock >= (MaximumUncleCountTransition ?? long.MaxValue) ? MaximumUncleCount ?? 2 : 2); + spec.MaximumUncleCount = (int)(startBlock >= (MaximumUncleCountTransition ?? ulong.MaxValue) ? MaximumUncleCount ?? 2 : 2); spec.Eip158IgnoredAccount = Address.SystemUser; } - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) => timestamps.AddRange(RewriteBytecodeTimestamp.Keys); + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) => timestamps.AddRange(RewriteBytecodeTimestamp.Keys); static AuRaParameters.Validator LoadValidator(AuRaValidatorJson validatorJson, int level = 0) { @@ -117,13 +117,13 @@ static AuRaParameters.Validator LoadValidator(AuRaValidatorJson validatorJson, i return validator; } - private class StepDurationJsonConverter : JsonConverter> + private class StepDurationJsonConverter : JsonConverter> { - public override void Write(Utf8JsonWriter writer, SortedDictionary value, JsonSerializerOptions options) => throw new NotSupportedException(); + public override void Write(Utf8JsonWriter writer, SortedDictionary value, JsonSerializerOptions options) => throw new NotSupportedException(); - public override SortedDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override SortedDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - SortedDictionary value = []; + SortedDictionary value = []; if (reader.TokenType == JsonTokenType.String) { value.Add(0, JsonSerializer.Deserialize(ref reader, options)); @@ -141,7 +141,7 @@ public override SortedDictionary Read(ref Utf8JsonReader reader, Typ { throw new ArgumentException("Cannot deserialize BlockReward."); } - long key = long.Parse(reader.GetString()); + ulong key = ulong.Parse(reader.GetString()); reader.Read(); if (reader.TokenType == JsonTokenType.String) { @@ -173,7 +173,7 @@ public class AuRaValidatorJson public Address[]? List { get; set; } public Address? Contract { get; set; } public Address? SafeContract { get; set; } - public Dictionary Multi { get; set; } = []; + public Dictionary Multi { get; set; } = []; public AuRaParameters.ValidatorType GetValidatorType() { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/ContractRewriter.cs b/src/Nethermind/Nethermind.Consensus.AuRa/ContractRewriter.cs index a0d55dae6113..80e3a4adffef 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/ContractRewriter.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/ContractRewriter.cs @@ -9,13 +9,13 @@ namespace Nethermind.Consensus.AuRa; public class ContractRewriter( - IDictionary> contractOverrides, + IDictionary> contractOverrides, (ulong, Address, byte[])[] contractOverridesTimestamp) { - private readonly IDictionary> _contractOverrides = contractOverrides; + private readonly IDictionary> _contractOverrides = contractOverrides; private readonly (ulong, Address, byte[])[] _contractOverridesTimestamp = contractOverridesTimestamp; - public bool RewriteContracts(long blockNumber, IWorldState stateProvider, IReleaseSpec spec) + public bool RewriteContracts(ulong blockNumber, IWorldState stateProvider, IReleaseSpec spec) { bool result = false; if (_contractOverrides.TryGetValue(blockNumber, out IDictionary overrides)) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs index 07b4752d7c4a..e3bd96eb43f5 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/BlockGasLimitContract.cs @@ -18,12 +18,12 @@ public interface IBlockGasLimitContract : IActivatedAtBlock public sealed class BlockGasLimitContract : Contract, IBlockGasLimitContract { private IConstantContract Constant { get; } - public long Activation { get; } + public ulong Activation { get; } public BlockGasLimitContract( IAbiEncoder abiEncoder, Address contractAddress, - long transitionBlock, + ulong transitionBlock, IReadOnlyTxProcessorSource readOnlyTxProcessorSource) : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs index 31a888f3ebf3..1423a70aec64 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RandomContract.cs @@ -80,7 +80,7 @@ public RandomContract( IAbiEncoder abiEncoder, Address contractAddress, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, - long transitionBlock, + ulong transitionBlock, ISigner signer) : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) { @@ -89,7 +89,7 @@ public RandomContract( Constant = GetConstant(readOnlyTxProcessorSource); } - public long Activation { get; } + public ulong Activation { get; } public (IRandomContract.Phase Phase, UInt256 Round) GetPhase(BlockHeader parentHeader) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs index 14bdfd213ea5..9ca4f9e8bdf0 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RegisterBasedContract.cs @@ -18,7 +18,7 @@ public class RegisterBasedContract( private readonly string _registryKey = registryKey; private Hash256 _currentHashAddress = Keccak.Zero; - protected override Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address sender, long gasLimit = DefaultContractGasLimit, BlockHeader header = null) => GenerateTransaction(GetContractAddress(header), transactionData, sender, gasLimit); + protected override Transaction GenerateTransaction(Address? contractAddress, byte[] transactionData, Address sender, ulong gasLimit = DefaultContractGasLimit, BlockHeader? header = null) => GenerateTransaction(GetContractAddress(header), transactionData, sender, gasLimit); private Address GetContractAddress(BlockHeader? header) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs index 2c9437c41e94..be8804097ad2 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/RewardContract.cs @@ -30,9 +30,9 @@ public interface IRewardContract : IActivatedAtBlock (Address[] Addresses, UInt256[] Rewards) Reward(BlockHeader blockHeader, Address[] benefactors, ushort[] kind); } - public sealed class RewardContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, long transitionBlock) : CallableContract(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))), IRewardContract + public sealed class RewardContract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, ulong transitionBlock) : CallableContract(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))), IRewardContract { - public long Activation { get; } = transitionBlock; + public ulong Activation { get; } = transitionBlock; /// /// produce rewards for the given benefactors, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs index 4b4af0944e2b..45fdf1633749 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TransactionPermissionContractV3.cs @@ -28,7 +28,7 @@ protected override object[] GetAllowedTxTypesParameters(Transaction tx, BlockHea // _gasPrice Gas price in wei for the transaction. // _data Transaction data. - long number = (parentHeader?.Number ?? 0) + 1; + ulong number = (parentHeader?.Number ?? 0) + 1; bool isEip1559Enabled = _specProvider.GetSpecFor1559(number).IsEip1559Enabled; UInt256 gasPrice = isEip1559Enabled && tx.Supports1559 ? tx.MaxFeePerGas : tx.GasPrice; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.Destination.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.Destination.cs index c141b2753301..143f30db51ae 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.Destination.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/TxPriorityContract.Destination.cs @@ -25,17 +25,17 @@ public struct Destination( byte[] fnSignature, UInt256 value, TxPriorityContract.DestinationSource source = TxPriorityContract.DestinationSource.Contract, - long blockNumber = 0) : IEqualityComparer + ulong blockNumber = 0) : IEqualityComparer { public static byte[] FnSignatureEmpty = new byte[4]; public Address Target { get; set; } = target; public byte[] FnSignature { get; set; } = fnSignature; public UInt256 Value { get; set; } = value; - public long BlockNumber { get; set; } = blockNumber; + public ulong BlockNumber { get; set; } = blockNumber; public DestinationSource Source { get; set; } = source; - public static Destination FromAbiTuple(DestinationTuple tuple, long blockNumber) => + public static Destination FromAbiTuple(DestinationTuple tuple, ulong blockNumber) => new(tuple.Item1, tuple.Item2, tuple.Item3, DestinationSource.Contract, blockNumber); public static implicit operator DestinationTuple(Destination destination) => diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedContract.cs index 2a783daaaaf7..5470f36ce3ec 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedContract.cs @@ -13,7 +13,7 @@ namespace Nethermind.Consensus.AuRa.Contracts { - public abstract class VersionedContract(IDictionary versions, LruCache cache, long activation, ILogManager logManager) : IActivatedAtBlock where T : IVersionedContract + public abstract class VersionedContract(IDictionary versions, LruCache cache, ulong activation, ILogManager logManager) : IActivatedAtBlock where T : IVersionedContract { private readonly IDictionary _versions = versions ?? throw new ArgumentNullException(nameof(versions)); @@ -45,6 +45,6 @@ public abstract class VersionedContract(IDictionary versions, Lru private T? ResolveVersion(in UInt256 versionNumber) => _versions.TryGetValue(versionNumber, out T contract) ? contract : default; - public long Activation { get; } = activation; + public ulong Activation { get; } = activation; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs index 4714e42767e6..d1a5cdee44fe 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/VersionedTransactionPermissionContract.cs @@ -15,7 +15,7 @@ namespace Nethermind.Consensus.AuRa.Contracts { public class VersionedTransactionPermissionContract(IAbiEncoder abiEncoder, Address contractAddress, - long activation, + ulong activation, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, LruCache cache, ILogManager logManager, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/IActivatedAt.cs b/src/Nethermind/Nethermind.Consensus.AuRa/IActivatedAt.cs index 7470607fcd90..24574c86364d 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/IActivatedAt.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/IActivatedAt.cs @@ -13,13 +13,13 @@ public interface IActivatedAt where T : IComparable T Activation { get; } } - public interface IActivatedAt : IActivatedAt + public interface IActivatedAt : IActivatedAt { } public interface IActivatedAtBlock : IActivatedAt { - public long ActivationBlock => Activation; + public ulong ActivationBlock => Activation; } /// diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaBlockFinalizationManager.cs index 5dbeb196ffe1..4f2a00c25b5d 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaBlockFinalizationManager.cs @@ -15,14 +15,14 @@ public interface IAuRaBlockFinalizationManager : IBlockFinalizationManager /// Hash of block /// Last level that was finalized by block hash. /// This is used when we have nonconsecutive block processing, like just switching from Fast to Full sync or when producing blocks. It is used when trying to find a non-finalized InitChange event. - long GetLastLevelFinalizedBy(Hash256 blockHash); + ulong GetLastLevelFinalizedBy(Hash256 blockHash); /// /// Gets level ath which the certain level was finalized. /// /// Level to check when was finalized. /// Level at which finalization happened. Null if checked level is not yet finalized. - long? GetFinalizationLevel(long level); + ulong? GetFinalizationLevel(ulong level); public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor); } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaValidatorFactory.cs b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaValidatorFactory.cs index 1859963e5258..5c588bc67e80 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaValidatorFactory.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaValidatorFactory.cs @@ -8,6 +8,6 @@ namespace Nethermind.Consensus.AuRa { public interface IAuRaValidatorFactory { - IAuRaValidator CreateValidatorProcessor(AuRaParameters.Validator validator, BlockHeader parentHeader, long? startBlock = null); + IAuRaValidator CreateValidatorProcessor(AuRaParameters.Validator validator, BlockHeader parentHeader, ulong? startBlock = null); } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaGasLimitOverrideFactory.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaGasLimitOverrideFactory.cs index ee52228e56df..ca049c5ae202 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaGasLimitOverrideFactory.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaGasLimitOverrideFactory.cs @@ -26,7 +26,7 @@ public class AuRaGasLimitOverrideFactory( { public AuRaContractGasLimitOverride? GetGasLimitCalculator() { - IDictionary blockGasLimitContractTransitions = parameters.BlockGasLimitContractTransitions; + IDictionary blockGasLimitContractTransitions = parameters.BlockGasLimitContractTransitions; if (blockGasLimitContractTransitions?.Any() == true) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs index ba86ee9257b3..e12e0e359630 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs @@ -158,7 +158,7 @@ private BlockProcessor CreateBlockProcessor(ITransactionProcessor txProcessor, I disposeStack.Push(disposableValidator); } - IDictionary> rewriteBytecode = _parameters.RewriteBytecode; + IDictionary> rewriteBytecode = _parameters.RewriteBytecode; (ulong, Address, byte[])[] rewriteBytecodeTimestamp = [.. _parameters.RewriteBytecodeTimestampParsed]; ContractRewriter? contractRewriter = rewriteBytecode?.Count > 0 || rewriteBytecodeTimestamp?.Length > 0 ? new(rewriteBytecode, rewriteBytecodeTimestamp) : null; @@ -287,7 +287,7 @@ BlockProducerEnv Create() private ITxSource CreateTxSourceForProducer() { - bool CheckAddPosdaoTransactions(IList list, long auRaPosdaoTransition) + bool CheckAddPosdaoTransactions(IList list, ulong auRaPosdaoTransition) { if (auRaPosdaoTransition != AuRaChainSpecEngineParameters.TransitionDisabled && _validator is ITxSource validatorSource) { @@ -298,10 +298,10 @@ bool CheckAddPosdaoTransactions(IList list, long auRaPosdaoTransition return false; } - bool CheckAddRandomnessTransactions(IList list, IDictionary? randomnessContractAddress, ISigner signer) + bool CheckAddRandomnessTransactions(IList list, IDictionary? randomnessContractAddress, ISigner signer) { IList GetRandomContracts( - IDictionary randomnessContractAddressPerBlock, + IDictionary randomnessContractAddressPerBlock, IAbiEncoder abiEncoder, IReadOnlyTxProcessorSource txProcessorSource, ISigner signerLocal) => diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/ListExtensions.cs b/src/Nethermind/Nethermind.Consensus.AuRa/ListExtensions.cs index c3e83fee06bc..0bc317f80e7c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/ListExtensions.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/ListExtensions.cs @@ -21,7 +21,7 @@ public static class ListExtensions public static bool TryGetForActivation(this IList list, in TComparable activation, out T item) where T : IActivatedAt where TComparable : IComparable => list.TryGetSearchedItem(activation, static (b, c) => b.CompareTo(c.Activation), out item); - public static bool TryGetForBlock(this IList list, in long blockNumber, out T item) where T : IActivatedAtBlock => + public static bool TryGetForBlock(this IList list, in ulong blockNumber, out T item) where T : IActivatedAtBlock => list.TryGetSearchedItem(blockNumber, static (b, c) => b.CompareTo(c.ActivationBlock), out item); } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs index 6d012ff97cbb..a2bd8fc6c1f3 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/AuRaRewardCalculator.cs @@ -32,13 +32,13 @@ IList BuildTransitions() if (auRaParameters.BlockRewardContractTransitions is not null) { contracts.AddRange(auRaParameters.BlockRewardContractTransitions.Select(t => new RewardContract(transactionProcessor, abiEncoder, t.Value, t.Key))); - CollectionsMarshal.AsSpan(contracts).Sort(default(ActivatedAtComparer)); + CollectionsMarshal.AsSpan(contracts).Sort(default(ActivatedAtComparer)); } if (auRaParameters.BlockRewardContractAddress is not null) { - long contractTransition = auRaParameters.BlockRewardContractTransition ?? 0; - if (contractTransition > (contracts.FirstOrDefault()?.Activation ?? long.MaxValue)) + ulong contractTransition = auRaParameters.BlockRewardContractTransition ?? 0; + if (contractTransition > (contracts.FirstOrDefault()?.Activation ?? ulong.MaxValue)) { throw new ArgumentException($"{nameof(auRaParameters.BlockRewardContractTransition)} provided for {nameof(auRaParameters.BlockRewardContractAddress)} is higher than first {nameof(auRaParameters.BlockRewardContractTransitions)}."); } @@ -121,7 +121,7 @@ public static class BenefactorKind private const ushort minDistance = 1; private const ushort maxDistance = 6; - public static bool TryGetUncle(long distance, out ushort kind) + public static bool TryGetUncle(ulong distance, out ushort kind) { if (IsValidDistance(distance)) { @@ -138,11 +138,12 @@ public static bool TryGetUncle(long distance, out ushort kind) Author => BlockRewardType.Block, External => BlockRewardType.External, EmptyStep => BlockRewardType.EmptyStep, - ushort uncle when IsValidDistance(uncle - uncleOffset) => BlockRewardType.Uncle, + // Safe cast: uncle - uncleOffset is always non-negative here since the pattern only matches uncle >= uncleOffset + ushort uncle when IsValidDistance((ulong)(uncle - uncleOffset)) => BlockRewardType.Uncle, _ => throw new ArgumentException($"Invalid BlockRewardType for kind {kind}", nameof(kind)), }; - private static bool IsValidDistance(long distance) => distance >= minDistance && distance <= maxDistance; + private static bool IsValidDistance(ulong distance) => distance >= minDistance && distance <= maxDistance; } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/StaticRewardCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/StaticRewardCalculator.cs index 9c48ba0086cc..83147b89c394 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/StaticRewardCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Rewards/StaticRewardCalculator.cs @@ -9,7 +9,7 @@ namespace Nethermind.Consensus.AuRa.Rewards { - public class StaticRewardCalculator(IDictionary? blockRewards) : IRewardCalculator + public class StaticRewardCalculator(IDictionary? blockRewards) : IRewardCalculator { private readonly IList _blockRewards = CreateBlockRewards(blockRewards); @@ -19,7 +19,7 @@ public BlockReward[] CalculateRewards(Block block) return new[] { new BlockReward(block.Beneficiary, blockReward.Reward) }; } - private static IList CreateBlockRewards(IDictionary? blockRewards) + private static IList CreateBlockRewards(IDictionary? blockRewards) { List blockRewardInfos = []; if (blockRewards?.Count > 0) @@ -28,7 +28,7 @@ private static IList CreateBlockRewards(IDictionary threshold in blockRewards) + foreach (KeyValuePair threshold in blockRewards) { blockRewardInfos.Add(new BlockRewardInfo(threshold.Key, threshold.Value)); } @@ -40,12 +40,12 @@ private static IList CreateBlockRewards(IDictionary.Activation => BlockNumber; + ulong IActivatedAt.Activation => BlockNumber; } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs index 24d3167a0f4f..5345b206e9d6 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs @@ -20,11 +20,11 @@ public class GeneratedTxSource(ITxSource innerSource, ITxSealer txSealer, IState private readonly ITxSealer _txSealer = txSealer ?? throw new ArgumentNullException(nameof(txSealer)); private readonly IStateReader _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - private readonly IDictionary _nonces = new Dictionary(1); + private readonly IDictionary _nonces = new Dictionary(1); public bool SupportsBlobs => _innerSource.SupportsBlobs; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) { _nonces.Clear(); @@ -52,11 +52,11 @@ public IEnumerable GetTransactions(BlockHeader parent, long gasLimi } } - private UInt256 CalculateNonce(Address address, BlockHeader baseBlock, IDictionary nonces) + private ulong CalculateNonce(Address address, BlockHeader baseBlock, IDictionary nonces) { - if (!nonces.TryGetValue(address, out UInt256 nonce)) + if (!nonces.TryGetValue(address, out ulong nonce)) { - nonce = _stateReader.GetNonce(baseBlock, address); + nonce = (ulong)_stateReader.GetNonce(baseBlock, address); } nonces[address] = nonce + 1; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/RandomContractTxSource.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/RandomContractTxSource.cs index de8e9fa10752..571e0ce2f260 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/RandomContractTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/RandomContractTxSource.cs @@ -40,7 +40,7 @@ public class RandomContractTxSource( public bool SupportsBlobs => false; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttribute, bool filterSources) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttribute, bool filterSources) { if (_contracts.TryGetForBlock(parent.Number + 1, out IRandomContract contract)) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs index d4529485a37a..384c513092ea 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TransactionExtensions.cs @@ -12,11 +12,11 @@ public static bool IsZeroGasPrice(this Transaction tx, IReleaseSpec releaseSpec) { bool isEip1559Enabled = releaseSpec.IsEip1559Enabled; bool checkByFeeCap = isEip1559Enabled && tx.Supports1559; - if (checkByFeeCap && !tx.MaxFeePerGas.IsZero) // only 0 gas price transactions are system transactions and can be whitelisted + if (checkByFeeCap && tx.GasPrice != 0) // only 0 gas price transactions are system transactions and can be whitelisted { return false; } - else if (!tx.GasPrice.IsZero && !checkByFeeCap) + else if (tx.GasPrice != 0 && !checkByFeeCap) { return false; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxGasPriceSender.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxGasPriceSender.cs index 3fb5639cdda1..bc3d7650a8c7 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxGasPriceSender.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxGasPriceSender.cs @@ -23,7 +23,9 @@ public class TxGasPriceSender( public async ValueTask<(Hash256, AcceptTxResult?)> SendTransaction(Transaction tx, TxHandlingOptions txHandlingOptions) { - UInt256 gasPriceEstimated = await _gasPriceOracle.GetGasPriceEstimate() * _percentDelta / 100; + UInt256 gasPrice = await _gasPriceOracle.GetGasPriceEstimate(); + // Safe cast: gas prices exceeding ulong.MaxValue (~1.8e19 wei/gas) are economically impossible + ulong gasPriceEstimated = (ulong)(gasPrice * _percentDelta / 100); tx.DecodedMaxFeePerGas = gasPriceEstimated; tx.GasPrice = gasPriceEstimated; return await _txSender.SendTransaction(tx, txHandlingOptions); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxPriorityTxSource.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxPriorityTxSource.cs index dac6c6eeec0f..4450aeafc30c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxPriorityTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/TxPriorityTxSource.cs @@ -41,7 +41,7 @@ protected override IComparer GetComparer(BlockHeader parent, BlockP public override string ToString() => $"{nameof(TxPriorityTxSource)}"; - protected override IEnumerable GetOrderedTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, long gasLimit) + protected override IEnumerable GetOrderedTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, ulong gasLimit) { if (_logger.IsTrace) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaParameters.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaParameters.cs index 4c6eb60061b1..00dc01f7ecf2 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaParameters.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaParameters.cs @@ -30,7 +30,7 @@ public class Validator /// /// This has to sorted in order of starting blocks. /// - public IDictionary? Validators { get; set; } + public IDictionary? Validators { get; set; } /// /// Addresses for validator. diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs index a2820ba9eee6..d83caf208da7 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs @@ -13,17 +13,17 @@ public abstract class AuRaValidatorBase( IValidSealerStrategy validSealerStrategy, IValidatorStore validatorStore, ILogManager logManager, - long startBlockNumber, + ulong startBlockNumber, bool forSealing) : IAuRaValidator { - public const long DefaultStartBlockNumber = 1; + public const ulong DefaultStartBlockNumber = 1; private readonly IValidSealerStrategy _validSealerStrategy = validSealerStrategy ?? throw new ArgumentNullException(nameof(validSealerStrategy)); private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); public Address[] Validators { get; protected internal set; } - protected long InitBlockNumber { get; } = startBlockNumber; + protected ulong InitBlockNumber { get; } = startBlockNumber; protected internal bool ForSealing { get; } = forSealing; protected IValidatorStore ValidatorStore { get; } = validatorStore ?? throw new ArgumentNullException(nameof(validatorStore)); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.Posdao.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.Posdao.cs index c7b3edded3a3..f149e55d7aba 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.Posdao.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.Posdao.cs @@ -11,15 +11,15 @@ namespace Nethermind.Consensus.AuRa.Validators { public partial class ContractBasedValidator : ITxSource { - private readonly long _posdaoTransition; + private readonly ulong _posdaoTransition; public bool SupportsBlobs => false; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) { if (ForSealing) { - long newBlockNumber = parent.Number + 1; + ulong newBlockNumber = parent.Number + 1; if (newBlockNumber < _posdaoTransition) { if (_logger.IsTrace) _logger.Trace("Skipping a call to emitInitiateChange"); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs index 0d2f0e4694be..a58235ab6e08 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs @@ -21,7 +21,7 @@ public partial class ContractBasedValidator : AuRaValidatorBase, IDisposable private readonly ILogger _logger; private PendingValidators _currentPendingValidators; - private long? _lastProcessedBlockNumber = null; + private ulong? _lastProcessedBlockNumber = null; private Hash256? _lastProcessedBlockHash = null; private IAuRaBlockFinalizationManager _blockFinalizationManager; internal IBlockTree BlockTree { get; } @@ -38,8 +38,8 @@ public ContractBasedValidator( IAuRaBlockFinalizationManager finalizationManager, BlockHeader parentHeader, ILogManager logManager, - long startBlockNumber, - long posdaoTransition = long.MaxValue, + ulong startBlockNumber, + ulong posdaoTransition = ulong.MaxValue, bool forSealing = false) : base(validSealerStrategy, validatorStore, logManager, startBlockNumber, forSealing) { BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); @@ -135,8 +135,8 @@ public override void OnBlockProcessingStart(Block block, ProcessingOptions optio private PendingValidators TryGetInitChangeFromPastBlocks(Hash256 blockHash) { PendingValidators pendingValidators = null; - long lastFinalized = _blockFinalizationManager.GetLastLevelFinalizedBy(blockHash); - long toBlock = Math.Max(lastFinalized, InitBlockNumber); + ulong lastFinalized = _blockFinalizationManager.GetLastLevelFinalizedBy(blockHash); + ulong toBlock = Math.Max(lastFinalized, InitBlockNumber); Block block = BlockTree.FindBlock(blockHash, BlockTreeLookupOptions.None); while (block?.Number >= toBlock) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IReportingValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IReportingValidator.cs index efd865f8d152..122b230627ce 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IReportingValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IReportingValidator.cs @@ -7,8 +7,8 @@ namespace Nethermind.Consensus.AuRa.Validators { public interface IReportingValidator { - void ReportMalicious(Address validator, long blockNumber, byte[] proof, MaliciousCause cause); - void ReportBenign(Address validator, long blockNumber, BenignCause cause); + void ReportMalicious(Address validator, ulong blockNumber, byte[] proof, MaliciousCause cause); + void ReportBenign(Address validator, ulong blockNumber, BenignCause cause); void TryReportSkipped(BlockHeader header, BlockHeader parent); public enum BenignCause diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidatorStore.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidatorStore.cs index 2d362b300a3c..605ca8e23b91 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidatorStore.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidatorStore.cs @@ -7,10 +7,10 @@ namespace Nethermind.Consensus.AuRa.Validators { public interface IValidatorStore { - void SetValidators(long finalizingBlockNumber, Address[] validators); + void SetValidators(ulong finalizingBlockNumber, Address[] validators); - Address[] GetValidators(in long? blockNumber = null); - ValidatorInfo GetValidatorsInfo(in long? blockNumber = null); + Address[] GetValidators(in ulong? blockNumber = null); + ValidatorInfo GetValidatorsInfo(in ulong? blockNumber = null); PendingValidators PendingValidators { get; set; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ListBasedValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ListBasedValidator.cs index 50917a775c60..deeda6d133a8 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ListBasedValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ListBasedValidator.cs @@ -8,7 +8,7 @@ namespace Nethermind.Consensus.AuRa.Validators { public sealed class ListBasedValidator : AuRaValidatorBase { - public ListBasedValidator(AuRaParameters.Validator validator, IValidSealerStrategy validSealerStrategy, IValidatorStore validatorStore, ILogManager logManager, long startBlockNumber, bool forSealing = false) + public ListBasedValidator(AuRaParameters.Validator validator, IValidSealerStrategy validSealerStrategy, IValidatorStore validatorStore, ILogManager logManager, ulong startBlockNumber, bool forSealing = false) : base(validSealerStrategy, validatorStore, logManager, startBlockNumber, forSealing) { ArgumentNullException.ThrowIfNull(validator); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/MultiValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/MultiValidator.cs index 2995fe7bad50..e8560db8ea17 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/MultiValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/MultiValidator.cs @@ -20,11 +20,11 @@ public class MultiValidator : IAuRaValidator, IReportingValidator, ITxSource, ID private readonly IValidatorStore _validatorStore; private readonly bool _forSealing; private IAuRaBlockFinalizationManager _blockFinalizationManager; - private readonly IDictionary _validators; + private readonly IDictionary _validators; private readonly ILogger _logger; private IAuRaValidator _currentValidator; private AuRaParameters.Validator _currentValidatorPrototype; - private long _lastProcessedBlock = 0; + private ulong _lastProcessedBlock = 0; public bool SupportsBlobs => false; @@ -55,9 +55,9 @@ public MultiValidator( public Address[] Validators => _currentValidator?.Validators; - private void InitCurrentValidator(long blockNumber, BlockHeader parentHeader) + private void InitCurrentValidator(ulong blockNumber, BlockHeader parentHeader) { - if (TryGetLastValidator(blockNumber, out KeyValuePair validatorInfo)) + if (TryGetLastValidator(blockNumber, out KeyValuePair validatorInfo)) { SetCurrentValidator(validatorInfo, parentHeader); } @@ -65,14 +65,14 @@ private void InitCurrentValidator(long blockNumber, BlockHeader parentHeader) _lastProcessedBlock = blockNumber; } - private bool TryGetLastValidator(long blockNum, out KeyValuePair validator) + private bool TryGetLastValidator(ulong blockNum, out KeyValuePair validator) { - long headNumber = _blockTree.Head?.Number ?? 0; + ulong headNumber = _blockTree.Head?.Number ?? 0; validator = default; bool found = false; - foreach (KeyValuePair kvp in _validators) + foreach (KeyValuePair kvp in _validators) { if (kvp.Key <= blockNum || kvp.Key <= headNumber && kvp.Value.ValidatorType.CanChangeImmediately()) { @@ -104,15 +104,15 @@ public void OnBlockProcessingStart(Block block, ProcessingOptions options = Proc { if (!block.IsGenesis) { - bool ValidatorWasAlreadyFinalized(KeyValuePair validatorInfo) => _blockFinalizationManager.LastFinalizedBlockLevel >= validatorInfo.Key; + bool ValidatorWasAlreadyFinalized(KeyValuePair validatorInfo) => _blockFinalizationManager.LastFinalizedBlockLevel >= validatorInfo.Key; bool isProducingBlock = options.ContainsFlag(ProcessingOptions.ProducingBlock); - long previousBlockNumber = block.Number - 1; + ulong previousBlockNumber = block.Number - 1; bool isNotConsecutive = previousBlockNumber != _lastProcessedBlock; if (isProducingBlock || isNotConsecutive) { - if (TryGetLastValidator(previousBlockNumber, out KeyValuePair validatorInfo)) + if (TryGetLastValidator(previousBlockNumber, out KeyValuePair validatorInfo)) { BlockHeader parentHeader = _blockTree.FindParentHeader(block.Header, BlockTreeLookupOptions.None); if (validatorInfo.Value.ValidatorType.CanChangeImmediately() || ValidatorWasAlreadyFinalized(validatorInfo)) @@ -121,8 +121,8 @@ public void OnBlockProcessingStart(Block block, ProcessingOptions options = Proc } else if (!isProducingBlock) { - bool canSetValidatorAsCurrent = !TryGetLastValidator(validatorInfo.Key - 1, out KeyValuePair previousValidatorInfo); - long? finalizedAtBlockNumber = null; + bool canSetValidatorAsCurrent = !TryGetLastValidator(validatorInfo.Key - 1, out KeyValuePair previousValidatorInfo); + ulong? finalizedAtBlockNumber = null; if (!canSetValidatorAsCurrent) { SetCurrentValidator(previousValidatorInfo, parentHeader); @@ -142,7 +142,7 @@ public void OnBlockProcessingStart(Block block, ProcessingOptions options = Proc _currentValidator?.OnBlockProcessingStart(block, options); } - private bool TryGetValidator(long blockNumber, out AuRaParameters.Validator validator) => _validators.TryGetValue(blockNumber, out validator); + private bool TryGetValidator(ulong blockNumber, out AuRaParameters.Validator validator) => _validators.TryGetValue(blockNumber, out validator); public void OnBlockProcessingEnd(Block block, TxReceipt[] receipts, ProcessingOptions options = ProcessingOptions.None) { @@ -175,9 +175,9 @@ public void SetFinalizationManager(IAuRaBlockFinalizationManager finalizationMan public void Dispose() => _blockFinalizationManager.BlocksFinalized -= OnBlocksFinalized; - private void SetCurrentValidator(KeyValuePair validatorInfo, BlockHeader parentHeader) => SetCurrentValidator(validatorInfo.Key, validatorInfo.Value, parentHeader); + private void SetCurrentValidator(KeyValuePair validatorInfo, BlockHeader parentHeader) => SetCurrentValidator(validatorInfo.Key, validatorInfo.Value, parentHeader); - private void SetCurrentValidator(long finalizedAtBlockNumber, AuRaParameters.Validator validatorPrototype, BlockHeader parentHeader) + private void SetCurrentValidator(ulong finalizedAtBlockNumber, AuRaParameters.Validator validatorPrototype, BlockHeader parentHeader) { if (validatorPrototype != _currentValidatorPrototype) { @@ -199,16 +199,16 @@ private void SetCurrentValidator(long finalizedAtBlockNumber, AuRaParameters.Val } } - private IAuRaValidator CreateValidator(long finalizedAtBlockNumber, AuRaParameters.Validator validatorPrototype, BlockHeader parentHeader) => + private IAuRaValidator CreateValidator(ulong finalizedAtBlockNumber, AuRaParameters.Validator validatorPrototype, BlockHeader parentHeader) => _validatorFactory.CreateValidatorProcessor(validatorPrototype, parentHeader, finalizedAtBlockNumber + 1); - public void ReportMalicious(Address validator, long blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) => _currentValidator.GetReportingValidator().ReportMalicious(validator, blockNumber, proof, cause); + public void ReportMalicious(Address validator, ulong blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) => _currentValidator.GetReportingValidator().ReportMalicious(validator, blockNumber, proof, cause); - public void ReportBenign(Address validator, long blockNumber, IReportingValidator.BenignCause cause) => _currentValidator.GetReportingValidator().ReportBenign(validator, blockNumber, cause); + public void ReportBenign(Address validator, ulong blockNumber, IReportingValidator.BenignCause cause) => _currentValidator.GetReportingValidator().ReportBenign(validator, blockNumber, cause); public void TryReportSkipped(BlockHeader header, BlockHeader parent) => _currentValidator.GetReportingValidator().TryReportSkipped(header, parent); - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => _currentValidator is ITxSource txSource ? txSource.GetTransactions(parent, gasLimit, payloadAttributes, filterSource) : []; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/NullReportingValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/NullReportingValidator.cs index 6a6b4fc5276c..094c25540999 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/NullReportingValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/NullReportingValidator.cs @@ -8,8 +8,8 @@ namespace Nethermind.Consensus.AuRa.Validators public class NullReportingValidator : IReportingValidator { public static NullReportingValidator Instance { get; } = new NullReportingValidator(); - public void ReportMalicious(Address validator, long blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) { } - public void ReportBenign(Address validator, long blockNumber, IReportingValidator.BenignCause cause) { } + public void ReportMalicious(Address validator, ulong blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) { } + public void ReportBenign(Address validator, ulong blockNumber, IReportingValidator.BenignCause cause) { } public void TryReportSkipped(BlockHeader header, BlockHeader parent) { } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs index 77a5d8f1a48f..b8f3eb2ab0e6 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs @@ -7,12 +7,12 @@ namespace Nethermind.Consensus.AuRa.Validators { - public class PendingValidators(long blockNumber, Hash256 blockHash, Address[] addresses) + public class PendingValidators(ulong blockNumber, Hash256 blockHash, Address[] addresses) { static PendingValidators() => Rlp.RegisterDecoder(typeof(PendingValidators), new PendingValidatorsDecoder()); public Address[] Addresses { get; } = addresses; - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; public Hash256 BlockHash { get; } = blockHash; public bool AreFinalized { get; set; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidatorsDecoder.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidatorsDecoder.cs index 38bc5a7e4ca0..2f65486b1bff 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidatorsDecoder.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidatorsDecoder.cs @@ -21,7 +21,7 @@ protected override PendingValidators DecodeInternal(ref Rlp.ValueDecoderContext int sequenceLength = decoderContext.ReadSequenceLength(); int pendingValidatorsCheck = decoderContext.Position + sequenceLength; - long blockNumber = decoderContext.DecodeLong(); + ulong blockNumber = decoderContext.DecodeULong(); Hash256 blockHash = decoderContext.DecodeKeccak(); int addressSequenceLength = decoderContext.ReadSequenceLength(); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.Cache.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.Cache.cs index 2043a8063f67..cf7cd8ad3c23 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.Cache.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.Cache.cs @@ -13,12 +13,12 @@ public class Cache { internal LinkedList PersistentReports { get; } = new LinkedList(); - private readonly LruCache<(Address Validator, ReportType ReportType, long BlockNumber), bool> _lastBlockReports = + private readonly LruCache<(Address Validator, ReportType ReportType, ulong BlockNumber), bool> _lastBlockReports = new(MaxQueuedReports, "ReportCache"); - internal bool AlreadyReported(ReportType reportType, Address validator, in long blockNumber) + internal bool AlreadyReported(ReportType reportType, Address validator, in ulong blockNumber) { - (Address Validator, ReportType ReportType, long BlockNumber) key = (validator, reportType, blockNumber); + (Address Validator, ReportType ReportType, ulong BlockNumber) key = (validator, reportType, blockNumber); bool alreadyReported = _lastBlockReports.TryGet(key, out _); _lastBlockReports.Set(key, true); return alreadyReported; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.PersistentReports.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.PersistentReports.cs index a6ad29c63a37..f0a47a09e7ea 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.PersistentReports.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.PersistentReports.cs @@ -31,18 +31,18 @@ public partial class ReportingContractBasedValidator : ITxSource private const int ReportsSkipBlocks = 1; private readonly LinkedList _persistentReports; - private long _sentReportsInBlock = 0; + private ulong _sentReportsInBlock = 0; public bool SupportsBlobs => false; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) { foreach (Transaction transaction in _contractValidator.GetTransactions(parent, gasLimit, payloadAttributes, filterSource)) { yield return transaction; } - long currentBlockNumber = parent.Number + 1; + ulong currentBlockNumber = parent.Number + 1; if (_contractValidator.ForSealing && IsPosdao(currentBlockNumber)) { @@ -55,7 +55,7 @@ public IEnumerable GetTransactions(BlockHeader parent, long gasLimi } } - private IEnumerable GetPersistentReportsTransactions(long currentBlockNumber) + private IEnumerable GetPersistentReportsTransactions(ulong currentBlockNumber) { foreach (PersistentReport persistentReport in _persistentReports) { @@ -69,7 +69,7 @@ private IEnumerable GetPersistentReportsTransactions(long currentBl private void ResendPersistedReports(BlockHeader blockHeader) { - long blockNumber = blockHeader.Number; + ulong blockNumber = blockHeader.Number; if (!IsPosdao(blockNumber)) { if (_logger.IsTrace) _logger.Trace("Skipping resending of queued malicious behavior reports."); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs index faf8364ff943..a4cd8365007b 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs @@ -24,10 +24,10 @@ namespace Nethermind.Consensus.AuRa.Validators #pragma warning disable IDE0290 // Constructor has unused DI parameters (txPool, blocksConfig) public partial class ReportingContractBasedValidator : IAuRaValidator, IReportingValidator { - private delegate Transaction CreateReportTransactionDelegate(Address validator, long block, byte[] proof); + private delegate Transaction CreateReportTransactionDelegate(Address validator, ulong block, byte[] proof); private readonly ContractBasedValidator _contractValidator; - private readonly long _posdaoTransition; + private readonly ulong _posdaoTransition; private readonly ITxSender _posdaoTxSender; private readonly IReadOnlyStateProvider _stateProvider; private readonly Cache _cache; @@ -38,7 +38,7 @@ public partial class ReportingContractBasedValidator : IAuRaValidator, IReportin public ReportingContractBasedValidator( ContractBasedValidator contractValidator, IReportingValidatorContract reportingValidatorContract, - long posdaoTransition, + ulong posdaoTransition, ITxSender txSender, ITxPool txPool, IBlocksConfig blocksConfig, @@ -62,9 +62,9 @@ public ReportingContractBasedValidator( private IReportingValidatorContract ValidatorContract { get; } - public void ReportMalicious(Address validator, long blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) => Report(ReportType.Malicious, validator, blockNumber, proof, cause, CreateReportMaliciousTransaction); + public void ReportMalicious(Address validator, ulong blockNumber, byte[] proof, IReportingValidator.MaliciousCause cause) => Report(ReportType.Malicious, validator, blockNumber, proof, cause, CreateReportMaliciousTransaction); - private Transaction CreateReportMaliciousTransaction(Address validator, long blockNumber, byte[] proof) + private Transaction CreateReportMaliciousTransaction(Address validator, ulong blockNumber, byte[] proof) { if (!Validators.Contains(validator)) { @@ -90,11 +90,11 @@ private Transaction CreateReportMaliciousTransactionCore(PersistentReport persis return transaction; } - public void ReportBenign(Address validator, long blockNumber, IReportingValidator.BenignCause cause) => Report(ReportType.Benign, validator, blockNumber, [], cause.ToString(), CreateReportBenignTransaction); + public void ReportBenign(Address validator, ulong blockNumber, IReportingValidator.BenignCause cause) => Report(ReportType.Benign, validator, blockNumber, [], cause.ToString(), CreateReportBenignTransaction); - private Transaction CreateReportBenignTransaction(Address validator, long blockNumber, byte[] proof) => ValidatorContract.ReportBenign(validator, (UInt256)blockNumber); + private Transaction CreateReportBenignTransaction(Address validator, ulong blockNumber, byte[] proof) => ValidatorContract.ReportBenign(validator, (UInt256)blockNumber); - private void Report(ReportType reportType, Address validator, long blockNumber, byte[] proof, object cause, CreateReportTransactionDelegate createReportTransactionDelegate) + private void Report(ReportType reportType, Address validator, ulong blockNumber, byte[] proof, object cause, CreateReportTransactionDelegate createReportTransactionDelegate) { try { @@ -149,13 +149,13 @@ private static void SendTransaction(ReportType reportType, ITxSender txSender, T txSender.SendTransaction(transaction, handlingOptions); } - private ITxSender SetSender(long blockNumber) + private ITxSender SetSender(ulong blockNumber) { bool posdao = IsPosdao(blockNumber); return posdao ? _posdaoTxSender : _nonPosdaoTxSender; } - private bool IsPosdao(long blockNumber) => _posdaoTransition <= blockNumber; + private bool IsPosdao(ulong blockNumber) => _posdaoTransition <= blockNumber; public void TryReportSkipped(BlockHeader header, BlockHeader parent) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs index b07d466854dd..410446b090f2 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs @@ -6,12 +6,12 @@ namespace Nethermind.Consensus.AuRa.Validators { - public class ValidatorInfo(long finalizingBlockNumber, long previousFinalizingBlockNumber, Address[] validators) + public class ValidatorInfo(ulong finalizingBlockNumber, ulong previousFinalizingBlockNumber, Address[] validators) { static ValidatorInfo() => Rlp.RegisterDecoder(typeof(ValidatorInfo), new ValidatorInfoDecoder()); - public long FinalizingBlockNumber { get; } = finalizingBlockNumber; - public long PreviousFinalizingBlockNumber { get; } = previousFinalizingBlockNumber; + public ulong FinalizingBlockNumber { get; } = finalizingBlockNumber; + public ulong PreviousFinalizingBlockNumber { get; } = previousFinalizingBlockNumber; public Address[] Validators { get; } = validators; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfoDecoder.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfoDecoder.cs index 063875be6ebc..082288dc660f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfoDecoder.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfoDecoder.cs @@ -18,8 +18,8 @@ internal sealed class ValidatorInfoDecoder : RlpDecoder int length = decoderContext.ReadSequenceLength(); int check = decoderContext.Position + length; - long finalizingBlockNumber = decoderContext.DecodeLong(); - long previousFinalizingBlockNumber = decoderContext.DecodeLong(); + ulong finalizingBlockNumber = decoderContext.DecodeULong(); + ulong previousFinalizingBlockNumber = decoderContext.DecodeULong(); int addressesSequenceLength = decoderContext.ReadSequenceLength(); int addressesCheck = decoderContext.Position + addressesSequenceLength; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs index 7d43cb0dce4a..0a6ec9f91db6 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs @@ -18,26 +18,26 @@ public class ValidatorStore : IValidatorStore private static readonly PendingValidatorsDecoder PendingValidatorsDecoder = new(); private readonly IDb _db; - private long _latestFinalizedValidatorsBlockNumber; + private ulong _latestFinalizedValidatorsBlockNumber; private ValidatorInfo? _latestValidatorInfo; - private static readonly int EmptyBlockNumber = -1; - private static readonly ValidatorInfo EmptyValidatorInfo = new(-1, -1, []); - private static Hash256 GetKey(in long blockNumber) => Keccak.Compute("Validators" + blockNumber); + private static readonly ulong EmptyBlockNumber = ulong.MaxValue; + private static readonly ValidatorInfo EmptyValidatorInfo = new(ulong.MaxValue, ulong.MaxValue, []); + private static Hash256 GetKey(in ulong blockNumber) => Keccak.Compute("Validators" + blockNumber); public ValidatorStore([KeyFilter(DbNames.BlockInfos)] IDb db) { _db = db; - _latestFinalizedValidatorsBlockNumber = _db.Get(LatestFinalizedValidatorsBlockNumberKey)?.ToLongFromBigEndianByteArrayWithoutLeadingZeros() ?? EmptyBlockNumber; + _latestFinalizedValidatorsBlockNumber = _db.Get(LatestFinalizedValidatorsBlockNumberKey) is { } bytes ? (ulong)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros() : EmptyBlockNumber; } - public void SetValidators(long finalizingBlockNumber, Address[] validators) + public void SetValidators(ulong finalizingBlockNumber, Address[] validators) { if (finalizingBlockNumber > _latestFinalizedValidatorsBlockNumber) { - ValidatorInfo validatorInfo = new(finalizingBlockNumber, _latestFinalizedValidatorsBlockNumber, validators); + ValidatorInfo validatorInfo = new(finalizingBlockNumber, _latestFinalizedValidatorsBlockNumber == EmptyBlockNumber ? EmptyBlockNumber : _latestFinalizedValidatorsBlockNumber, validators); Rlp rlp = Rlp.Encode(validatorInfo); _db.Set(GetKey(finalizingBlockNumber), rlp.Bytes); - _db.PutSpan(LatestFinalizedValidatorsBlockNumberKey.Bytes, finalizingBlockNumber.ToBigEndianSpanWithoutLeadingZeros(out _)); + _db.PutSpan(LatestFinalizedValidatorsBlockNumberKey.Bytes, ((long)finalizingBlockNumber).ToBigEndianSpanWithoutLeadingZeros(out _)); _latestFinalizedValidatorsBlockNumber = finalizingBlockNumber; _latestValidatorInfo = validatorInfo; Metrics.ValidatorsCount = validators.Length; @@ -45,11 +45,11 @@ public void SetValidators(long finalizingBlockNumber, Address[] validators) } - public Address[] GetValidators(in long? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber + public Address[] GetValidators(in ulong? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber ? GetLatestValidatorInfo().Validators : FindValidatorInfo(blockNumber.Value).Validators; - public ValidatorInfo GetValidatorsInfo(in long? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber + public ValidatorInfo GetValidatorsInfo(in ulong? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber ? GetLatestValidatorInfo() : FindValidatorInfo(blockNumber.Value); @@ -69,10 +69,10 @@ private void StorePendingValidators(PendingValidators value) _db.PutSpan(PendingValidatorsKey.Bytes, stream.AsSpan()); } - private ValidatorInfo FindValidatorInfo(in long blockNumber) + private ValidatorInfo FindValidatorInfo(in ulong blockNumber) { ValidatorInfo currentValidatorInfo = GetLatestValidatorInfo(); - while (currentValidatorInfo.FinalizingBlockNumber >= blockNumber) + while (currentValidatorInfo.FinalizingBlockNumber >= blockNumber && currentValidatorInfo.PreviousFinalizingBlockNumber != EmptyBlockNumber) { currentValidatorInfo = LoadValidatorInfo(currentValidatorInfo.PreviousFinalizingBlockNumber); } @@ -87,9 +87,9 @@ private ValidatorInfo GetLatestValidatorInfo() return info; } - private ValidatorInfo LoadValidatorInfo(in long blockNumber) + private ValidatorInfo LoadValidatorInfo(in ulong blockNumber) { - if (blockNumber > EmptyBlockNumber) + if (blockNumber != EmptyBlockNumber) { Span bytes = _db.Get(GetKey(blockNumber)); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs index 114c5cc77804..42fed07a81f5 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs @@ -421,10 +421,10 @@ ILogManager logManager []); // If the block isn't a checkpoint, cast a random vote (good enough for now) - long number = header.Number; + ulong number = header.Number; // Assemble the voting snapshot to check which votes make sense Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(number - 1, parentHeader.Hash); - bool isEpochBlock = (ulong)number % 30000 == 0; + bool isEpochBlock = number % 30000 == 0; if (!isEpochBlock && !_proposals.IsEmpty) { // Gather all the proposals that make sense voting on diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs index fdf1fd09dbfa..428e7902472c 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs @@ -54,10 +54,10 @@ public void UncastVote(Address signer) cliqueBlockProducer.UncastVote(signer); } - public Snapshot GetSnapshot(long? number = null) + public Snapshot GetSnapshot(ulong? number = null) { Block head = _blockTree.Head; - if (number is not null && head.Number != number) + if (number is not null && head.Number != number.Value) { head = _blockTree.FindBlock(number.Value); } @@ -76,7 +76,7 @@ public Address[] GetSigners() return _snapshotManager.GetOrCreateSnapshot(head.Number, head.Hash).Signers.Select(static s => s.Key).ToArray(); } - public Address[] GetSigners(long number) + public Address[] GetSigners(ulong number) { BlockHeader header = _blockTree.FindHeader(number, BlockTreeLookupOptions.TotalDifficultyNotNeeded); return _snapshotManager.GetOrCreateSnapshot(header.Number, header.Hash).Signers @@ -109,7 +109,7 @@ public string[] GetSignersAnnotated(Hash256 hash) public ResultWrapper> clique_proposals() => ResultWrapper>.Success(cliqueBlockProducer?.GetProposals() ?? new Dictionary()); - public ResultWrapper clique_getSnapshot(long? number) => ResultWrapper.Success(GetSnapshot(number)); + public ResultWrapper clique_getSnapshot(ulong? number) => ResultWrapper.Success(GetSnapshot(number)); public ResultWrapper clique_getSnapshotAtHash(Hash256 hash) => ResultWrapper.Success(GetSnapshot(hash)); @@ -117,7 +117,7 @@ public ResultWrapper> clique_proposals() => public ResultWrapper clique_getSignersAtHash(Hash256 hash) => ResultWrapper.Success(GetSigners(hash).ToArray()); - public ResultWrapper clique_getSignersAtNumber(long number) => ResultWrapper.Success(GetSigners(number).ToArray()); + public ResultWrapper clique_getSignersAtNumber(ulong number) => ResultWrapper.Success(GetSigners(number).ToArray()); public ResultWrapper clique_getSignersAnnotated() => ResultWrapper.Success(GetSignersAnnotated().ToArray()); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealValidator.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealValidator.cs index 4e68b2512a95..8cb2581e3ef6 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealValidator.cs @@ -20,7 +20,7 @@ internal class CliqueSealValidator( public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle = false) { - long number = header.Number; + ulong number = header.Number; // Retrieve the snapshot needed to validate this header and cache it Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(number - 1, header.ParentHash!); // Resolve the authorization key and check against signers @@ -128,11 +128,11 @@ public bool ValidateSeal(BlockHeader header, bool force) return header.Author is not null; } - private bool IsEpochTransition(long number) => (ulong)number % _cliqueConfig.Epoch == 0; + private bool IsEpochTransition(ulong number) => number % _cliqueConfig.Epoch == 0; private bool ValidateCascadingFields(BlockHeader parent, BlockHeader header) { - long number = header.Number; + ulong number = header.Number; if (parent.Timestamp + _cliqueConfig.BlockPeriod > header.Timestamp) { if (_logger.IsWarn) _logger.Warn($"Incorrect block timestamp ({header.Timestamp}) - should have big enough difference with parent"); @@ -143,7 +143,7 @@ private bool ValidateCascadingFields(BlockHeader parent, BlockHeader header) Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(number - 1, header.ParentHash); // If the block is a checkpoint block, validate the signer list - if (IsEpochTransition(number)) + if (IsEpochTransition(header.Number)) { byte[] signersBytes = new byte[snapshot.Signers.Count * Address.Size]; int signerIndex = 0; diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs index d203e08b7a8e..d09c78918023 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs @@ -51,7 +51,7 @@ public CliqueSealer(ISigner signer, ICliqueConfig config, ISnapshotManager snaps BlockHeader header = block.Header; // Sealing the genesis block is not supported - long number = header.Number; + ulong number = header.Number; if (number == 0) throw new InvalidOperationException("Can't sign genesis block"); // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) @@ -93,7 +93,7 @@ public CliqueSealer(ISigner signer, ICliqueConfig config, ISnapshotManager snaps return block; } - public bool CanSeal(long blockNumber, Hash256 parentHash) + public bool CanSeal(ulong blockNumber, Hash256 parentHash) { Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(blockNumber - 1, parentHash); if (!_signer.CanSign) diff --git a/src/Nethermind/Nethermind.Consensus.Clique/ICliqueRpcModule.cs b/src/Nethermind/Nethermind.Consensus.Clique/ICliqueRpcModule.cs index 45b690ae68ae..1ec10c8cb639 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/ICliqueRpcModule.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/ICliqueRpcModule.cs @@ -16,7 +16,7 @@ public interface ICliqueRpcModule : IRpcModule ResultWrapper clique_getBlockSigner(Hash256? hash); [JsonRpcMethod(Description = "Retrieves a snapshot of all clique state at a given block.", IsImplemented = true)] - ResultWrapper clique_getSnapshot(long? number = null); + ResultWrapper clique_getSnapshot(ulong? number = null); [JsonRpcMethod(Description = "Retrieves the state snapshot at a given block.", IsImplemented = true)] ResultWrapper clique_getSnapshotAtHash(Hash256 hash); @@ -28,7 +28,7 @@ public interface ICliqueRpcModule : IRpcModule ResultWrapper clique_getSignersAtHash(Hash256 hash); [JsonRpcMethod(Description = "Retrieves the list of authorized signers at the specified block by block number.", IsImplemented = true)] - ResultWrapper clique_getSignersAtNumber(long number); + ResultWrapper clique_getSignersAtNumber(ulong number); [JsonRpcMethod(Description = "Retrieves the list of authorized signers but with signer names instead of addresses", IsImplemented = true)] ResultWrapper clique_getSignersAnnotated(); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/ISnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/ISnapshotManager.cs index 75693587cd06..fcb1def011fe 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/ISnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/ISnapshotManager.cs @@ -9,10 +9,10 @@ namespace Nethermind.Consensus.Clique public interface ISnapshotManager { ulong GetLastSignersCount(); - Snapshot GetOrCreateSnapshot(long number, Hash256 hash); + Snapshot GetOrCreateSnapshot(ulong number, Hash256 hash); Address GetBlockSealer(BlockHeader header); bool IsValidVote(Snapshot snapshot, Address address, bool authorize); - bool IsInTurn(Snapshot snapshot, long number, Address signer); - bool HasSignedRecently(Snapshot snapshot, long number, Address signer); + bool IsInTurn(Snapshot snapshot, ulong number, Address signer); + bool HasSignedRecently(Snapshot snapshot, ulong number, Address signer); } } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs b/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs index a81e82731779..fac860203064 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs @@ -10,22 +10,22 @@ namespace Nethermind.Consensus.Clique { public class Snapshot : ICloneable { - public long Number { get; set; } + public ulong Number { get; set; } public Hash256 Hash { get; set; } - public SortedList Signers { get; } + public SortedList Signers { get; } public List Votes { get; init; } public Dictionary Tally { get; } - internal Snapshot(long number, Hash256 hash, SortedList signers, Dictionary tally) + internal Snapshot(ulong number, Hash256 hash, SortedList signers, Dictionary tally) { Number = number; Hash = hash; - Signers = new SortedList(signers, GenericComparer.GetOptimized
()); + Signers = new SortedList(signers, GenericComparer.GetOptimized
()); Votes = []; Tally = tally; } - internal Snapshot(long number, Hash256 hash, SortedList signers) + internal Snapshot(ulong number, Hash256 hash, SortedList signers) : this(number, hash, signers, []) { } @@ -33,7 +33,7 @@ internal Snapshot(long number, Hash256 hash, SortedList signers) public object Clone() => new Snapshot(Number, Hash, - new SortedList(Signers, GenericComparer.GetOptimized
()), + new SortedList(Signers, GenericComparer.GetOptimized
()), new Dictionary(Tally)) { Votes = [.. Votes] diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotDecoder.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotDecoder.cs index d9516f47a27b..ebe3c9a54a22 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotDecoder.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotDecoder.cs @@ -16,11 +16,11 @@ protected override Snapshot DecodeInternal(ref Rlp.ValueDecoderContext decoderCo decoderContext.ReadSequenceLength(); // Block number - long number = (long)decoderContext.DecodeUInt256(); + ulong number = (ulong)decoderContext.DecodeUInt256(); // Hash Hash256 hash = decoderContext.DecodeKeccak(); // Signers - SortedList signers = DecodeSigners(ref decoderContext); + SortedList signers = DecodeSigners(ref decoderContext); // Votes List votes = DecodeVotes(ref decoderContext); // Tally @@ -65,16 +65,16 @@ private static (int contentLength, int signersLength, int votesLength, int tally return (contentLength, signersLength, votesLength, tallyLength); } - private static SortedList DecodeSigners(ref Rlp.ValueDecoderContext decoderContext) + private static SortedList DecodeSigners(ref Rlp.ValueDecoderContext decoderContext) { decoderContext.ReadSequenceLength(); int length = decoderContext.DecodePositiveInt(); decoderContext.GuardLimit(length); - SortedList signers = new(GenericComparer.GetOptimized
()); + SortedList signers = new(GenericComparer.GetOptimized
()); for (int i = 0; i < length; i++) { Address signer = decoderContext.DecodeAddress(); - long signedAt = (long)decoderContext.DecodeUInt256(); + ulong signedAt = (ulong)decoderContext.DecodeUInt256(); signers.Add(signer, signedAt); } @@ -90,7 +90,7 @@ private static List DecodeVotes(ref Rlp.ValueDecoderContext decoderContext for (int i = 0; i < length; i++) { Address signer = decoderContext.DecodeAddress(); - long block = (long)decoderContext.DecodeUInt256(); + ulong block = (ulong)decoderContext.DecodeUInt256(); Address address = decoderContext.DecodeAddress(); bool authorize = decoderContext.DecodeBool(); Vote vote = new(signer, block, address, authorize); @@ -117,12 +117,12 @@ private static Dictionary DecodeTally(ref Rlp.ValueDecoderContex return tally; } - private static int GetSignersContentLength(SortedList signers) + private static int GetSignersContentLength(SortedList signers) { int signerCount = signers.Count; int contentLength = Rlp.LengthOf(signerCount); int i = 0; - foreach ((Address address, long signedAt) in signers) + foreach ((Address address, ulong signedAt) in signers) { contentLength += Rlp.LengthOf(address); contentLength += Rlp.LengthOf((UInt256)signedAt); @@ -131,13 +131,13 @@ private static int GetSignersContentLength(SortedList signers) return contentLength; } - private static void EncodeSigners(RlpStream stream, SortedList signers, int contentLength) + private static void EncodeSigners(RlpStream stream, SortedList signers, int contentLength) { stream.StartSequence(contentLength); int signerCount = signers.Count; stream.Encode(signerCount); int i = 0; - foreach ((Address address, long signedAt) in signers) + foreach ((Address address, ulong signedAt) in signers) { stream.Encode(address); stream.Encode(signedAt); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index 226cb2274bfa..077d45ee7295 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -93,7 +93,7 @@ public static byte[] SliceExtraSealFromExtraData(byte[] extraData) public ulong GetLastSignersCount() => _lastSignersCount; - public Snapshot GetOrCreateSnapshot(long number, Hash256 hash) + public Snapshot GetOrCreateSnapshot(ulong number, Hash256 hash) { Snapshot? snapshot = GetSnapshot(number, hash); if (snapshot is not null) @@ -126,12 +126,12 @@ public Snapshot GetOrCreateSnapshot(long number, Hash256 hash) if (_logger.IsInfo) _logger.Info($"Creating epoch snapshot at block {number}"); int signersCount = CalculateSignersCount(header); - SortedList signers = new(signersCount, GenericComparer.GetOptimized
()); + SortedList signers = new(signersCount, GenericComparer.GetOptimized
()); Address epochSigner = GetBlockSealer(header); for (int i = 0; i < signersCount; i++) { Address signer = new(header.ExtraData.Slice(Clique.ExtraVanityLength + i * Address.Size, Address.Size)); - signers.Add(signer, signer == epochSigner ? number : parentSnapshot is null ? 0L : parentSnapshot.Signers.TryGetValue(signer, out long value) ? value : 0L); + signers.Add(signer, signer == epochSigner ? number : parentSnapshot is null ? 0UL : parentSnapshot.Signers.TryGetValue(signer, out ulong value) ? value : 0UL); } snapshot = new Snapshot(number, header.Hash, signers); @@ -171,7 +171,7 @@ public Snapshot GetOrCreateSnapshot(long number, Hash256 hash) // If we've generated a new checkpoint snapshot, save to disk } - if ((ulong)snapshot.Number % Clique.CheckpointInterval == 0 && headers.Count > 0) + if (snapshot.Number % Clique.CheckpointInterval == 0 && headers.Count > 0) { Store(snapshot); } @@ -179,12 +179,12 @@ public Snapshot GetOrCreateSnapshot(long number, Hash256 hash) return snapshot; } - public bool HasSignedRecently(Snapshot snapshot, long number, Address signer) + public bool HasSignedRecently(Snapshot snapshot, ulong number, Address signer) { - long signedAt = snapshot.Signers[signer]; - if (signedAt == 0L) return false; + ulong signedAt = snapshot.Signers[signer]; + if (signedAt == 0UL) return false; - return number - signedAt < snapshot.SignerLimit; + return number - signedAt < (ulong)snapshot.SignerLimit; } public bool IsValidVote(Snapshot snapshot, Address address, bool authorize) @@ -193,11 +193,11 @@ public bool IsValidVote(Snapshot snapshot, Address address, bool authorize) return signer && !authorize || !signer && authorize; } - public bool IsInTurn(Snapshot snapshot, long number, Address signer) => (long)number % snapshot.Signers.Count == snapshot.Signers.IndexOfKey(signer); + public bool IsInTurn(Snapshot snapshot, ulong number, Address signer) => number % (ulong)snapshot.Signers.Count == (ulong)snapshot.Signers.IndexOfKey(signer); - private bool IsEpochTransition(long number) => (ulong)number % _cliqueConfig.Epoch == 0; + private bool IsEpochTransition(ulong number) => number % _cliqueConfig.Epoch == 0; - private Snapshot? GetSnapshot(long number, Hash256 hash) + private Snapshot? GetSnapshot(ulong number, Hash256 hash) { if (_logger.IsTrace) _logger.Trace($"Getting snapshot for {number}"); // If an in-memory snapshot was found, use that @@ -205,7 +205,7 @@ public bool IsValidVote(Snapshot snapshot, Address address, bool authorize) if (cachedSnapshot is not null) return cachedSnapshot; // If an on-disk checkpoint snapshot can be found, use that - if ((ulong)number % Clique.CheckpointInterval == 0) + if (number % Clique.CheckpointInterval == 0) { Snapshot? persistedSnapshot = LoadSnapshot(hash); if (persistedSnapshot is not null) return persistedSnapshot; @@ -243,7 +243,7 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch // Sanity check that the headers can be applied for (int i = 0; i < headers.Count - 1; i++) { - if (headers[i].Number != original.Number + i + 1) + if (headers[i].Number != original.Number + (ulong)i + 1) { throw new InvalidOperationException("Invalid voting chain"); } @@ -254,8 +254,8 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch foreach (BlockHeader header in headers) { // Remove any votes on checkpoint blocks - long number = header.Number; - if ((ulong)number % epoch == 0) + ulong number = header.Number; + if (number % epoch == 0) { snapshot.Votes.Clear(); snapshot.Tally.Clear(); @@ -263,7 +263,7 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch // Resolve the authorization key and check against signers Address signer = header.Author; - if (!snapshot.Signers.TryGetValue(signer, out long value)) throw new InvalidOperationException("Unauthorized signer"); + if (!snapshot.Signers.TryGetValue(signer, out ulong value)) throw new InvalidOperationException("Unauthorized signer"); if (HasSignedRecently(snapshot, number, signer)) throw new InvalidOperationException($"Recently signed (trying to sign {number} when last signed {value} with {snapshot.Signers.Count} signers)"); snapshot.Signers[signer] = number; @@ -296,7 +296,7 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch { if (tally.Authorize) { - snapshot.Signers.Add(header.Beneficiary, 0); + snapshot.Signers.Add(header.Beneficiary, 0UL); } else { @@ -332,7 +332,7 @@ private Snapshot Apply(Snapshot original, List headers, ulong epoch } } - snapshot.Number += headers.Count; + snapshot.Number += (ulong)headers.Count; // was this needed? // snapshot.Hash = headers[headers.Count - 1].CalculateHash(); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/Vote.cs b/src/Nethermind/Nethermind.Consensus.Clique/Vote.cs index cc56703cd386..96e2cc6adb8a 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/Vote.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/Vote.cs @@ -5,10 +5,10 @@ namespace Nethermind.Consensus.Clique { - public class Vote(Address signer, long block, Address address, bool authorize) + public class Vote(Address signer, ulong block, Address address, bool authorize) { public Address Signer { get; } = signer; - public long Block { get; } = block; + public ulong Block { get; } = block; public Address Address { get; } = address; public bool Authorize { get; } = authorize; } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/WiggleRandomizer.cs b/src/Nethermind/Nethermind.Consensus.Clique/WiggleRandomizer.cs index ab35f1cfefa5..d04b1c9e0f2e 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/WiggleRandomizer.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/WiggleRandomizer.cs @@ -14,7 +14,7 @@ internal class WiggleRandomizer(ICryptoRandom cryptoRandom, ISnapshotManager sna private readonly ICryptoRandom _cryptoRandom = cryptoRandom; private readonly ISnapshotManager _snapshotManager = snapshotManager; private readonly int _minimumWiggle = minWiggle; - private long _lastWiggleAtNumber; + private ulong _lastWiggleAtNumber; private int _lastWiggle; diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs index 1cb8a4c7b765..1b4d73befb35 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs @@ -40,14 +40,14 @@ public Ethash(ILogManager logManager) public static uint CacheBytesInit = 1U << 24; // bytes in cache at genesis public static uint CacheBytesGrowth = 1U << 17; // cache growth per epoch public const int CacheMultiplier = 1024; // Size of the DAG relative to the cache - public const long EpochLength = 30000; // blocks per epoch + public const ulong EpochLength = 30000; // blocks per epoch public const uint MixBytes = 128; // width of mix public const int HashBytes = 64; // hash length in bytes public const uint DataSetParents = 256; // blockNumber of parents of each dataset element public const int CacheRounds = 3; // blockNumber of rounds in cache production public const int Accesses = 64; // blockNumber of accesses in hashimoto loop - public static uint GetEpoch(long blockNumber) => (uint)(blockNumber / EpochLength); + public static uint GetEpoch(ulong blockNumber) => (uint)(blockNumber / EpochLength); /// Improvement from @AndreaLanfranchi public static ulong GetDataSize(uint epoch) @@ -204,7 +204,7 @@ public bool Validate(BlockHeader header) if (dataSet is null) { if (_logger.IsDebug) _logger.Debug($"Ethash cache miss for block {header.ToString(BlockHeader.Format.Short)}"); - _hintBasedCache.Hint(_hintBasedCacheUser, header.Number, header.Number); + _hintBasedCache.Hint(_hintBasedCacheUser, (long)header.Number, (long)header.Number); dataSet = _hintBasedCache.Get(epoch); if (dataSet is null) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashChainSpecEngineParameters.cs index f9d8a0c7fb72..85a382266d9c 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashChainSpecEngineParameters.cs @@ -8,7 +8,7 @@ using Nethermind.Specs; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Specs.ChainSpecStyle.Json; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Nethermind.Consensus.Ethash; @@ -17,25 +17,26 @@ public class EthashChainSpecEngineParameters : IChainSpecEngineParameters public string? EngineName => SealEngineType; public string? SealEngineType => Core.SealEngineType.Ethash; - public long HomesteadTransition { get; set; } = 0; - public long? DaoHardforkTransition { get; set; } + public ulong HomesteadTransition { get; set; } = 0; + public ulong? DaoHardforkTransition { get; set; } public Address DaoHardforkBeneficiary { get; set; } public Address[] DaoHardforkAccounts { get; set; } = []; - public long? Eip100bTransition { get; set; } - public long? FixedDifficulty { get; set; } - public long DifficultyBoundDivisor { get; set; } = 0x0800; - public long DurationLimit { get; set; } = 13; + public ulong? Eip100bTransition { get; set; } + public ulong? FixedDifficulty { get; set; } + public ulong DifficultyBoundDivisor { get; set; } = 0x0800; + public ulong DurationLimit { get; set; } = 13; public UInt256 MinimumDifficulty { get; set; } = 0; [JsonConverter(typeof(BlockRewardConverter))] - public SortedDictionary? BlockReward { get; set; } - public IDictionary? DifficultyBombDelays { get; set; } + public SortedDictionary? BlockReward { get; set; } + [JsonConverter(typeof(DifficultyBombDelaysConverter))] + public IDictionary? DifficultyBombDelays { get; set; } - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { if (DifficultyBombDelays is not null) { - foreach ((long blockNumber, _) in DifficultyBombDelays) + foreach ((ulong blockNumber, _) in DifficultyBombDelays) { blockNumbers.Add(blockNumber); } @@ -43,7 +44,7 @@ public void AddTransitions(SortedSet blockNumbers, SortedSet timest if (BlockReward is not null) { - foreach ((long blockNumber, _) in BlockReward) + foreach ((ulong blockNumber, _) in BlockReward) { blockNumbers.Add(blockNumber); } @@ -54,7 +55,7 @@ public void AddTransitions(SortedSet blockNumbers, SortedSet timest if (Eip100bTransition is not null) blockNumbers.Add(Eip100bTransition.Value); } - public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) + public void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) { SetDifficultyBombDelays(spec, startBlock); @@ -65,11 +66,11 @@ public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTi spec.FixedDifficulty = FixedDifficulty; } - private void SetDifficultyBombDelays(ReleaseSpec spec, long startBlock) + private void SetDifficultyBombDelays(ReleaseSpec spec, ulong startBlock) { if (BlockReward is not null) { - foreach (KeyValuePair blockReward in BlockReward) + foreach (KeyValuePair blockReward in BlockReward) { if (blockReward.Key <= startBlock) { @@ -80,7 +81,7 @@ private void SetDifficultyBombDelays(ReleaseSpec spec, long startBlock) if (DifficultyBombDelays is not null) { - foreach (KeyValuePair bombDelay in DifficultyBombDelays) + foreach (KeyValuePair bombDelay in DifficultyBombDelays) { if (bombDelay.Key <= startBlock) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs index 855399a98461..73d891efc0d9 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs @@ -32,10 +32,10 @@ public UInt256 Calculate( in UInt256 parentDifficulty, ulong parentTimestamp, ulong currentTimestamp, - long blockNumber, + ulong blockNumber, bool parentHasUncles) { - IReleaseSpec spec = specProvider.GetSpec(blockNumber, currentTimestamp); + IReleaseSpec spec = specProvider.GetSpec(new ForkActivation(blockNumber, currentTimestamp)); if (spec.FixedDifficulty is not null && blockNumber != 0) { return (UInt256)spec.FixedDifficulty.Value; @@ -70,10 +70,25 @@ private static BigInteger TimeAdjustment( } } - private static BigInteger TimeBomb(IReleaseSpec spec, long blockNumber) + private static BigInteger TimeBomb(IReleaseSpec spec, ulong blockNumber) { - blockNumber -= spec.DifficultyBombDelay; - return blockNumber < InitialDifficultyBombBlock ? BigInteger.Zero : BigInteger.Pow(2, (int)(BigInteger.Divide(blockNumber, 100000) - 2)); + if (blockNumber < spec.DifficultyBombDelay) + { + return BigInteger.Zero; + } + ulong effective = blockNumber - spec.DifficultyBombDelay; + if (effective < InitialDifficultyBombBlock) + { + return BigInteger.Zero; + } + ulong exponent = effective / 100000; + if (exponent < 2) + { + return BigInteger.Zero; + } + exponent -= 2; + int exp = exponent > 100 ? 100 : (int)exponent; + return BigInteger.Pow(2, exp); } } } diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs index d72b81a9d5dc..8cca556da184 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs @@ -26,7 +26,7 @@ public class EthashSealValidator : ISealValidator private readonly LruCache _sealCache = new(2048, 2048, "ethash seals"); private const int SealValidationIntervalConstantComponent = 1024; private const long AllowedFutureBlockTimeSeconds = 15; - private int _sealValidationInterval = SealValidationIntervalConstantComponent; + private uint _sealValidationInterval = SealValidationIntervalConstantComponent; public EthashSealValidator(ILogManager logManager, IDifficultyCalculator difficultyCalculator, ICryptoRandom cryptoRandom, IEthash ethash, ITimestamper timestamper) { @@ -42,7 +42,7 @@ public EthashSealValidator(ILogManager logManager, IDifficultyCalculator difficu private void ResetValidationInterval() => // more or less at the constant component // prevents attack on all Nethermind nodes at once - _sealValidationInterval = SealValidationIntervalConstantComponent - 8 + _cryptoRandom.NextInt(16); + _sealValidationInterval = (uint)(SealValidationIntervalConstantComponent - 8 + _cryptoRandom.NextInt(16)); public bool ValidateSeal(BlockHeader header, bool force) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealer.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealer.cs index dfa830d0f76f..85e6c11899a8 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealer.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealer.cs @@ -39,7 +39,7 @@ public async Task SealBlock(Block processed, CancellationToken cancellati return block; } - public bool CanSeal(long blockNumber, Hash256 parentHash) => true; + public bool CanSeal(ulong blockNumber, Hash256 parentHash) => true; public Address Address => _signer.Address; diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs index aef9db8d4371..6d37441f7cfe 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs @@ -36,8 +36,8 @@ private struct DataSetWithTime(DateTimeOffset timestamp, Task da [MethodImpl(MethodImplOptions.Synchronized)] public void Hint(Guid guid, long start, long end) { - uint startEpoch = (uint)(start / Ethash.EpochLength); - uint endEpoch = (uint)(end / Ethash.EpochLength); + uint startEpoch = (uint)((ulong)start / Ethash.EpochLength); + uint endEpoch = (uint)((ulong)end / Ethash.EpochLength); if (endEpoch - startEpoch > 10) { diff --git a/src/Nethermind/Nethermind.Consensus.Test/BlockCachePreWarmerTests.cs b/src/Nethermind/Nethermind.Consensus.Test/BlockCachePreWarmerTests.cs index 06cc707a6830..32db9c243478 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/BlockCachePreWarmerTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/BlockCachePreWarmerTests.cs @@ -345,7 +345,7 @@ public async Task ParentReaderEnvPolicy_SharesBalWarmupCachesAndPopulatesMisses( Assert.That(preBlockCaches.StateCache.TryGetValue(in warmedAddress, out _), Is.True); Assert.That(preBlockCaches.StorageCache.TryGetValue(in warmedCell, out _), Is.True); - preBlockCaches.StateCache.Set(in warmedAddress, new Account((UInt256)777)); + preBlockCaches.StateCache.Set(in warmedAddress, new Account(777UL)); preBlockCaches.StorageCache.Set(in warmedCell, [0x24]); AddressAsKey missedAddress = TestItem.AddressB; diff --git a/src/Nethermind/Nethermind.Consensus.Test/ExecutionProcessorTests.cs b/src/Nethermind/Nethermind.Consensus.Test/ExecutionProcessorTests.cs index 5d04565af535..b0c842c45875 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/ExecutionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/ExecutionProcessorTests.cs @@ -130,7 +130,7 @@ TestExecutionRequest[] consolidationRequests return ExecutionRequestExtensions.CalculateHashFromFlatEncodedRequests(requests.ToArray()); } - private Hash256 ProcessBlockAndGetRequestsHash(long blockNumber, TxReceipt[] txReceipts) + private Hash256 ProcessBlockAndGetRequestsHash(ulong blockNumber, TxReceipt[] txReceipts) { Block block = Build.A.Block.WithNumber(blockNumber).TestObject; ExecutionRequestsProcessor executionRequestsProcessor = new(_transactionProcessor); diff --git a/src/Nethermind/Nethermind.Consensus.Test/ManualGasLimitCalculator.cs b/src/Nethermind/Nethermind.Consensus.Test/ManualGasLimitCalculator.cs index c5ef4bc8e317..1db5eaaf1246 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/ManualGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/ManualGasLimitCalculator.cs @@ -7,7 +7,7 @@ namespace Nethermind.Consensus.Test { public class ManualGasLimitCalculator : IGasLimitCalculator { - public long GasLimit { get; set; } - public long GetGasLimit(BlockHeader parentHeader) => GasLimit; + public ulong GasLimit { get; set; } + public ulong GetGasLimit(BlockHeader parentHeader) => GasLimit; } } diff --git a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs index c5aef7637225..9f19e277090e 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs @@ -120,8 +120,8 @@ private static async Task WithRestoredBlockchainMetrics(Func test) long originalBlockchainHeight = BlockchainMetrics.BlockchainHeight; UInt256 originalTotalDifficulty = BlockchainMetrics.TotalDifficulty; UInt256 originalLastDifficulty = BlockchainMetrics.LastDifficulty; - long originalGasUsed = BlockchainMetrics.GasUsed; - long originalGasLimit = BlockchainMetrics.GasLimit; + ulong originalGasUsed = BlockchainMetrics.GasUsed; + ulong originalGasLimit = BlockchainMetrics.GasLimit; try { @@ -152,7 +152,7 @@ public void GenerateReportForTest( Block block, BlockHeader baseBlock, long blockCount, - long gasUsed, + ulong gasUsed, long transactionCount, long processingMicroseconds) => GenerateReport(new BlockData diff --git a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs index 0349f474d10f..ad830fca4697 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs @@ -18,8 +18,8 @@ public class TargetAdjustedGasLimitCalculatorTests [Test] public void Is_bump_on_1559_eip_block() { - int londonBlock = 5; - long gasLimit = 1000000000000000000; + ulong londonBlock = 5; + ulong gasLimit = 1000000000000000000; OverridableReleaseSpec spec = new(London.Instance) { Eip1559TransitionBlock = londonBlock @@ -27,35 +27,35 @@ public void Is_bump_on_1559_eip_block() TestSpecProvider specProvider = new(spec); TargetAdjustedGasLimitCalculator targetedAdjustedGasLimitCalculator = new(specProvider, new BlocksConfig()); BlockHeader header = Build.A.BlockHeader.WithNumber(londonBlock - 1).WithGasLimit(gasLimit).TestObject; - long actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); - Assert.That(actualValue, Is.EqualTo(gasLimit * Eip1559Constants.DefaultElasticityMultiplier)); + ulong actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); + Assert.That(actualValue, Is.EqualTo(gasLimit * (ulong)Eip1559Constants.DefaultElasticityMultiplier)); } - [TestCase(30_000_000, 100_000_000, 30029295)] - public void Is_calculating_correct_gasLimit(long currentGasLimit, long targetGasLimit, long expectedGasLimit) + [TestCase(30_000_000ul, 100_000_000, 30029295)] + public void Is_calculating_correct_gasLimit(ulong currentGasLimit, long targetGasLimit, long expectedGasLimit) { - int blockNumber = 20_000_000; - long gasLimit = currentGasLimit; + ulong blockNumber = 20_000_000; + ulong gasLimit = currentGasLimit; TestSpecProvider specProvider = new(Prague.Instance); TargetAdjustedGasLimitCalculator targetedAdjustedGasLimitCalculator = new(specProvider, new BlocksConfig() { TargetBlockGasLimit = targetGasLimit }); - BlockHeader header = Build.A.BlockHeader.WithNumber(blockNumber - 1).WithGasLimit(gasLimit).TestObject; - long actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); + BlockHeader header = Build.A.BlockHeader.WithNumber(blockNumber - 1UL).WithGasLimit(gasLimit).TestObject; + ulong actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); Assert.That(actualValue, Is.EqualTo(expectedGasLimit)); } [Test] public void DoesNot_go_below_minimum() { - int londonBlock = 5; - long gasLimit = 5000; + ulong londonBlock = 5; + ulong gasLimit = 5000; TestSpecProvider specProvider = new(London.Instance); TargetAdjustedGasLimitCalculator targetedAdjustedGasLimitCalculator = new(specProvider, new BlocksConfig() { TargetBlockGasLimit = 1 }); - BlockHeader header = Build.A.BlockHeader.WithNumber(londonBlock - 1).WithGasLimit(gasLimit).TestObject; - long actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); + BlockHeader header = Build.A.BlockHeader.WithNumber(londonBlock - 1UL).WithGasLimit(gasLimit).TestObject; + ulong actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); Assert.That(actualValue, Is.EqualTo(specProvider.GetSpec(new ForkActivation(5)).MinGasLimit)); } } diff --git a/src/Nethermind/Nethermind.Consensus/AlwaysPoS.cs b/src/Nethermind/Nethermind.Consensus/AlwaysPoS.cs index b1db0bc0d5fd..8ff38ea54463 100644 --- a/src/Nethermind/Nethermind.Consensus/AlwaysPoS.cs +++ b/src/Nethermind/Nethermind.Consensus/AlwaysPoS.cs @@ -21,7 +21,7 @@ private AlwaysPoS() { } public Hash256? ConfiguredTerminalBlockHash => null; - public long? ConfiguredTerminalBlockNumber => 0; + public ulong? ConfiguredTerminalBlockNumber => 0; #pragma warning disable CS0067 public event EventHandler TerminalBlockReached; diff --git a/src/Nethermind/Nethermind.Consensus/BlockPreparationContext.cs b/src/Nethermind/Nethermind.Consensus/BlockPreparationContext.cs index 88383204521a..84a7c6d340cb 100644 --- a/src/Nethermind/Nethermind.Consensus/BlockPreparationContext.cs +++ b/src/Nethermind/Nethermind.Consensus/BlockPreparationContext.cs @@ -7,10 +7,10 @@ namespace Nethermind.Consensus { /// Block producer is setting current context and thanks to this context /// other classes like gas price comparison know what base fee they should be used - public readonly struct BlockPreparationContext(in UInt256 baseFee, long blockNumber) + public readonly struct BlockPreparationContext(in UInt256 baseFee, ulong blockNumber) { public UInt256 BaseFee { get; } = baseFee; - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; } } diff --git a/src/Nethermind/Nethermind.Consensus/Comparers/GasPriceTxComparer.cs b/src/Nethermind/Nethermind.Consensus/Comparers/GasPriceTxComparer.cs index c470f93e6342..35a3ef6f120f 100644 --- a/src/Nethermind/Nethermind.Consensus/Comparers/GasPriceTxComparer.cs +++ b/src/Nethermind/Nethermind.Consensus/Comparers/GasPriceTxComparer.cs @@ -31,7 +31,7 @@ public int Compare(Transaction? x, Transaction? y) // When we're adding Tx to TxPool, we don't know the base fee of the block in which transaction will be added. // We can get a base fee from the current head. Block block = _blockFinder.Head; - bool isEip1559Enabled = _specProvider.GetSpecFor1559(block?.Number ?? 0L).IsEip1559Enabled; + bool isEip1559Enabled = _specProvider.GetSpecFor1559(block?.Number ?? 0UL).IsEip1559Enabled; return GasPriceTxComparerHelper.Compare(x, y, (block?.Header.BaseFeePerGas).GetValueOrDefault(), isEip1559Enabled); } diff --git a/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs b/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs index 52649295c1ca..42890d003a04 100644 --- a/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs +++ b/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs @@ -8,12 +8,13 @@ namespace Nethermind.Consensus /// In the 1559 fork block the new gas limit is gasLimit * Eip1559Constants.ElasticityMultiplier. public static class Eip1559GasLimitAdjuster { - public static long AdjustGasLimit(IReleaseSpec releaseSpec, long gasLimit, long blockNumber) + public static ulong AdjustGasLimit(IReleaseSpec releaseSpec, ulong gasLimit, ulong blockNumber) { - long adjustedGasLimit = gasLimit; + ulong adjustedGasLimit = gasLimit; if (releaseSpec.Eip1559TransitionBlock == blockNumber) { - adjustedGasLimit *= releaseSpec.ElasticityMultiplier; + // Safe cast: ElasticityMultiplier is always a small positive constant (e.g. 2) + adjustedGasLimit *= (ulong)releaseSpec.ElasticityMultiplier; } return adjustedGasLimit; diff --git a/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs b/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs index b1373b958925..0e9b45a9f4b5 100644 --- a/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs @@ -24,28 +24,28 @@ public class ExecutionRequestsProcessor : IExecutionRequestsProcessor public static readonly AbiSignature DepositEventAbi = new("DepositEvent", AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes); private readonly AbiEncoder _abiEncoder = AbiEncoder.Instance; - private const long GasLimit = Eip8037Constants.SystemCallGasLimit; + private const ulong GasLimit = Eip8037Constants.SystemCallGasLimit; private readonly ITransactionProcessor _transactionProcessor; private readonly SystemCall _withdrawalTransaction = new() { - Value = UInt256.Zero, + Value = 0, Data = Array.Empty(), To = Eip7002Constants.WithdrawalRequestPredeployAddress, SenderAddress = Address.SystemUser, GasLimit = GasLimit, - GasPrice = UInt256.Zero, + GasPrice = 0, }; private readonly SystemCall _consolidationTransaction = new() { - Value = UInt256.Zero, + Value = 0, Data = Array.Empty(), To = Eip7251Constants.ConsolidationRequestPredeployAddress, SenderAddress = Address.SystemUser, GasLimit = GasLimit, - GasPrice = UInt256.Zero, + GasPrice = 0, }; public ExecutionRequestsProcessor(ITransactionProcessor transactionProcessor) diff --git a/src/Nethermind/Nethermind.Consensus/FollowOtherMiners.cs b/src/Nethermind/Nethermind.Consensus/FollowOtherMiners.cs index 146f402ccfac..2ed613e7cc25 100644 --- a/src/Nethermind/Nethermind.Consensus/FollowOtherMiners.cs +++ b/src/Nethermind/Nethermind.Consensus/FollowOtherMiners.cs @@ -10,10 +10,10 @@ public class FollowOtherMiners(ISpecProvider specProvider) : IGasLimitCalculator { private readonly ISpecProvider _specProvider = specProvider; - public long GetGasLimit(BlockHeader parentHeader) + public ulong GetGasLimit(BlockHeader parentHeader) { - long gasLimit = parentHeader.GasLimit; - long newBlockNumber = parentHeader.Number + 1; + ulong gasLimit = parentHeader.GasLimit; + ulong newBlockNumber = parentHeader.Number + 1; IReleaseSpec spec = _specProvider.GetSpec(parentHeader); gasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(spec, gasLimit, newBlockNumber); return gasLimit; diff --git a/src/Nethermind/Nethermind.Consensus/IGasLimitCalculator.cs b/src/Nethermind/Nethermind.Consensus/IGasLimitCalculator.cs index 1660ef75aa76..ae65509f3cfb 100644 --- a/src/Nethermind/Nethermind.Consensus/IGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus/IGasLimitCalculator.cs @@ -7,6 +7,6 @@ namespace Nethermind.Consensus { public interface IGasLimitCalculator { - long GetGasLimit(BlockHeader parentHeader); + ulong GetGasLimit(BlockHeader parentHeader); } } diff --git a/src/Nethermind/Nethermind.Consensus/IPoSSwitcher.cs b/src/Nethermind/Nethermind.Consensus/IPoSSwitcher.cs index c8163ece61a1..3ee7bc0dc78d 100644 --- a/src/Nethermind/Nethermind.Consensus/IPoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Consensus/IPoSSwitcher.cs @@ -32,7 +32,7 @@ public interface IPoSSwitcher bool TransitionFinished { get; } public Hash256? ConfiguredTerminalBlockHash { get; } - public long? ConfiguredTerminalBlockNumber { get; } + public ulong? ConfiguredTerminalBlockNumber { get; } // We can get TerminalBlock from three different points in the system: // 1) Block Processing - it is needed because we need to switch classes, for example, block production, during the transition diff --git a/src/Nethermind/Nethermind.Consensus/ISealer.cs b/src/Nethermind/Nethermind.Consensus/ISealer.cs index 58054650fb2b..965f85635b4a 100644 --- a/src/Nethermind/Nethermind.Consensus/ISealer.cs +++ b/src/Nethermind/Nethermind.Consensus/ISealer.cs @@ -12,7 +12,7 @@ public interface ISealer { Task SealBlock(Block block, CancellationToken cancellationToken); - bool CanSeal(long blockNumber, Hash256 parentHash); + bool CanSeal(ulong blockNumber, Hash256 parentHash); Address Address { get; } } diff --git a/src/Nethermind/Nethermind.Consensus/NethDevSealEngine.cs b/src/Nethermind/Nethermind.Consensus/NethDevSealEngine.cs index 60e8c44d5d81..435b7349170f 100644 --- a/src/Nethermind/Nethermind.Consensus/NethDevSealEngine.cs +++ b/src/Nethermind/Nethermind.Consensus/NethDevSealEngine.cs @@ -18,7 +18,7 @@ public Task SealBlock(Block block, CancellationToken cancellationToken) return Task.FromResult(block); } - public bool CanSeal(long blockNumber, Hash256 parentHash) => true; + public bool CanSeal(ulong blockNumber, Hash256 parentHash) => true; public Address Address { get; } = address ?? Address.Zero; diff --git a/src/Nethermind/Nethermind.Consensus/NoPoS.cs b/src/Nethermind/Nethermind.Consensus/NoPoS.cs index dbfd34d0d9bb..62351e5f7a96 100644 --- a/src/Nethermind/Nethermind.Consensus/NoPoS.cs +++ b/src/Nethermind/Nethermind.Consensus/NoPoS.cs @@ -26,7 +26,7 @@ private NoPoS() { } public UInt256? FinalTotalDifficulty => null; public bool TransitionFinished => false; public Hash256? ConfiguredTerminalBlockHash => Keccak.Zero; - public long? ConfiguredTerminalBlockNumber => null; + public ulong? ConfiguredTerminalBlockNumber => null; public bool TryUpdateTerminalBlock(BlockHeader header) => throw new NotImplementedException(); diff --git a/src/Nethermind/Nethermind.Consensus/NullSealEngine.cs b/src/Nethermind/Nethermind.Consensus/NullSealEngine.cs index 7de470a4983f..47156a971931 100644 --- a/src/Nethermind/Nethermind.Consensus/NullSealEngine.cs +++ b/src/Nethermind/Nethermind.Consensus/NullSealEngine.cs @@ -20,7 +20,7 @@ private NullSealEngine() public Task SealBlock(Block? block, CancellationToken cancellationToken) => Task.FromResult(block); - public bool CanSeal(long blockNumber, Hash256? parentHash) => true; + public bool CanSeal(ulong blockNumber, Hash256? parentHash) => true; public bool ValidateParams(BlockHeader? parent, BlockHeader? header, bool isUncle = false) => true; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs index 90bab37b0697..199f89de9f9b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs @@ -45,8 +45,8 @@ public void ApplyAuRaPreprocessingChanges(IReleaseSpec spec, Address withdrawalC return; } - stateProvider.CreateAccount(Address.SystemUser, UInt256.Zero, UInt256.Zero); - stateProvider.CreateAccount(withdrawalContractAddress, UInt256.Zero, UInt256.Zero); + stateProvider.CreateAccount(Address.SystemUser, UInt256.Zero); + stateProvider.CreateAccount(withdrawalContractAddress, UInt256.Zero); stateProvider.Commit(spec.ForSystemTransaction(true, false), commitRoots: false); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs index 7c371f7322b4..8c02a3b32514 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs @@ -36,8 +36,8 @@ public void IncrementalValidation(Block block, GasValidationResultSlot[] gasResu MergeAndReturnBal(0u); ValidateBlockAccessList(block, 0u); - long totalRegularGas = 0; - long totalStateGas = 0; + ulong totalRegularGas = 0; + ulong totalStateGas = 0; for (int chunkStart = 0; chunkStart < len; chunkStart += GasValidationChunkSize) { if (token.IsCancellationRequested) @@ -83,10 +83,10 @@ public void IncrementalValidation(Block block, GasValidationResultSlot[] gasResu // EIP-8037: 2D gas accounting — block gasUsed = max(sum_regular, sum_state) _blockExecutionContext.Value.Header.GasUsed = Math.Max(totalRegularGas, totalStateGas); - static void CheckGasUsed(int index, Block block, long totalRegularGas, long totalStateGas) + static void CheckGasUsed(int index, Block block, ulong totalRegularGas, ulong totalStateGas) { // EIP-8037: block gasUsed = max(sum_regular, sum_state) - long effectiveGas = Math.Max(totalRegularGas, totalStateGas); + ulong effectiveGas = Math.Max(totalRegularGas, totalStateGas); if (effectiveGas > block.Header.GasLimit) { throw new InvalidBlockException(block, $"Block gas limit exceeded: cumulative gas {effectiveGas} > block gas limit {block.Header.GasLimit} after transaction index {index}."); @@ -94,7 +94,7 @@ static void CheckGasUsed(int index, Block block, long totalRegularGas, long tota } } - internal static void CheckPerTxInclusion(Block block, int index, Transaction tx, IReleaseSpec spec, long cumulativeRegular, long cumulativeState) + internal static void CheckPerTxInclusion(Block block, int index, Transaction tx, IReleaseSpec spec, ulong cumulativeRegular, ulong cumulativeState) { if (!spec.IsEip8037Enabled) return; @@ -104,12 +104,12 @@ internal static void CheckPerTxInclusion(Block block, int index, Transaction tx, // EIP-8037 worst-case 2D inclusion check. Only fires when EIP-8037 is active; legacy and // pre-EIP-8037 blocks rely solely on the post-execution running max(R,S) check. - internal static void CheckPerTxInclusion(Block block, int index, Transaction tx, IReleaseSpec spec, long cumulativeRegular, long cumulativeState, in IntrinsicGas intrinsic) + internal static void CheckPerTxInclusion(Block block, int index, Transaction tx, IReleaseSpec spec, ulong cumulativeRegular, ulong cumulativeState, in IntrinsicGas intrinsic) { if (!spec.IsEip8037Enabled) return; - long intrinsicRegular = intrinsic.Standard.Value; - long intrinsicState = intrinsic.Standard.StateReservoir; + ulong intrinsicRegular = intrinsic.Standard.Value; + ulong intrinsicState = intrinsic.Standard.StateReservoir; Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( block.Header.GasLimit, @@ -164,7 +164,7 @@ _generatedValidationIndex is null || } int surplus = _suggestedChargeableStorageReads - _generatedChargeableStorageReads; - if (validateStorageReads && surplus > 0 && _gasRemaining < surplus * Eip7928Constants.ItemCost) + if (validateStorageReads && surplus > 0 && _gasRemaining < (ulong)(surplus * Eip7928Constants.ItemCost)) { throw new InvalidBlockLevelAccessListException(block.Header, "Suggested block-level access list contained invalid storage reads."); } @@ -235,7 +235,7 @@ private void SlowPathFromGeneratedBlockAccessList(Block block, uint index, bool } int surplusSuggestedReads = suggestedReads - generatedReads; - if (validateStorageReads && surplusSuggestedReads > 0 && _gasRemaining < surplusSuggestedReads * Eip7928Constants.ItemCost) + if (validateStorageReads && surplusSuggestedReads > 0 && _gasRemaining < (ulong)(surplusSuggestedReads * Eip7928Constants.ItemCost)) { throw new InvalidBlockLevelAccessListException(block.Header, "Suggested block-level access list contained invalid storage reads."); } @@ -305,7 +305,7 @@ private void SlowPathFromColumnIndex(Block block, uint index, bool validateStora // Storage-read gas budget — counts already tracked block-cumulative on both sides. int surplusReads = _suggestedChargeableStorageReads - _generatedChargeableStorageReads; - if (validateStorageReads && surplusReads > 0 && _gasRemaining < surplusReads * Eip7928Constants.ItemCost) + if (validateStorageReads && surplusReads > 0 && _gasRemaining < (ulong)(surplusReads * Eip7928Constants.ItemCost)) { throw new InvalidBlockLevelAccessListException(block.Header, "Suggested block-level access list contained invalid storage reads."); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs index 3cab74892435..0c22592de698 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs @@ -55,7 +55,7 @@ public partial class BlockAccessListManager( private readonly Lazy _sequentialTxProcessorWithWorldStateManager = new(() => new(blockHashProvider, specProvider, stateProvider, logManager)); private const int GasValidationChunkSize = 8; - private long? _gasRemaining; + private ulong? _gasRemaining; private bool _isBuilding; private bool _blockAccessListsEnabled; @@ -161,7 +161,7 @@ public void Setup(Block block) } } - public void SpendGas(long gas) + public void SpendGas(ulong gas) { CheckInitialized(); _gasRemaining -= gas; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockAccessListSystemContractHandler.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockAccessListSystemContractHandler.cs index f8ddc7e91bc3..5069e0394ba5 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockAccessListSystemContractHandler.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockAccessListSystemContractHandler.cs @@ -32,7 +32,7 @@ public void StoreBeaconRoot(Block block, IReleaseSpec spec, ITxTracer tracer) public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spec) => balManager.ApplyBlockhashStateChanges(blockHeader, spec); - public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, long requiredBlockNumber, IReleaseSpec spec) + public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, ulong requiredBlockNumber, IReleaseSpec spec) => blockHashStore.GetBlockHashFromState(currentBlockHeader, requiredBlockNumber, spec); public void ProcessExecutionRequests(Block block, IWorldState state, TxReceipt[] receipts, IReleaseSpec spec) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs index f558f635f6cc..d6e0b54165b2 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs @@ -36,7 +36,7 @@ public virtual AddingTxEventArgs CanAddTransaction(Block block, Transaction curr { AddingTxEventArgs args = new(transactionsInBlock.Count, currentTx, block, transactionsInBlock); - long gasRemaining = block.Header.GasLimit - block.GasUsed; + ulong gasRemaining = block.Header.GasLimit - block.GasUsed; // No more gas available in block for any transactions, // the only case we have to really stop @@ -79,7 +79,7 @@ public virtual AddingTxEventArgs CanAddTransaction(Block block, Transaction curr return args.Set(TxAction.Skip, $"Sender is contract"); } - UInt256 expectedNonce = stateProvider.GetNonce(currentTx.SenderAddress); + ulong expectedNonce = stateProvider.GetNonce(currentTx.SenderAddress); if (expectedNonce != currentTx.Nonce) { return args.Set(TxAction.Skip, $"Invalid nonce - expected {expectedNonce}"); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.ParallelBlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.ParallelBlockValidationTransactionsExecutor.cs index 5d1a575147bc..dd706013a8e2 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.ParallelBlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.ParallelBlockValidationTransactionsExecutor.cs @@ -68,8 +68,8 @@ private TxReceipt[] ProcessTransactionsSequential(Block block, ProcessingOptions // makes the building intent explicit on this hot path. bool shouldValidateBal = shouldValidate && !processingOptions.ContainsFlag(ProcessingOptions.ProducingBlock); IReleaseSpec spec = specProvider.GetSpec(block.Header); - long totalRegularGas = 0; - long totalStateGas = 0; + ulong totalRegularGas = 0; + ulong totalStateGas = 0; balManager.NextTransaction(); if (shouldValidateBal) balManager.ValidateBlockAccessList(block, 0); @@ -340,7 +340,7 @@ private static void HarvestPerTxReceiptsIntoOuter(BlockReceiptsTracer[] perTxTra // exactly which tx caused the rejection. Recompute GasUsedTotal across the harvested // sequence: each per-tx tracer's _cumulativeReceiptGas only tracks that single tx // (resets to 0 per tracer), so the dump would otherwise show GasUsedTotal = GasUsed. - long cumulativeGas = 0; + ulong cumulativeGas = 0; for (int i = 0; i < length; i++) { ReadOnlySpan receipts = perTxTracers[i].TxReceipts; @@ -355,7 +355,7 @@ private static void HarvestPerTxReceiptsIntoOuter(BlockReceiptsTracer[] perTxTra private static TxReceipt[] CombineReceipts(BlockReceiptsTracer[] receiptsTracers, int len, Block block) { TxReceipt[] result = new TxReceipt[len]; - long cumulativeGas = 0; + ulong cumulativeGas = 0; Bloom blockBloom = new(); for (int i = 0; i < len; i++) { @@ -402,7 +402,7 @@ private static void ProcessTransaction( /// schedule is deterministic.
private readonly struct TxExecutionSortKey(Transaction tx, int index) : IComparable { - private readonly long _gasLimit = tx.GasLimit; + private readonly ulong _gasLimit = tx.GasLimit; private readonly int _dataLength = tx.DataLength; private readonly int _authorizationCount = tx.AuthorizationList?.Length ?? 0; private readonly int _accessListItems = GetAccessListItemCount(tx.AccessList); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.SystemContractHandler.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.SystemContractHandler.cs index 874563f0e62e..013dd6099aac 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.SystemContractHandler.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.SystemContractHandler.cs @@ -38,7 +38,7 @@ public void StoreBeaconRoot(Block block, IReleaseSpec spec, ITxTracer tracer) public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spec) => blockHashStore.ApplyBlockhashStateChanges(blockHeader, spec); - public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, long requiredBlockNumber, IReleaseSpec spec) + public Hash256? GetBlockHashFromState(BlockHeader currentBlockHeader, ulong requiredBlockNumber, IReleaseSpec spec) => blockHashStore.GetBlockHashFromState(currentBlockHeader, requiredBlockNumber, spec); public void ProcessExecutionRequests(Block block, IWorldState state, TxReceipt[] receipts, IReleaseSpec spec) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index c04b034ebcff..b709b0ade5b3 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -373,7 +373,7 @@ private void ApplyMinerReward(Block block, BlockReward reward, IReleaseSpec spec private void ApplyDaoTransition(Block block) { - long? daoBlockNumber = _specProvider.DaoBlockNumber; + ulong? daoBlockNumber = _specProvider.DaoBlockNumber; if (daoBlockNumber.HasValue && daoBlockNumber.Value == block.Header.Number) { ApplyTransition(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs index 513bbb99687a..b509d5616781 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs @@ -509,6 +509,7 @@ private void FireProcessingQueueEmpty() if (!readonlyChain) { + // Safe cast: block numbers fit well within long range for any realistic chain Metrics.BestKnownBlockNumber = _blockTree.BestKnownNumber; } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs index a1db3f6da9f3..bdeb718bfdc8 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs @@ -19,14 +19,14 @@ namespace Nethermind.Consensus.Processing.CensorshipDetector; public interface ICensorshipDetector { IEnumerable GetCensoredBlocks(); - bool BlockPotentiallyCensored(long blockNumber, ValueHash256 blockHash); + bool BlockPotentiallyCensored(ulong blockNumber, ValueHash256 blockHash); } public class NoopCensorshipDetector : ICensorshipDetector { public IEnumerable GetCensoredBlocks() => []; - public bool BlockPotentiallyCensored(long blockNumber, ValueHash256 blockHash) => false; + public bool BlockPotentiallyCensored(ulong blockNumber, ValueHash256 blockHash) => false; } public class CensorshipDetector : IDisposable, ICensorshipDetector @@ -189,6 +189,7 @@ private void Cache(Block block) if (isCensored) { Metrics.NumberOfPotentiallyCensoredBlocks++; + // Safe cast: block numbers fit well within long range for any realistic chain Metrics.LastPotentiallyCensoredBlockNumber = block.Number; DetectMultiBlockCensorship(blockNumberHash, blockCensorshipInfo); } @@ -212,6 +213,7 @@ private void DetectMultiBlockCensorship(BlockNumberHash block, BlockCensorshipIn { _censoredBlocks.Add(block); Metrics.NumberOfCensoredBlocks++; + // Safe cast: block numbers fit well within long range for any realistic chain Metrics.LastCensoredBlockNumber = block.Number; if (_logger.IsInfo) _logger.Info($"Censorship detected for block {block.Number} with hash {block.Hash!}"); } @@ -221,7 +223,7 @@ bool DetectPastBlockCensorship() // Censorship is detected if potential censorship is flagged for the last _blockCensorshipThreshold blocks including the latest. if (block.Number >= _blockCensorshipThreshold) { - long blockNumber = block.Number - 1; + ulong blockNumber = block.Number - 1; ValueHash256 parentHash = blockCensorshipInfo.ParentHash!.Value; for (int i = 1; i < _blockCensorshipThreshold; i++) { @@ -245,14 +247,14 @@ bool DetectPastBlockCensorship() public IEnumerable GetCensoredBlocks() => _censoredBlocks; - public bool BlockPotentiallyCensored(long blockNumber, ValueHash256 blockHash) => _potentiallyCensoredBlocks.Contains(new BlockNumberHash(blockNumber, blockHash)); + public bool BlockPotentiallyCensored(ulong blockNumber, ValueHash256 blockHash) => _potentiallyCensoredBlocks.Contains(new BlockNumberHash(blockNumber, blockHash)); public void Dispose() => _blockProcessor.BlockProcessing -= OnBlockProcessing; } public readonly record struct BlockCensorshipInfo(bool IsCensored, ValueHash256? ParentHash); -public readonly record struct BlockNumberHash(long Number, ValueHash256 Hash) : IEquatable +public readonly record struct BlockNumberHash(ulong Number, ValueHash256 Hash) : IEquatable { public BlockNumberHash(Block block) : this(block.Number, block.Hash ?? block.CalculateHash()) { } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/Metrics.cs b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/Metrics.cs index 8b1b45758cb5..5dbfbbd366b6 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/Metrics.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/Metrics.cs @@ -18,9 +18,9 @@ public static class Metrics [GaugeMetric] [Description("Number of last potentially censored block.")] - public static long LastPotentiallyCensoredBlockNumber; + public static ulong LastPotentiallyCensoredBlockNumber; [GaugeMetric] [Description("Number of last known censored block.")] - public static long LastCensoredBlockNumber; + public static ulong LastCensoredBlockNumber; } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/GasValidationResultSlot.cs b/src/Nethermind/Nethermind.Consensus/Processing/GasValidationResultSlot.cs index f6de8d55f907..472a8d5cb189 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/GasValidationResultSlot.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/GasValidationResultSlot.cs @@ -11,8 +11,8 @@ namespace Nethermind.Consensus.Processing; public readonly record struct GasValidationResult( - long BlockGasUsed, - long BlockStateGasUsed, + ulong BlockGasUsed, + ulong BlockStateGasUsed, IntrinsicGas IntrinsicGas, InvalidBlockException? Exception); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IBlockAccessListManager.cs b/src/Nethermind/Nethermind.Consensus/Processing/IBlockAccessListManager.cs index 5dac84b776ce..09e3b501ebc5 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IBlockAccessListManager.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IBlockAccessListManager.cs @@ -24,7 +24,7 @@ public interface IBlockAccessListManager void PrepareForProcessing(Block suggestedBlock, IReleaseSpec spec, ProcessingOptions options); void Setup(Block block); - void SpendGas(long gas); + void SpendGas(ulong gas); void SetBlockExecutionContext(in BlockExecutionContext blockExecutionContext); ITransactionProcessorAdapter GetTxProcessor(uint? balIndex = null); void NextTransaction(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockAccessListManager.cs b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockAccessListManager.cs index 08a75f62a4f2..c8317d4b2e5b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockAccessListManager.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockAccessListManager.cs @@ -25,7 +25,7 @@ private NullBlockAccessListManager() { } public void PrepareForProcessing(Block suggestedBlock, IReleaseSpec spec, ProcessingOptions options) { } public void Setup(Block block) { } - public void SpendGas(long gas) { } + public void SpendGas(ulong gas) { } public void SetBlockExecutionContext(in BlockExecutionContext blockExecutionContext) { } public ITransactionProcessorAdapter GetTxProcessor(uint? balIndex = null) => throw new InvalidOperationException("NullBlockAccessListManager does not provide transaction processors."); public void NextTransaction() { } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 1abce70c337e..7ee5a1a4ae10 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -24,7 +24,7 @@ namespace Nethermind.Consensus.Processing public class BlockStatistics { public long BlockCount { get; set; } - public long BlockFrom { get; set; } + public ulong BlockFrom { get; set; } public long BlockTo { get; set; } public double ProcessingMs { get; set; } public double SlotMs { get; set; } @@ -34,7 +34,7 @@ public class BlockStatistics public float MedianGas { get; set; } public float AveGas { get; set; } public float MaxGas { get; set; } - public long GasLimit { get; set; } + public ulong GasLimit { get; set; } } //TODO Consult on disabling of such metrics from configuration public class ProcessingStats : IProcessingStats @@ -105,7 +105,7 @@ public class ProcessingStats : IProcessingStats private long _chunkTx; private long _chunkBlobs; private long _chunkBlocks; - private long _chunkFirstBlockNumber = -1; + private ulong _chunkFirstBlockNumber = ulong.MaxValue; private long _opCodes; private long _callOps; private long _emptyCalls; @@ -214,7 +214,7 @@ public void UpdateStats(IReadOnlyList blocks, BlockHeader? baseBlock, lon if (blocks.Count == 0) return; Block lastBlock = blocks[^1]; - long gasUsed = 0; + ulong gasUsed = 0; long transactionCount = 0; long blobCount = 0; for (int i = 0; i < blocks.Count; i++) @@ -336,7 +336,7 @@ protected virtual void GenerateReport(BlockData data) Block? block = data.Block; if (block is null) return; - long blockNumber = data.Block.Number; + ulong blockNumber = data.Block.Number; double chunkMGas = (_chunkMGas += data.GasUsed / 1_000_000.0); // We want the rate here @@ -362,8 +362,8 @@ protected virtual void GenerateReport(BlockData data) double chunkMicroseconds = (_chunkProcessingMicroseconds += data.ProcessingMicroseconds); double chunkTx = (_chunkTx += data.TransactionCount); - long chunkFirstBlockNumber = _chunkFirstBlockNumber; - if (chunkFirstBlockNumber == -1) + ulong chunkFirstBlockNumber = _chunkFirstBlockNumber; + if (chunkFirstBlockNumber == ulong.MaxValue) { chunkFirstBlockNumber = data.FirstBlockNumber; _chunkFirstBlockNumber = chunkFirstBlockNumber; @@ -371,8 +371,9 @@ protected virtual void GenerateReport(BlockData data) long chunkBlocks = (_chunkBlocks += data.BlockCount); - Metrics.Blocks = blockNumber; - Metrics.BlockchainHeight = blockNumber; + // Safe cast: block numbers fit well within long range for any realistic chain + Metrics.Blocks = (long)blockNumber; + Metrics.BlockchainHeight = (long)blockNumber; Metrics.Transactions += data.TransactionCount; Metrics.TotalDifficulty = block.TotalDifficulty ?? UInt256.Zero; @@ -445,7 +446,7 @@ protected virtual void GenerateReport(BlockData data) _chunkBlobs = 0; _chunkBlocks = 0; - _chunkFirstBlockNumber = -1; + _chunkFirstBlockNumber = ulong.MaxValue; _chunkMGas = 0; _chunkTx = 0; _chunkProcessingMicroseconds = 0; @@ -485,7 +486,7 @@ protected virtual void GenerateReport(BlockData data) { BlockCount = chunkBlocks, BlockFrom = chunkFirstBlockNumber, - BlockTo = block.Number, + BlockTo = (long)block.Number, ProcessingMs = chunkMs, SlotMs = runMs, @@ -847,8 +848,8 @@ protected class BlockData public Block Block; public BlockHeader? BaseBlock; public long BlockCount; - public long FirstBlockNumber; - public long GasUsed; + public ulong FirstBlockNumber; + public ulong GasUsed; public long TransactionCount; public long BlobCount; public long CurrentOpCodes; diff --git a/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs b/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs index 76a49e928601..84f69f533bee 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs @@ -28,7 +28,7 @@ public class PayloadAttributes public ulong? SlotNumber { get; set; } - public virtual long? GetGasLimit() => null; + public virtual ulong? GetGasLimit() => null; public override string ToString() => ToString(string.Empty); diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 51ae0aadeaba..2ede66225923 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -40,9 +40,9 @@ public class TxPoolTxSource( private readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); protected readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) { - long blockNumber = parent.Number + 1; + ulong blockNumber = parent.Number + 1; IReleaseSpec spec = NextBlockSpecHelper.GetSpec(_specProvider, parent, payloadAttributes, blocksConfig); UInt256 baseFee = BaseFeeCalculator.Calculate(parent, spec); IDictionary pendingTransactions = filterSource ? @@ -56,7 +56,7 @@ public IEnumerable GetTransactions(BlockHeader parent, long gasLimi int maxBlobCount = spec.MaxProductionBlobCount(blocksConfig.BlockProductionBlobLimit); IEnumerable transactions = GetOrderedTransactions(pendingTransactions, comparer, filter, gasLimit); - IEnumerable<(Transaction tx, long blobChain)> blobTransactions = GetOrderedBlobTransactions(pendingBlobTransactionsEquivalences, comparer, filter, maxBlobCount); + IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions = GetOrderedBlobTransactions(pendingBlobTransactionsEquivalences, comparer, filter, maxBlobCount); if (_logger.IsDebug) _logger.Debug($"Collecting pending transactions at block gas limit {gasLimit}."); int checkedTransactions = 0; @@ -151,7 +151,7 @@ private static IEnumerable PickBlobTxsBetterThanCurrentTx(ArrayPool } } - private void SelectBlobTransactions(IEnumerable<(Transaction tx, long blobChain)> blobTransactions, BlockHeader parent, IReleaseSpec spec, in UInt256 baseFee, ArrayPoolList selectedBlobTxs, int maxBlobs) + private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions, BlockHeader parent, IReleaseSpec spec, in UInt256 baseFee, ArrayPoolList selectedBlobTxs, int maxBlobs) { int maxBlobsToConsider = maxBlobs * 5; int countOfRemainingBlobs = 0; @@ -162,8 +162,8 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, long blobChain) return; } - ArrayPoolList<(Transaction tx, long blobChain)>? candidates = null; - foreach ((Transaction blobTx, long blobChain) in blobTransactions) + ArrayPoolList<(Transaction tx, ulong blobChain)>? candidates = null; + foreach ((Transaction blobTx, ulong blobChain) in blobTransactions) { int txBlobCount = blobTx.GetBlobCount(); if (txBlobCount > maxBlobs) @@ -213,7 +213,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, long blobChain) if (countOfRemainingBlobs <= leftoverCapacity) { // We can take all, no optimal picking needed. - foreach ((Transaction tx, long blobChain) tx in candidates.AsSpan()) + foreach ((Transaction tx, ulong blobChain) tx in candidates.AsSpan()) { selectedBlobTxs.Add(tx.tx); } @@ -240,7 +240,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, long blobChain) /// Existing entries remain untouched; chosen ones are appended at the end. /// private static void ChooseBestBlobTransactions( - ArrayPoolList<(Transaction tx, long blobChain)> candidateTxs, + ArrayPoolList<(Transaction tx, ulong blobChain)> candidateTxs, int leftoverCapacity, in UInt256 baseFee, ArrayPoolList selectedBlobTxs) @@ -257,7 +257,7 @@ private static void ChooseBestBlobTransactions( // Inner loop: iterate capacity in descending order to avoid overwriting data needed for the calculation. for (int i = 0; i < candidateTxs.Count; i++) { - (Transaction tx, long blobChain) = candidateTxs[i]; + (Transaction tx, ulong blobChain) = candidateTxs[i]; if (!tx.TryCalculatePremiumPerGas(baseFee, out UInt256 premiumPerGas)) { @@ -270,17 +270,17 @@ private static void ChooseBestBlobTransactions( // If this tx has explicit dependencies (i.e. it requires k prior blobs // from the *same address* to be in the block before it), include them here. // We'll need a capacity of blobDependenciesCount slots *plus* its own blobCount. - long blobCapacityNeeded = blobChain + blobCount; + ulong blobCapacityNeeded = blobChain + (ulong)blobCount; // Compute the total fee this tx contributes (premium * gas used). // Use actual gas used (SpentGas) when available as the tx may be using over-estimated gaslimit - ulong feeValue = (ulong)premiumPerGas * (ulong)tx.SpentGas; + ulong feeValue = (ulong)premiumPerGas * tx.SpentGas; int dependencyIndex = -1; // If dependencies, look back for the one direct predecessor tx. // if blobDependenciesCount > 0, then we require *the* previous // nonce from the same address to also be chosen in order to // include this tx's extra blob-dependency slots. - if (blobCapacityNeeded > blobCount) + if (blobCapacityNeeded > (ulong)blobCount) { // scan backward from i–1 until you hit a tx from the same address // this ensures we only link to the immediate prior-nonce. @@ -309,7 +309,7 @@ private static void ChooseBestBlobTransactions( // Iterate backward from maxBlobCapacity down to blobCount (from high to low to avoid overwrite) // so we only compute for valid capacities that can fit this transaction. - for (int capacity = leftoverCapacity; capacity >= blobCapacityNeeded; capacity--) + for (int capacity = leftoverCapacity; capacity >= (int)blobCapacityNeeded; capacity--) { // We subtract only tx's own blobCount from capacity, // because the dpFees index represents total blobs used; @@ -380,24 +380,24 @@ private bool TryUpdateFeePerBlobGas(BlockHeader parent, IReleaseSpec spec, out U return true; } - protected virtual IEnumerable GetOrderedTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, long gasLimit) => + protected virtual IEnumerable GetOrderedTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, ulong gasLimit) => Order(pendingTransactions, comparer, filter, gasLimit); - private static IEnumerable<(Transaction tx, long blobChain)> GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, int maxBlobs = 0) => - OrderCore(pendingTransactions, comparer, static tx => tx.GetBlobCount(), filter, maxBlobs); + private static IEnumerable<(Transaction tx, ulong blobChain)> GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, int maxBlobs = 0) => + OrderCore(pendingTransactions, comparer, static tx => (ulong)tx.GetBlobCount(), filter, (ulong)maxBlobs); protected virtual IComparer GetComparer(BlockHeader parent, BlockPreparationContext blockPreparationContext) => _transactionComparerProvider.GetDefaultProducerComparer(blockPreparationContext); - internal static IEnumerable Order(IDictionary pendingTransactions, IComparer comparer, Func filter, long gasLimit) => + internal static IEnumerable Order(IDictionary pendingTransactions, IComparer comparer, Func filter, ulong gasLimit) => OrderCore(pendingTransactions, comparer, static tx => tx.BlockGasUsed, filter, gasLimit).Select(static tx => tx.tx); - private static IEnumerable<(Transaction tx, long resource)> OrderCore( + private static IEnumerable<(Transaction tx, ulong resource)> OrderCore( IDictionary pendingTransactions, IComparer comparer, - Func resourceSelector, + Func resourceSelector, Func filter, - long resourceLimit) + ulong resourceLimit) { using ArrayPoolList> bySenderEnumerators = pendingTransactions .Select, IEnumerable>(static g => g.Value) @@ -406,15 +406,15 @@ internal static IEnumerable Order(IDictionary, long)> transactions = SortEnumerators(bySenderEnumerators, comparer); + DictionarySortedSet, ulong)> transactions = SortEnumerators(bySenderEnumerators, comparer); while (transactions.Count > 0) { - (Transaction candidateTx, (IEnumerator enumerator, long resourceChain)) = transactions.Min; + (Transaction candidateTx, (IEnumerator enumerator, ulong resourceChain)) = transactions.Min; transactions.Remove(candidateTx); - long totalResource = resourceChain + resourceSelector(candidateTx); + ulong totalResource = resourceChain + resourceSelector(candidateTx); if (totalResource > resourceLimit) continue; @@ -438,9 +438,9 @@ internal static IEnumerable Order(IDictionary, long)> SortEnumerators(ArrayPoolList> bySenderEnumerators, IComparer comparerWithIdentity) + private static DictionarySortedSet, ulong)> SortEnumerators(ArrayPoolList> bySenderEnumerators, IComparer comparerWithIdentity) { - DictionarySortedSet, long)> transactions = new(comparerWithIdentity); + DictionarySortedSet, ulong)> transactions = new(comparerWithIdentity); foreach (IEnumerator enumerator in bySenderEnumerators.AsSpan()) { diff --git a/src/Nethermind/Nethermind.Consensus/SealEngine.cs b/src/Nethermind/Nethermind.Consensus/SealEngine.cs index 91b7a9bcfe8f..3ede70c9ae4c 100644 --- a/src/Nethermind/Nethermind.Consensus/SealEngine.cs +++ b/src/Nethermind/Nethermind.Consensus/SealEngine.cs @@ -17,7 +17,7 @@ public class SealEngine(ISealer? sealer, ISealValidator? sealValidator) : ISealE public Task SealBlock(Block block, CancellationToken cancellationToken) => _sealer.SealBlock(block, cancellationToken); - public bool CanSeal(long blockNumber, Hash256 parentHash) => + public bool CanSeal(ulong blockNumber, Hash256 parentHash) => _sealer.CanSeal(blockNumber, parentHash); public Address Address => _sealer.Address; diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs index 68948143e263..d9375968b346 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs @@ -23,25 +23,25 @@ public class StatelessBlockTree(IReadOnlyCollection headers) private readonly Dictionary _hashToHeader = headers.ToDictionary(header => (Hash256AsKey)(header.Hash ?? throw new ArgumentNullException(nameof(header.Hash))), header => header); - private readonly Dictionary _numberToHeader = + private readonly Dictionary _numberToHeader = headers.ToDictionary(header => header.Number, header => header); - public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => throw new NotSupportedException(); - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => + public Block? FindBlock(ulong blockNumber, BlockTreeLookupOptions options) => throw new NotSupportedException(); - public bool HasBlock(long blockNumber, Hash256 blockHash) => + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => throw new NotSupportedException(); - public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => _hashToHeader.GetValueOrDefault(blockHash); - public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) + public BlockHeader? FindHeader(ulong blockNumber, BlockTreeLookupOptions options) => _numberToHeader.GetValueOrDefault(blockNumber); - public Hash256? FindBlockHash(long blockNumber) + public Hash256? FindBlockHash(ulong blockNumber) => _numberToHeader.GetValueOrDefault(blockNumber)?.Hash; public bool IsMainChain(BlockHeader blockHeader) @@ -53,7 +53,7 @@ public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) public BlockHeader FindBestSuggestedHeader() => throw new NotSupportedException(); - public long GetLowestBlock() + public ulong GetLowestBlock() => throw new NotSupportedException(); public Hash256 HeadHash => throw new NotSupportedException(); @@ -63,7 +63,7 @@ public long GetLowestBlock() public Hash256? SafeHash => throw new NotSupportedException(); public Block? Head => throw new NotSupportedException(); - public long? BestPersistedState + public ulong? BestPersistedState { get => throw new NotSupportedException(); set => throw new NotSupportedException(); @@ -88,8 +88,8 @@ public BlockHeader? LowestInsertedBeaconHeader set => throw new NotSupportedException(); } - public long BestKnownNumber => throw new NotSupportedException(); - public long BestKnownBeaconNumber => throw new NotSupportedException(); + public ulong BestKnownNumber => throw new NotSupportedException(); + public ulong BestKnownBeaconNumber => throw new NotSupportedException(); public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) @@ -116,13 +116,13 @@ public ValueTask SuggestBlockAsync(Block block, BlockTreeSuggest public AddBlockResult SuggestHeader(BlockHeader header) => throw new NotSupportedException(); - public bool IsKnownBlock(long number, Hash256 blockHash) + public bool IsKnownBlock(ulong number, Hash256 blockHash) => throw new NotSupportedException(); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) + public bool IsKnownBeaconBlock(ulong number, Hash256 blockHash) => throw new NotSupportedException(); - public bool WasProcessed(long number, Hash256 blockHash) + public bool WasProcessed(ulong number, Hash256 blockHash) => throw new NotSupportedException(); public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) @@ -134,16 +134,16 @@ public void MarkChainAsProcessed(IReadOnlyList blocks) public bool CanAcceptNewBlocks => throw new NotSupportedException(); public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) => throw new NotSupportedException(); - public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) + public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(ulong number, Hash256 blockHash) => throw new NotSupportedException(); - public ChainLevelInfo? FindLevel(long number) + public ChainLevelInfo? FindLevel(ulong number) => throw new NotSupportedException(); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) + public BlockInfo FindCanonicalBlockInfo(ulong blockNumber) => throw new NotSupportedException(); - public Hash256 FindHash(long blockNumber) + public Hash256? FindHash(ulong blockNumber) => throw new NotSupportedException(); public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) @@ -180,19 +180,19 @@ public event EventHandler? OnUpdateMainChain add => throw new NotSupportedException(); remove => throw new NotSupportedException(); } - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) + public int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false) => throw new NotSupportedException(); public bool IsBetterThanHead(BlockHeader? header) => throw new NotSupportedException(); - public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint) + public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint) => throw new NotSupportedException(); public void RecalculateTreeLevels() => throw new NotSupportedException(); - public (long BlockNumber, Hash256 BlockHash) SyncPivot + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get => throw new NotSupportedException(); set => throw new NotSupportedException(); @@ -204,9 +204,9 @@ public bool IsProcessingBlock set => throw new NotSupportedException(); } - public void NewOldestBlock(long oldestBlock) => throw new NotImplementedException(); + public void NewOldestBlock(ulong oldestBlock) => throw new NotImplementedException(); - public void DeleteOldBlock(long blockNumber, Hash256 blockHash) => throw new NotImplementedException(); + public void DeleteOldBlock(ulong blockNumber, Hash256 blockHash) => throw new NotImplementedException(); public event EventHandler? OnForkChoiceUpdated { @@ -217,7 +217,7 @@ public event EventHandler? OnForkChoiceUpd public Hash256? GetHash(BlockHeader headBlock, int depth) => depth == 0 ? headBlock.Hash - : _numberToHeader.TryGetValue(headBlock.Number - depth, out BlockHeader? header) + : _numberToHeader.TryGetValue(headBlock.Number - (ulong)depth, out BlockHeader? header) ? header?.Hash : null; @@ -228,7 +228,7 @@ public event EventHandler? OnForkChoiceUpd result[0] = blockHeader.Hash; for (int i = 1; i < length; i++) { - if (_numberToHeader.TryGetValue(blockHeader.Number - i, out BlockHeader header)) + if (_numberToHeader.TryGetValue(blockHeader.Number - (ulong)i, out BlockHeader header)) { result[i] = header.Hash; } diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessCapturingTrieStore.cs b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessCapturingTrieStore.cs index 767dd9bf41db..acdeee1aabd7 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessCapturingTrieStore.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessCapturingTrieStore.cs @@ -50,7 +50,7 @@ public TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256 public INodeStorage.KeyScheme Scheme => baseStore.Scheme; - public IBlockCommitter BeginBlockCommit(long blockNumber) => NullCommitter.Instance; + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => NullCommitter.Instance; // WitnessCapturingTrieStore is read-only, so we return a no-op committer that doesn't persist any trie nodes public ICommitter BeginCommit(Hash256? address, TrieNode? root, WriteFlags writeFlags) => NullCommitter.Instance; diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs index 5de4415b167b..747be523102b 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs @@ -13,9 +13,9 @@ namespace Nethermind.Consensus.Stateless; public class WitnessGeneratingHeaderFinder(IHeaderFinder inner) : IHeaderFinder { private static readonly HeaderDecoder _decoder = new(); - private long _lowestRequestedHeader = long.MaxValue; + private ulong _lowestRequestedHeader = ulong.MaxValue; - public BlockHeader? Get(Hash256 blockHash, long? blockNumber = null) + public BlockHeader? Get(Hash256 blockHash, ulong? blockNumber = null) { BlockHeader? header = inner.Get(blockHash, blockNumber); if (header is not null && header.Number < _lowestRequestedHeader) @@ -33,9 +33,9 @@ public IOwnedReadOnlyList GetWitnessHeaders(Hash256 parentHash) BlockHeader childHeader = inner.Get(currentHash) ?? throw new ArgumentException($"Parent {currentHash} is not found"); headers.Add(_decoder.Encode(childHeader).Bytes); - if (_lowestRequestedHeader < long.MaxValue) + if (_lowestRequestedHeader < ulong.MaxValue) { - for (long i = childHeader.Number - 1; i >= _lowestRequestedHeader; i--) + for (ulong i = childHeader.Number - 1; i >= _lowestRequestedHeader && i != ulong.MaxValue; i--) { currentHash = childHeader.ParentHash!; childHeader = inner.Get(currentHash, i) ?? throw new ArgumentException($"Unable to get requested header at hash {currentHash} and number {i} during witness generation"); diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingWorldState.cs b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingWorldState.cs index df5a26834c57..0a8aaa46180e 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingWorldState.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingWorldState.cs @@ -215,13 +215,13 @@ public void DeleteAccount(Address address) inner.DeleteAccount(address); } - public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { RecordEmptySlots(address); inner.CreateAccount(address, in balance, in nonce); } - public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default) { RecordEmptySlots(address); inner.CreateAccountIfNotExists(address, in balance, in nonce); @@ -257,19 +257,19 @@ public void SubtractFromBalance(Address address, in UInt256 balanceChange, IRele inner.SubtractFromBalance(address, in balanceChange, spec, out oldBalance); } - public void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce) + public void IncrementNonce(Address address, ulong delta, out ulong oldNonce) { RecordEmptySlots(address); inner.IncrementNonce(address, delta, out oldNonce); } - public void DecrementNonce(Address address, UInt256 delta) + public void DecrementNonce(Address address, ulong delta) { RecordEmptySlots(address); inner.DecrementNonce(address, delta); } - public void SetNonce(Address address, in UInt256 nonce) + public void SetNonce(Address address, in ulong nonce) { RecordEmptySlots(address); inner.SetNonce(address, nonce); @@ -281,7 +281,7 @@ public void Commit(IReleaseSpec releaseSpec, bool isGenesis = false, bool commit public void Commit(IReleaseSpec releaseSpec, IWorldStateTracer tracer, bool isGenesis = false, bool commitRoots = true) => inner.Commit(releaseSpec, tracer, isGenesis, commitRoots); - public void CommitTree(long blockNumber) => inner.CommitTree(blockNumber); + public void CommitTree(ulong blockNumber) => inner.CommitTree(blockNumber); public ArrayPoolList? GetAccountChanges() => inner.GetAccountChanges(); diff --git a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs index 90153d6ff643..dfb70b085787 100644 --- a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs @@ -13,20 +13,21 @@ public class TargetAdjustedGasLimitCalculator(ISpecProvider? specProvider, IBloc private readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); private readonly IBlocksConfig _blocksConfig = blocksConfig ?? throw new ArgumentNullException(nameof(blocksConfig)); - public long GetGasLimit(BlockHeader parentHeader) + public ulong GetGasLimit(BlockHeader parentHeader) { - long parentGasLimit = parentHeader.GasLimit; - long gasLimit = parentGasLimit; + ulong parentGasLimit = parentHeader.GasLimit; + ulong gasLimit = parentGasLimit; long? targetGasLimit = _blocksConfig.TargetBlockGasLimit; - long newBlockNumber = parentHeader.Number + 1; + ulong newBlockNumber = parentHeader.Number + 1; IReleaseSpec spec = _specProvider.GetSpec(newBlockNumber, parentHeader.Timestamp); // taking the parent timestamp is a temporary solution if (targetGasLimit is not null) { - long maxGasLimitDifference = Math.Max(0, parentGasLimit / spec.GasLimitBoundDivisor - 1); - gasLimit = targetGasLimit.Value > parentGasLimit - ? parentGasLimit + Math.Min(targetGasLimit.Value - parentGasLimit, maxGasLimitDifference) - : parentGasLimit - Math.Min(parentGasLimit - targetGasLimit.Value, maxGasLimitDifference); + ulong target = (ulong)targetGasLimit.Value; + ulong maxGasLimitDifference = Math.Max(0UL, parentGasLimit / spec.GasLimitBoundDivisor - 1); + gasLimit = target > parentGasLimit + ? parentGasLimit + Math.Min(target - parentGasLimit, maxGasLimitDifference) + : parentGasLimit - Math.Min(parentGasLimit - target, maxGasLimitDifference); } gasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(spec, gasLimit, newBlockNumber); diff --git a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs index 7245149bfd6d..cd16cb2d4b92 100644 --- a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs +++ b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs @@ -83,7 +83,7 @@ public class GethStyleTracer( return TraceImpl(block, txHash, cancellationToken, traceOptions, writer: writer, pipeWriter: pipeWriter); } - public GethLikeTxTrace? Trace(long blockNumber, int txIndex, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null) + public GethLikeTxTrace? Trace(ulong blockNumber, int txIndex, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null) { Block block = blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical) ?? throw new InvalidOperationException($"No historical block found for {blockNumber}"); if (txIndex > block.Transactions.Length - 1) throw new InvalidOperationException($"Block {blockNumber} has only {block.Transactions.Length} transactions and the requested tx index was {txIndex}"); @@ -91,7 +91,7 @@ public class GethStyleTracer( return TraceImpl(block, block.Transactions[txIndex].Hash, cancellationToken, options, writer: writer, pipeWriter: pipeWriter); } - public GethLikeTxTrace? Trace(long blockNumber, Transaction tx, GethTraceOptions options, CancellationToken cancellationToken) + public GethLikeTxTrace? Trace(ulong blockNumber, Transaction tx, GethTraceOptions options, CancellationToken cancellationToken) { Block block = blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical) ?? throw new InvalidOperationException($"No historical block found for {blockNumber}"); if (tx.Hash is null) throw new InvalidOperationException("Cannot trace transactions without tx hash set."); diff --git a/src/Nethermind/Nethermind.Consensus/Tracing/IGethStyleTracer.cs b/src/Nethermind/Nethermind.Consensus/Tracing/IGethStyleTracer.cs index f4f42e467cc0..e5d5078864cd 100644 --- a/src/Nethermind/Nethermind.Consensus/Tracing/IGethStyleTracer.cs +++ b/src/Nethermind/Nethermind.Consensus/Tracing/IGethStyleTracer.cs @@ -21,8 +21,8 @@ public interface IGethStyleTracer /// produced (returned value contains only the header fields). ///
GethLikeTxTrace? Trace(Hash256 txHash, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); - GethLikeTxTrace? Trace(long blockNumber, Transaction transaction, GethTraceOptions options, CancellationToken cancellationToken); - GethLikeTxTrace? Trace(long blockNumber, int txIndex, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); + GethLikeTxTrace? Trace(ulong blockNumber, Transaction transaction, GethTraceOptions options, CancellationToken cancellationToken); + GethLikeTxTrace? Trace(ulong blockNumber, int txIndex, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? Trace(Hash256 blockHash, int txIndex, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? Trace(Rlp blockRlp, Hash256 txHash, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? Trace(Block block, Hash256 txHash, GethTraceOptions options, CancellationToken cancellationToken, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/CompositeTxSource.cs b/src/Nethermind/Nethermind.Consensus/Transactions/CompositeTxSource.cs index f08ace666db5..8271e6156012 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/CompositeTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/CompositeTxSource.cs @@ -25,7 +25,7 @@ public CompositeTxSource(params ITxSource[] transactionSources) public void First(ITxSource txSource) => _transactionSources.Insert(0, txSource); - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) { for (int i = 0; i < _transactionSources.Count; i++) { diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/EmptyTxSource.cs b/src/Nethermind/Nethermind.Consensus/Transactions/EmptyTxSource.cs index 98061703b949..2e3e18756a87 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/EmptyTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/EmptyTxSource.cs @@ -16,6 +16,6 @@ private EmptyTxSource() { } public static ITxSource Instance { get; } = new EmptyTxSource(); - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => Array.Empty(); + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => Array.Empty(); } } diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/FilteredTxSource.cs b/src/Nethermind/Nethermind.Consensus/Transactions/FilteredTxSource.cs index 281cd6d19586..945449d2a525 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/FilteredTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/FilteredTxSource.cs @@ -18,7 +18,7 @@ public class FilteredTxSource(ITxSource innerSource, ITxFilter txFilter, ILog public bool SupportsBlobs => innerSource.SupportsBlobs; - public IEnumerable GetTransactions(BlockHeader parentHeader, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) + public IEnumerable GetTransactions(BlockHeader parentHeader, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) { IReleaseSpec currentSpec = NextBlockSpecHelper.GetSpec(specProvider, parentHeader, payloadAttributes, blocksConfig); diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/ITxSource.cs b/src/Nethermind/Nethermind.Consensus/Transactions/ITxSource.cs index f6c240ed6f51..e836095e3cd3 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/ITxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/ITxSource.cs @@ -9,7 +9,7 @@ namespace Nethermind.Consensus.Transactions { public interface ITxSource { - IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false); + IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false); bool SupportsBlobs { get; } } } diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/OneByOneTxSource.cs b/src/Nethermind/Nethermind.Consensus/Transactions/OneByOneTxSource.cs index dca1393be039..bcf5656608f3 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/OneByOneTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/OneByOneTxSource.cs @@ -13,7 +13,7 @@ public class OneByOneTxSource(ITxSource txSource) : ITxSource public bool SupportsBlobs => _txSource.SupportsBlobs; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) { foreach (Transaction transaction in _txSource.GetTransactions(parent, gasLimit, payloadAttributes, filterSource)) { diff --git a/src/Nethermind/Nethermind.Consensus/Transactions/SinglePendingTxSelector.cs b/src/Nethermind/Nethermind.Consensus/Transactions/SinglePendingTxSelector.cs index d31bab771bd3..da07751c87ae 100644 --- a/src/Nethermind/Nethermind.Consensus/Transactions/SinglePendingTxSelector.cs +++ b/src/Nethermind/Nethermind.Consensus/Transactions/SinglePendingTxSelector.cs @@ -14,7 +14,7 @@ public class SinglePendingTxSelector(ITxSource innerSource) : ITxSource public bool SupportsBlobs => _innerSource.SupportsBlobs; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) => + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) => _innerSource.GetTransactions(parent, gasLimit, payloadAttributes, filterSource) .OrderBy(static t => t.Nonce) .ThenByDescending(static t => t.Timestamp) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index fbc94691ae71..e057023a89fa 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -459,9 +459,9 @@ private bool ValidateBlockLevelAccessListSize(Block block, ref string? error) // Suggested/engine blocks carry the wire BAL in BlockAccessList. RLP/P2P // validation reaches this helper after execution with only GeneratedBlockAccessList. int itemCount = block.BlockAccessList?.ItemCount ?? block.GeneratedBlockAccessList?.ItemCount ?? 0; - long maxBalItems = block.Header.GasLimit / Eip7928Constants.ItemCost; + ulong maxBalItems = block.Header.GasLimit / Eip7928Constants.ItemCost; - if (itemCount > maxBalItems) + if (itemCount > 0 && (ulong)itemCount > maxBalItems) { error = BlockErrorMessages.BlockAccessListGasLimitExceeded(itemCount, maxBalItems); if (_logger.IsWarn) _logger.Warn($"{Invalid(block)} {error}"); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index dfd357e5344e..071aba383249 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -27,7 +27,7 @@ public class HeaderValidator( protected readonly ISealValidator _sealValidator = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator)); protected readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); - private readonly long? _daoBlockNumber = specProvider.DaoBlockNumber; + private readonly ulong? _daoBlockNumber = specProvider.DaoBlockNumber; protected readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); protected readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); @@ -211,42 +211,19 @@ protected virtual bool ValidateSeal(BlockHeader header, BlockHeader parent, bool return result; } - protected virtual bool ValidateFieldLimit(BlockHeader blockHeader, ref string? error) - { - // Note, these are out of spec. Technically, there could be a block with field with very high value that is - // valid when using ulong, but wrapped to negative value when using long. However, switching to ulong - // at this point can cause other unexpected error. So we just won't support it for now. - - error = blockHeader switch - { - { Number: < 0 } => BlockErrorMessages.NegativeBlockNumber, - { GasLimit: < 0 } => BlockErrorMessages.NegativeGasLimit, - { GasUsed: < 0 } => BlockErrorMessages.NegativeGasUsed, - _ => null - }; - - if (error is null) return true; - - if (_logger.IsWarn) - _logger.Warn($"Invalid block header ({blockHeader.Hash}) - {blockHeader switch - { - { Number: < 0 } => $"Block number is negative {blockHeader.Number}", - { GasLimit: < 0 } => $"Block GasLimit is negative {blockHeader.GasLimit}", - { GasUsed: < 0 } => $"Block GasUsed is negative {blockHeader.GasUsed}", - _ => error - }}"); - - return false; - - } + protected virtual bool ValidateFieldLimit(BlockHeader blockHeader, ref string? error) => + // Number, GasLimit and GasUsed are ulong — they can never be negative. + // This method is kept for subclass extensibility; no checks are needed at this level. + true; protected virtual bool ValidateExtraData(BlockHeader header, IReleaseSpec spec, bool isUncle, ref string? error) { bool extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize && (isUncle || _daoBlockNumber is null - || header.Number < _daoBlockNumber - || header.Number >= _daoBlockNumber + 10 + // Safe cast: DaoBlockNumber is a known small constant (~1.9M), always fits ulong + || header.Number < (ulong)_daoBlockNumber.Value + || header.Number >= (ulong)(_daoBlockNumber.Value + 10) || Bytes.AreEqual(header.ExtraData, DaoExtraData)); if (!extraDataValid) { @@ -263,15 +240,15 @@ protected virtual bool ValidateGasLimitRange(BlockHeader header, BlockHeader par // Gas-limit-vs-parent comparisons don't apply at genesis, so skip them. if (parent is null) return true; - long adjustedParentGasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(spec, parent.GasLimit, header.Number); - long maxGasLimitDifference = adjustedParentGasLimit / spec.GasLimitBoundDivisor; + ulong adjustedParentGasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(spec, parent.GasLimit, header.Number); + ulong maxGasLimitDifference = adjustedParentGasLimit / spec.GasLimitBoundDivisor; - long maxNextGasLimit = adjustedParentGasLimit + maxGasLimitDifference; - bool notToHighWithOverflow = long.MaxValue - maxGasLimitDifference < adjustedParentGasLimit; - // The edge case used in hive tests. If adjustedParentGasLimit + maxGasLimitDifference >= long.MaxValue, - // we can check for long.MaxValue - maxGasLimitDifference < adjustedParentGasLimit to ensure that we are in range. - // In hive we have tests that using long.MaxValue in the genesis block - // Even if we add maxGasLimitDifference we don't get header.GasLimit higher than long.MaxValue + ulong maxNextGasLimit = adjustedParentGasLimit + maxGasLimitDifference; + bool notToHighWithOverflow = ulong.MaxValue - maxGasLimitDifference < adjustedParentGasLimit; + // The edge case used in hive tests. If adjustedParentGasLimit + maxGasLimitDifference >= ulong.MaxValue, + // we can check for ulong.MaxValue - maxGasLimitDifference < adjustedParentGasLimit to ensure that we are in range. + // In hive we have tests that using ulong.MaxValue in the genesis block + // Even if we add maxGasLimitDifference we don't get header.GasLimit higher than ulong.MaxValue bool gasLimitNotTooHigh = notToHighWithOverflow || header.GasLimit < maxNextGasLimit; if (!gasLimitNotTooHigh) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs index 0024d7d3ed5d..3032c19099e3 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs @@ -98,7 +98,7 @@ public TxValidator(ulong chainId) public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) => IsWellFormed(transaction, releaseSpec, blockGasLimit: 0); - public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit) => + public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit) => _validators.TryGetByTxType(transaction.Type, out ITxValidator validator) ? validator.IsWellFormed(transaction, releaseSpec, blockGasLimit) : TxErrorMessages.InvalidTxType(releaseSpec.Name); @@ -109,7 +109,7 @@ public class CompositeTxValidator(params ITxValidator[] validators) : ITxValidat public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) => IsWellFormed(transaction, releaseSpec, blockGasLimit: 0); - public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit) + public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit) { foreach (ITxValidator validator in validators) { @@ -132,10 +132,10 @@ private IntrinsicGasTxValidator() { } public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) => IsWellFormed(transaction, releaseSpec, blockGasLimit: 0); - public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit) + public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit) { IntrinsicGas intrinsicGas = EthereumGasPolicy.CalculateIntrinsicGas(transaction, releaseSpec, blockGasLimit); - if (releaseSpec.IsEip8037Enabled && intrinsicGas.ExceedsCap(Eip7825Constants.DefaultTxGasLimitCap, out long regular, out long floor)) + if (releaseSpec.IsEip8037Enabled && intrinsicGas.ExceedsCap(Eip7825Constants.DefaultTxGasLimitCap, out ulong regular, out ulong floor)) { return TxErrorMessages.TxIntrinsicGasExceedsCap(regular, floor, Eip7825Constants.DefaultTxGasLimitCap); } @@ -401,7 +401,7 @@ private GasLimitCapTxValidator() { } public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) { - long gasLimitCap = releaseSpec.GetTxGasLimitCap(); + ulong gasLimitCap = releaseSpec.GetTxGasLimitCap(); return transaction.GasLimit > gasLimitCap ? TxErrorMessages.TxGasLimitCapExceeded(transaction.GasLimit, gasLimitCap) : ValidationResult.Success; } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs index 1f532ede8a14..6e924d56fd4e 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs @@ -76,12 +76,12 @@ private bool IsKin(BlockHeader header, BlockHeader uncle, int relationshipLevel) return false; } - if (relationshipLevel > header.Number) + if ((ulong)relationshipLevel > header.Number) { return IsKin(header, uncle, (int)header.Number); } - if (uncle.Number < header.Number - relationshipLevel) + if (uncle.Number < header.Number - (ulong)relationshipLevel) { return false; } diff --git a/src/Nethermind/Nethermind.Core.Test/AddressTests.cs b/src/Nethermind/Nethermind.Core.Test/AddressTests.cs index 429c98c9013a..c24a7a6aa591 100644 --- a/src/Nethermind/Nethermind.Core.Test/AddressTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/AddressTests.cs @@ -163,9 +163,9 @@ public void From_number_for_precompile(int number, bool isPrecompile) Assert.That(Byzantium.Instance.IsPrecompile(address), Is.EqualTo(isPrecompile)); } - [TestCase(0, "0x24cd2edba056b7c654a50e8201b619d4f624fdda")] - [TestCase(1, "0xdc98b4d0af603b4fb5ccdd840406a0210e5deff8")] - public void Of_contract(long nonce, string expectedAddress) + [TestCase(0UL, "0x24cd2edba056b7c654a50e8201b619d4f624fdda")] + [TestCase(1UL, "0xdc98b4d0af603b4fb5ccdd840406a0210e5deff8")] + public void Of_contract(ulong nonce, string expectedAddress) { Address address = ContractAddress.From(TestItem.AddressA, (UInt256)nonce); Assert.That(new Address(expectedAddress), Is.EqualTo(address)); diff --git a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs index 28f9efda9f24..fe7867c11cea 100644 --- a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs @@ -27,11 +27,11 @@ public void Hash_as_expected() Beneficiary = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1"), Difficulty = Bytes.FromHexString("0x020000").ToUInt256(), ExtraData = [], - GasLimit = (long)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), - GasUsed = (long)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), + GasLimit = (ulong)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), + GasUsed = (ulong)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), MixHash = new Hash256(Bytes.FromHexString("0x00be1f287e0911ea2f070b3650a1a0346535895b6c919d7e992a0c255a83fc8b")), Nonce = (ulong)Bytes.FromHexString("0xa0ddc06c6d7b9f48").ToUnsignedBigInteger(), - Number = (long)Bytes.FromHexString("0x01").ToUInt256(), + Number = (ulong)Bytes.FromHexString("0x01").ToUInt256(), ParentHash = new Hash256(Bytes.FromHexString("0x5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae")), ReceiptsRoot = new Hash256(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2")), StateRoot = new Hash256(Bytes.FromHexString("0x5c2e5a51a79da58791cdfe572bcfa3dfe9c860bf7fad7d9738a1aace56ef9332")), @@ -53,11 +53,11 @@ public void Hash_as_expected_2() Beneficiary = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1"), Difficulty = Bytes.FromHexString("0x020080").ToUInt256(), ExtraData = [], - GasLimit = (long)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), - GasUsed = (long)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), + GasLimit = (ulong)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), + GasUsed = (ulong)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), MixHash = new Hash256(Bytes.FromHexString("0x615bbf44eb133eab3cb24d5766ae9617d9e45ee00e7a5667db30672b47d22149")), Nonce = (ulong)Bytes.FromHexString("0x4c4f3d3e055cb264").ToUnsignedBigInteger(), - Number = (long)Bytes.FromHexString("0x03").ToUInt256(), + Number = (ulong)Bytes.FromHexString("0x03").ToUInt256(), ParentHash = new Hash256(Bytes.FromHexString("0xde1457da701ef916533750d46c124e9ae50b974410bd590fbcf4c935a4d19465")), ReceiptsRoot = new Hash256(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2")), StateRoot = new Hash256(Bytes.FromHexString("0xfb4084a7f8b57e370fefe24a3da3aaea6c4dd8b6f6251916c32440336035160b")), @@ -159,16 +159,16 @@ public void Eip_1559_CalculateBaseFee_should_returns_zero_when_eip1559_not_enabl Assert.That(baseFee, Is.EqualTo(UInt256.Zero)); } - [TestCase(100, 100, 88, 0)] - [TestCase(100, 300, 267, 10)] - [TestCase(500, 200, 185, 200)] - [TestCase(500, 0, 0, 200)] - [TestCase(21, 23, 23, 21)] - [TestCase(21, 23, 61, 300)] - [TestCase(500, 0, 10, 200, 10)] - [TestCase(100, 100, 88, 0, 80)] - [TestCase(100, 100, 110, 0, 110)] - public void Eip_1559_CalculateBaseFee(long gasTarget, long baseFee, long expectedBaseFee, long gasUsed, long? minimalBaseFee = null) + [TestCase(100, 100, 88, 0UL)] + [TestCase(100, 300, 267, 10UL)] + [TestCase(500, 200, 185, 200UL)] + [TestCase(500, 0, 0, 200UL)] + [TestCase(21, 23, 23, 21UL)] + [TestCase(21, 23, 61, 300UL)] + [TestCase(500, 0, 10, 200UL, 10)] + [TestCase(100, 100, 88, 0UL, 80)] + [TestCase(100, 100, 110, 0UL, 110)] + public void Eip_1559_CalculateBaseFee(long gasTarget, long baseFee, long expectedBaseFee, ulong gasUsed, long? minimalBaseFee = null) { IReleaseSpec releaseSpec = ReleaseSpecSubstitute.Create(); releaseSpec.BaseFeeCalculator.Returns(new DefaultBaseFeeCalculator()); @@ -180,7 +180,7 @@ public void Eip_1559_CalculateBaseFee(long gasTarget, long baseFee, long expecte BlockHeader blockHeader = Build.A.BlockHeader.TestObject; blockHeader.Number = 2001; - blockHeader.GasLimit = gasTarget * Eip1559Constants.DefaultElasticityMultiplier; + blockHeader.GasLimit = (ulong)(gasTarget * Eip1559Constants.DefaultElasticityMultiplier); blockHeader.BaseFeePerGas = (UInt256)baseFee; blockHeader.GasUsed = gasUsed; UInt256 actualBaseFee = BaseFeeCalculator.Calculate(blockHeader, releaseSpec); @@ -210,9 +210,9 @@ public void Eip_1559_CalculateBaseFee_shared_test_cases((BaseFeeTestCases Info, BlockHeader blockHeader = Build.A.BlockHeader.TestObject; blockHeader.Number = 2001; - blockHeader.GasLimit = testCase.Info.ParentTargetGasUsed * Eip1559Constants.DefaultElasticityMultiplier; + blockHeader.GasLimit = (ulong)(testCase.Info.ParentTargetGasUsed * Eip1559Constants.DefaultElasticityMultiplier); blockHeader.BaseFeePerGas = (UInt256)testCase.Info.ParentBaseFee; - blockHeader.GasUsed = testCase.Info.ParentGasUsed; + blockHeader.GasUsed = (ulong)testCase.Info.ParentGasUsed; UInt256 actualBaseFee = BaseFeeCalculator.Calculate(blockHeader, releaseSpec); Assert.That(actualBaseFee, Is.EqualTo((UInt256)testCase.Info.ExpectedBaseFee), testCase.Description); } diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs index ade374ad4c9d..8382033277ec 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs @@ -27,7 +27,7 @@ public static async Task Create(Action? c public async Task BuildSomeBlocks(int numOfBlocks) { - UInt256 nonce = WorldStateManager.GlobalStateReader.GetNonce(BlockTree.Head!.Header, TestItem.PrivateKeyA.Address); + ulong nonce = (ulong)WorldStateManager.GlobalStateReader.GetNonce(BlockTree.Head!.Header, TestItem.PrivateKeyA.Address); for (int i = 0; i < numOfBlocks; i++) { IReleaseSpec spec = SpecProvider.GetSpec(BlockTree.Head!.Header); diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index df22fe6d56c3..d09b4d2d3424 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -488,7 +488,7 @@ public async Task AddFundsAfterLondon(params (Address address, UInt256 ether)[] private Transaction GetFundsTransaction(Address address, UInt256 ether, uint index = 0) { - UInt256 nonce = StateReader.GetNonce(BlockTree.Head!.Header, TestItem.AddressA); + ulong nonce = StateReader.GetNonce(BlockTree.Head!.Header, TestItem.AddressA); Transaction tx = Builders.Build.A.Transaction .SignedAndResolved(TestItem.PrivateKeyA) .To(address) @@ -500,7 +500,7 @@ private Transaction GetFundsTransaction(Address address, UInt256 ether, uint ind private Transaction GetFunds1559Transaction(Address address, UInt256 ether, uint index = 0) { - UInt256 nonce = StateReader.GetNonce(BlockTree.Head!.Header, TestItem.AddressA); + ulong nonce = StateReader.GetNonce(BlockTree.Head!.Header, TestItem.AddressA); Transaction tx = Builders.Build.A.Transaction .SignedAndResolved(TestItem.PrivateKeyA) .To(address) diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/AccountBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/AccountBuilder.cs index bf2f0b34a86f..09f528b64a75 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/AccountBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/AccountBuilder.cs @@ -12,11 +12,11 @@ public class AccountBuilder : BuilderBase public AccountBuilder WithBalance(UInt256 balance) { - TestObjectInternal = TestObjectInternal.WithChangedBalance(balance); + TestObjectInternal = TestObjectInternal.WithChangedBalance((ulong)balance); return this; } - public AccountBuilder WithNonce(UInt256 nonce) + public AccountBuilder WithNonce(ulong nonce) { TestObjectInternal = TestObjectInternal.WithChangedNonce(nonce); return this; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs index 39511e451fe3..b558825a6df5 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs @@ -31,7 +31,7 @@ public BlockBuilder WithHeader(BlockHeader header) return this; } - public BlockBuilder WithNumber(long number) + public BlockBuilder WithNumber(ulong number) { TestObjectInternal.Header.Number = number; return this; @@ -49,7 +49,7 @@ public BlockBuilder WithExtraData(byte[] extraData) return this; } - public BlockBuilder WithGasLimit(long gasLimit) + public BlockBuilder WithGasLimit(ulong gasLimit) { TestObjectInternal.Header.GasLimit = gasLimit; return this; @@ -261,7 +261,7 @@ public BlockBuilder WithEmptyRequestsHash() return this; } - public BlockBuilder WithGasUsed(long gasUsed) + public BlockBuilder WithGasUsed(ulong gasUsed) { TestObjectInternal.Header.GasUsed = gasUsed; return this; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs index 616d393beed6..7fd4ec1a691f 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs @@ -122,7 +122,7 @@ public BlockHeaderBuilder WithDifficulty(UInt256 difficulty) return this; } - public BlockHeaderBuilder WithNumber(long blockNumber) + public BlockHeaderBuilder WithNumber(ulong blockNumber) { TestObjectInternal.Number = blockNumber; return this; @@ -134,13 +134,13 @@ public BlockHeaderBuilder WithTotalDifficulty(long totalDifficulty) return this; } - public BlockHeaderBuilder WithGasLimit(long gasLimit) + public BlockHeaderBuilder WithGasLimit(ulong gasLimit) { TestObjectInternal.GasLimit = gasLimit; return this; } - public BlockHeaderBuilder WithGasUsed(long gasUsed) + public BlockHeaderBuilder WithGasUsed(ulong gasUsed) { TestObjectInternal.GasUsed = gasUsed; return this; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs index 113572ba18e6..5c245fbf82bf 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs @@ -260,7 +260,7 @@ public BlockTreeBuilder OfChainLengthWithSharedSplits(out Block headBlock, int c bool fromGenesis = splitFrom == 0; Block current = fromGenesis ? genesisBlock - : BlockTree.FindBlock(splitFrom, BlockTreeLookupOptions.RequireCanonical) ?? throw new ArgumentException("Cannot find split block"); + : BlockTree.FindBlock((ulong)splitFrom, BlockTreeLookupOptions.RequireCanonical) ?? throw new ArgumentException("Cannot find split block"); bool skipGenesis = BlockTree.Genesis is not null; for (int i = 0; i < chainLength; i++) { @@ -294,7 +294,7 @@ private Block CreateBlock(int splitVariant, int splitFrom, int blockIndex, Block { Block currentBlock; BlockBuilder currentBlockBuilder = Build.A.Block - .WithNumber(blockIndex + 1) + .WithNumber((ulong)(blockIndex + 1)) .WithParent(parent) .WithWithdrawals(withWithdrawals ? [TestItem.WithdrawalA_1Eth] : null) .WithBaseFeePerGas(withWithdrawals ? UInt256.One : UInt256.Zero) @@ -312,7 +312,7 @@ private Block CreateBlock(int splitVariant, int splitFrom, int blockIndex, Block else { currentBlockBuilder.WithDifficulty(BlockHeaderBuilder.DefaultDifficulty - - (splitFrom > parent.Number ? 0 : (ulong)splitVariant)); + ((ulong)splitFrom > parent.Number ? 0 : (ulong)splitVariant)); } if (_receiptStorage is not null && blockIndex % 3 == 0) @@ -323,13 +323,13 @@ private Block CreateBlock(int splitVariant, int splitFrom, int blockIndex, Block .WithValue(1) .WithData(Rlp.Encode(blockIndex).Bytes) .WithGasLimit(GasCostOf.Transaction * 2) - .Signed(_ecdsa!, TestItem.PrivateKeyA, _specProvider.GetSpec(blockIndex + 1, null).IsEip155Enabled) + .Signed(_ecdsa!, TestItem.PrivateKeyA, _specProvider.GetSpec((ulong)(blockIndex + 1), null).IsEip155Enabled) .TestObject, Build.A.Transaction .WithValue(2) .WithData(Rlp.Encode(blockIndex + 1).Bytes) .WithGasLimit(GasCostOf.Transaction * 2) - .Signed(_ecdsa!, TestItem.PrivateKeyA, _specProvider.GetSpec(blockIndex + 1, null).IsEip155Enabled) + .Signed(_ecdsa!, TestItem.PrivateKeyA, _specProvider.GetSpec((ulong)(blockIndex + 1), null).IsEip155Enabled) .TestObject ]; @@ -388,12 +388,12 @@ public BlockTreeBuilder WithOnlySomeBlocksProcessed(int chainLength, int process for (int i = 0; i < chainLength; i++) { BlockTree.SuggestBlock(current); - if (current.Number < processedChainLength) + if (current.Number < (ulong)processedChainLength) { BlockTree.UpdateMainChain(current); } - current = Build.A.Block.WithNumber(i + 1).WithParent(current).WithDifficulty(BlockHeaderBuilder.DefaultDifficulty).TestObject; + current = Build.A.Block.WithNumber((ulong)(i + 1)).WithParent(current).WithDifficulty(BlockHeaderBuilder.DefaultDifficulty).TestObject; } return this; @@ -420,7 +420,7 @@ public BlockTreeBuilder WithBlocks(params Block[] blocks) foreach (Block block in blocks) { - if (block.Number != counter++) + if (block.Number != (ulong)counter++) { throw new ArgumentException("Block numbers are not consecutively increasing."); } @@ -432,11 +432,11 @@ public BlockTreeBuilder WithBlocks(params Block[] blocks) return this; } - public static void ExtendTree(IBlockTree blockTree, long newChainLength) + public static void ExtendTree(IBlockTree blockTree, ulong newChainLength) { Block previous = blockTree.RetrieveHeadBlock()!; - long initialLength = previous.Number + 1; - for (long i = initialLength; i < newChainLength; i++) + ulong initialLength = previous.Number + 1; + for (ulong i = initialLength; i < newChainLength; i++) { previous = Build.A.Block.WithNumber(i).WithParent(previous).TestObject; blockTree.SuggestBlock(previous); diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeExtensions.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeExtensions.cs index 7f60dd22a149..377393b2b7e4 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeExtensions.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeExtensions.cs @@ -15,14 +15,14 @@ public static class BlockTreeExtensions public static void AddBranch(this IBlockTree blockTree, int branchLength, int splitBlockNumber) { int splitVariant = 0; - BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0, BlockTreeLookupOptions.RequireCanonical)!).OfChainLength(branchLength, splitVariant).TestObject; + BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0UL, BlockTreeLookupOptions.RequireCanonical)!).OfChainLength(branchLength, splitVariant).TestObject; Block? parent = null; for (int i = splitBlockNumber + 1; i < branchLength; i++) { - Block block = alternative.FindBlock(i, BlockTreeLookupOptions.RequireCanonical)!; + Block block = alternative.FindBlock((ulong)i, BlockTreeLookupOptions.RequireCanonical)!; if (i == splitBlockNumber + 1) { - Block? mainBlock = blockTree.FindBlock(i - 1, BlockTreeLookupOptions.RequireCanonical); + Block? mainBlock = blockTree.FindBlock((ulong)(i - 1), BlockTreeLookupOptions.RequireCanonical); if (mainBlock is not null) parent = mainBlock; } @@ -40,16 +40,16 @@ public static void AddBranch(this IBlockTree blockTree, int branchLength, int sp public static void AddBranch(this IBlockTree blockTree, int branchLength, int splitBlockNumber, int splitVariant) { - BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0, BlockTreeLookupOptions.RequireCanonical)!).OfChainLength(branchLength, splitVariant).TestObject; + BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0UL, BlockTreeLookupOptions.RequireCanonical)!).OfChainLength(branchLength, splitVariant).TestObject; List blocks = []; for (int i = splitBlockNumber + 1; i < branchLength; i++) { - Block block = alternative.FindBlock(i, BlockTreeLookupOptions.RequireCanonical)!; + Block block = alternative.FindBlock((ulong)i, BlockTreeLookupOptions.RequireCanonical)!; blockTree.SuggestBlock(block); blocks.Add(block); } - if (branchLength > blockTree.Head!.Number) + if ((ulong)branchLength > blockTree.Head!.Number) { blockTree.UpdateMainChain(blocks, true); } diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/ReceiptBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/ReceiptBuilder.cs index 5877a0e518fc..9998b49305ff 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/ReceiptBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/ReceiptBuilder.cs @@ -53,7 +53,7 @@ public ReceiptBuilder WithTransactionHash(Hash256? hash) return this; } - public ReceiptBuilder WithBlockNumber(long number) + public ReceiptBuilder WithBlockNumber(ulong number) { TestObject.BlockNumber = number; return this; @@ -65,13 +65,13 @@ public ReceiptBuilder WithBlockHash(Hash256? hash) return this; } - public ReceiptBuilder WithGasUsedTotal(long gasTotal) + public ReceiptBuilder WithGasUsedTotal(ulong gasTotal) { TestObjectInternal.GasUsedTotal = gasTotal; return this; } - public ReceiptBuilder WithGasUsed(long gasUsed) + public ReceiptBuilder WithGasUsed(ulong gasUsed) { TestObjectInternal.GasUsed = gasUsed; return this; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs index e4db2cc0a140..5d92f08d60b1 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs @@ -156,8 +156,8 @@ public static Account GenerateRandomAccount(Random? random = null) random ??= Random; Account account = new( - (UInt256)random.Next(1000), - (UInt256)random.Next(1000), + (ulong)random.Next(1000), + (ulong)random.Next(1000), Keccak.EmptyTreeHash, Keccak.OfAnEmptyString); @@ -176,8 +176,8 @@ public static byte[] GenerateRandomAccountRlp(AccountDecoder? accountDecoder = n public static Account GenerateIndexedAccount(int index) { Account account = new( - (UInt256)index, - (UInt256)index); + (ulong)index, + (ulong)index); return account; } diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs index 6bfa6e4cffd8..9a520701ea2d 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs @@ -18,7 +18,7 @@ namespace Nethermind.Core.Test.Builders public TransactionBuilder() => TestObjectInternal = new T { GasPrice = 1, - GasLimit = Transaction.BaseTxGasCost, + GasLimit = Transaction.BaseTxGasCost, // BaseTxGasCost must also be ulong after broader migration To = Address.Zero, Nonce = 0, Value = 1, @@ -26,7 +26,8 @@ namespace Nethermind.Core.Test.Builders Timestamp = 0, }; - public TransactionBuilder WithNonce(UInt256 nonce) + // Nonce is ulong — nonces are non-negative and fit well within ulong range + public TransactionBuilder WithNonce(ulong nonce) { TestObjectInternal.Nonce = nonce; return this; @@ -77,7 +78,8 @@ public TransactionBuilder WithGasPrice(UInt256 gasPrice) return this; } - public TransactionBuilder WithGasLimit(long gasLimit) + // GasLimit is ulong — gas limits are never negative + public TransactionBuilder WithGasLimit(ulong gasLimit) { TestObjectInternal.GasLimit = gasLimit; return this; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs index 187bc9efb20e..f97956bcbc96 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs @@ -40,8 +40,8 @@ public TrieBuilder WithAccountsByIndex(int start, int count) private Account GenerateIndexedAccount(int index) { Account account = new( - (UInt256)index, - (UInt256)index, + (ulong)index, + (ulong)index, Keccak.EmptyTreeHash, Keccak.OfAnEmptyString); diff --git a/src/Nethermind/Nethermind.Core.Test/Eip2935TestConstants.cs b/src/Nethermind/Nethermind.Core.Test/Eip2935TestConstants.cs index 189ec1c91360..ada8b4f7a40c 100644 --- a/src/Nethermind/Nethermind.Core.Test/Eip2935TestConstants.cs +++ b/src/Nethermind/Nethermind.Core.Test/Eip2935TestConstants.cs @@ -3,7 +3,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; -using Nethermind.Int256; namespace Nethermind.Core.Test; @@ -14,5 +13,5 @@ public static class Eip2935TestConstants public static readonly byte[] InitCode = Bytes.FromHexString("0x60538060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500"); public static readonly ValueHash256 CodeHash = ValueKeccak.Compute(Code); - public static readonly UInt256 Nonce = 1; + public static readonly ulong Nonce = 1; } diff --git a/src/Nethermind/Nethermind.Core.Test/Eip4788TestConstants.cs b/src/Nethermind/Nethermind.Core.Test/Eip4788TestConstants.cs index a581508379e4..90a8e64cdcb0 100644 --- a/src/Nethermind/Nethermind.Core.Test/Eip4788TestConstants.cs +++ b/src/Nethermind/Nethermind.Core.Test/Eip4788TestConstants.cs @@ -3,7 +3,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; -using Nethermind.Int256; namespace Nethermind.Core.Test; @@ -13,5 +12,5 @@ public static class Eip4788TestConstants public static readonly ValueHash256 CodeHash = ValueKeccak.Compute(Code); - public static readonly UInt256 Nonce = 1; + public static readonly ulong Nonce = 1; } diff --git a/src/Nethermind/Nethermind.Core.Test/Eip7002TestConstants.cs b/src/Nethermind/Nethermind.Core.Test/Eip7002TestConstants.cs index 99357058d859..37ce5f076bcf 100644 --- a/src/Nethermind/Nethermind.Core.Test/Eip7002TestConstants.cs +++ b/src/Nethermind/Nethermind.Core.Test/Eip7002TestConstants.cs @@ -3,7 +3,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; -using Nethermind.Int256; namespace Nethermind.Core.Test; @@ -13,5 +12,5 @@ public static class Eip7002TestConstants public static readonly ValueHash256 CodeHash = ValueKeccak.Compute(Code); - public static readonly UInt256 Nonce = 1; + public static readonly ulong Nonce = 1; } diff --git a/src/Nethermind/Nethermind.Core.Test/Eip7251TestConstants.cs b/src/Nethermind/Nethermind.Core.Test/Eip7251TestConstants.cs index 30dd241e13f4..65ac4682016a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Eip7251TestConstants.cs +++ b/src/Nethermind/Nethermind.Core.Test/Eip7251TestConstants.cs @@ -3,7 +3,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; -using Nethermind.Int256; namespace Nethermind.Core.Test; @@ -13,5 +12,5 @@ public static class Eip7251TestConstants public static readonly ValueHash256 CodeHash = ValueKeccak.Compute(Code); - public static readonly UInt256 Nonce = 1; + public static readonly ulong Nonce = 1; } diff --git a/src/Nethermind/Nethermind.Core.Test/Encoding/BlockDecoderTests.cs b/src/Nethermind/Nethermind.Core.Test/Encoding/BlockDecoderTests.cs index c691bd2a2598..3f9e9da022f3 100644 --- a/src/Nethermind/Nethermind.Core.Test/Encoding/BlockDecoderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Encoding/BlockDecoderTests.cs @@ -23,11 +23,11 @@ public class BlockDecoderTests private static Block[] BuildScenarios() { Transaction[] transactions = new Transaction[100]; - for (int i = 0; i < transactions.Length; i++) + for (uint i = 0; i < transactions.Length; i++) { transactions[i] = Build.A.Transaction .WithData(new byte[] { (byte)i }) - .WithNonce((UInt256)i) + .WithNonce(i) .WithValue((UInt256)i) .Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA, true) .TestObject; diff --git a/src/Nethermind/Nethermind.Core.Test/Encoding/HeaderDecoderTests.cs b/src/Nethermind/Nethermind.Core.Test/Encoding/HeaderDecoderTests.cs index 9744a3d77728..dc135e836ba2 100644 --- a/src/Nethermind/Nethermind.Core.Test/Encoding/HeaderDecoderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Encoding/HeaderDecoderTests.cs @@ -102,38 +102,38 @@ public void If_withdrawals_are_null_should_not_encode() Assert.That(Convert.ToHexString(rlp.Bytes).ToLower(), Is.EqualTo("f901f7a0ff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008080833d090080830f424083010203a02ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e288000000000000000001")); } - [TestCase(-1)] - [TestCase(long.MinValue)] - public void Can_encode_decode_with_negative_long_fields(long negativeLong) + [TestCase(ulong.MaxValue)] + [TestCase(ulong.MaxValue / 2)] + public void Can_encode_decode_with_large_ulong_fields(ulong largeValue) { BlockHeader header = Build.A.BlockHeader. - WithNumber(negativeLong). - WithGasUsed(negativeLong). - WithGasLimit(negativeLong).TestObject; + WithNumber(largeValue). + WithGasUsed(largeValue). + WithGasLimit(largeValue).TestObject; Rlp rlp = Rlp.Encode(header); BlockHeader blockHeader = Rlp.Decode(rlp); - Assert.That(blockHeader.GasUsed, Is.EqualTo(negativeLong)); - Assert.That(blockHeader.Number, Is.EqualTo(negativeLong)); - Assert.That(blockHeader.GasLimit, Is.EqualTo(negativeLong)); + Assert.That(blockHeader.GasUsed, Is.EqualTo(largeValue)); + Assert.That(blockHeader.Number, Is.EqualTo(largeValue)); + Assert.That(blockHeader.GasLimit, Is.EqualTo(largeValue)); } - [TestCase(-1)] - [TestCase(long.MinValue)] - public void Can_encode_decode_with_negative_long_when_using_span(long negativeLong) + [TestCase(ulong.MaxValue)] + [TestCase(ulong.MaxValue / 2)] + public void Can_encode_decode_with_large_ulong_when_using_span(ulong largeValue) { BlockHeader header = Build.A.BlockHeader. - WithNumber(negativeLong). - WithGasUsed(negativeLong). - WithGasLimit(negativeLong).TestObject; + WithNumber(largeValue). + WithGasUsed(largeValue). + WithGasLimit(largeValue).TestObject; Rlp rlp = Rlp.Encode(header); BlockHeader blockHeader = Rlp.Decode(rlp.Bytes.AsSpan()); - Assert.That(blockHeader.GasUsed, Is.EqualTo(negativeLong)); - Assert.That(blockHeader.Number, Is.EqualTo(negativeLong)); - Assert.That(blockHeader.GasLimit, Is.EqualTo(negativeLong)); + Assert.That(blockHeader.GasUsed, Is.EqualTo(largeValue)); + Assert.That(blockHeader.Number, Is.EqualTo(largeValue)); + Assert.That(blockHeader.GasLimit, Is.EqualTo(largeValue)); } [TestCaseSource(nameof(CancunFieldsSource))] diff --git a/src/Nethermind/Nethermind.Core.Test/FixedForkActivationChainHeadSpecProvider.cs b/src/Nethermind/Nethermind.Core.Test/FixedForkActivationChainHeadSpecProvider.cs index 707631926271..2dc62ba25242 100644 --- a/src/Nethermind/Nethermind.Core.Test/FixedForkActivationChainHeadSpecProvider.cs +++ b/src/Nethermind/Nethermind.Core.Test/FixedForkActivationChainHeadSpecProvider.cs @@ -8,11 +8,11 @@ namespace Nethermind.Core.Test { public class FixedForkActivationChainHeadSpecProvider( ISpecProvider specProvider, - long fixedBlock = 10_000_000, + ulong fixedBlock = 10_000_000, ulong? timestamp = null) : IChainHeadSpecProvider { - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) => specProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => specProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public ForkActivation? MergeBlockNumber => specProvider.MergeBlockNumber; public ulong TimestampFork => specProvider.TimestampFork; @@ -22,7 +22,7 @@ public class FixedForkActivationChainHeadSpecProvider( public IReleaseSpec GetSpec(ForkActivation forkActivation) => specProvider.GetSpec(forkActivation); - public long? DaoBlockNumber => specProvider.DaoBlockNumber; + public ulong? DaoBlockNumber => specProvider.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => specProvider.BeaconChainGenesisTimestamp; diff --git a/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs b/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs index 1b02783d5fe8..1fbfc5fbfd40 100644 --- a/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs @@ -13,8 +13,8 @@ public class Int64Tests public void ToLongFromBytes() { byte[] bytes = Bytes.FromHexString("7fffffffffffffff"); - long number = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); - Assert.That(number, Is.EqualTo(long.MaxValue)); + ulong number = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + Assert.That(number, Is.EqualTo((ulong)long.MaxValue)); } } } diff --git a/src/Nethermind/Nethermind.Core.Test/Modules/FlatDbManagerTestCompat.cs b/src/Nethermind/Nethermind.Core.Test/Modules/FlatDbManagerTestCompat.cs index 1352690df83d..6aa472789db5 100644 --- a/src/Nethermind/Nethermind.Core.Test/Modules/FlatDbManagerTestCompat.cs +++ b/src/Nethermind/Nethermind.Core.Test/Modules/FlatDbManagerTestCompat.cs @@ -28,7 +28,7 @@ public bool HasStateForBlock(in StateId stateId) private StateId NormalizeState(StateId stateId) { - if (stateId.StateRoot == Keccak.EmptyTreeHash && stateId.BlockNumber != -1 && + if (stateId.StateRoot == Keccak.EmptyTreeHash && stateId.BlockNumber != StateId.PreGenesis.BlockNumber && !flatDbManager.HasStateForBlock(stateId)) return StateId.PreGenesis; return stateId; diff --git a/src/Nethermind/Nethermind.Core.Test/SyncPeerMock.cs b/src/Nethermind/Nethermind.Core.Test/SyncPeerMock.cs index 5434cbb33b05..56876167a6c9 100644 --- a/src/Nethermind/Nethermind.Core.Test/SyncPeerMock.cs +++ b/src/Nethermind/Nethermind.Core.Test/SyncPeerMock.cs @@ -64,7 +64,7 @@ private void RunQueue() public string ProtocolCode { get; } = null!; public string ClientId => Node.ClientId; public Hash256 HeadHash { get; set; } - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public UInt256? TotalDifficulty { get; set; } public bool IsInitialized { get; set; } public bool IsPriority { get; set; } @@ -88,7 +88,7 @@ public Task GetBlockBodies(IReadOnlyList blockHashes, public Task?> GetBlockHeaders(Hash256 blockHash, int maxBlocks, int skip, CancellationToken token) { ArrayPoolList result = new(maxBlocks, maxBlocks); - long? firstNumber = _remoteTree.FindHeader(blockHash, BlockTreeLookupOptions.RequireCanonical)?.Number; + ulong? firstNumber = _remoteTree.FindHeader(blockHash, BlockTreeLookupOptions.RequireCanonical)?.Number; if (!firstNumber.HasValue) { return Task.FromResult?>(result); @@ -96,16 +96,16 @@ public Task GetBlockBodies(IReadOnlyList blockHashes, for (int i = 0; i < maxBlocks; i++) { - result[i] = _remoteTree.FindHeader(firstNumber.Value + i + skip, BlockTreeLookupOptions.RequireCanonical)!; + result[i] = _remoteTree.FindHeader(firstNumber.Value + (ulong)i + (ulong)skip, BlockTreeLookupOptions.RequireCanonical)!; } return Task.FromResult?>(result); } - public Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) + public Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) { ArrayPoolList result = new(maxBlocks, maxBlocks); - long? firstNumber = _remoteTree.FindHeader(number, BlockTreeLookupOptions.RequireCanonical)?.Number; + ulong? firstNumber = _remoteTree.FindHeader(number, BlockTreeLookupOptions.RequireCanonical)?.Number; if (!firstNumber.HasValue) { return Task.FromResult>(result)!; @@ -113,7 +113,7 @@ public Task GetBlockBodies(IReadOnlyList blockHashes, for (int i = 0; i < maxBlocks; i++) { - long blockNumber = firstNumber.Value + i + skip; + ulong blockNumber = firstNumber.Value + (ulong)i + (ulong)skip; if (blockNumber > (_remoteTree.Head?.Number ?? 0)) { result[i] = null!; @@ -145,7 +145,7 @@ public void NotifyOfNewBlock(Block block, SendBlockMode mode) private void SendNewBlock(Block block) => _sendQueue.Add(() => _remoteSyncServer?.AddNewBlock(block, this)); - private void HintNewBlock(Hash256 blockHash, long number) => _sendQueue.Add(() => _remoteSyncServer?.HintBlock(blockHash, number, this)); + private void HintNewBlock(Hash256 blockHash, ulong number) => _sendQueue.Add(() => _remoteSyncServer?.HintBlock(blockHash, number, this)); public PublicKey Id => Node.Id; diff --git a/src/Nethermind/Nethermind.Core.Test/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Core.Test/TestBlockhashProvider.cs index ae119a350544..259bc0a0bb6b 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestBlockhashProvider.cs @@ -11,10 +11,10 @@ namespace Nethermind.Core.Test { public class TestBlockhashProvider(ISpecProvider specProvider) : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, long number) + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number) => GetBlockhash(currentBlock, number, specProvider.GetSpec(currentBlock)); - public Hash256 GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) => Keccak.Compute(spec.IsBlockHashInStateAvailable + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) => Keccak.Compute(spec.IsBlockHashInStateAvailable ? (Eip2935Constants.RingBufferSize + number).ToString() : number.ToString()); diff --git a/src/Nethermind/Nethermind.Core.Test/TestFinalizedStateProvider.cs b/src/Nethermind/Nethermind.Core.Test/TestFinalizedStateProvider.cs index 95c449ff1c8b..f1e78ea0a8ba 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestFinalizedStateProvider.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestFinalizedStateProvider.cs @@ -13,12 +13,12 @@ namespace Nethermind.Core.Test; /// TrieStore must be set later. ///
/// -public class TestFinalizedStateProvider(long depth) : IFinalizedStateProvider +public class TestFinalizedStateProvider(ulong depth) : IFinalizedStateProvider { public TrieStore TrieStore { get; set; } = null!; private BlockHeader? _manualFinalizedPoint = null; - public long FinalizedBlockNumber + public ulong FinalizedBlockNumber { get { @@ -26,11 +26,11 @@ public long FinalizedBlockNumber { return _manualFinalizedPoint.Number; } - return TrieStore.LatestCommittedBlockNumber - depth; + return TrieStore.LatestCommittedBlockNumber >= depth ? TrieStore.LatestCommittedBlockNumber - depth : 0UL; } } - public Hash256? GetFinalizedStateRootAt(long blockNumber) + public Hash256? GetFinalizedStateRootAt(ulong blockNumber) { if (_manualFinalizedPoint is not null && _manualFinalizedPoint.Number == blockNumber) { diff --git a/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs b/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs index 74f5449011f4..bc16f9eae3d6 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs @@ -32,7 +32,7 @@ public class TestReadOnlyStateProvider : IReadOnlyStateProvider public bool IsDeadAccount(Address address) => !TryGetAccount(address, out AccountStruct account) || account.IsEmpty; - public void CreateAccount(Address address, UInt256 wei, UInt256 nonce = default) => _accounts[address] = new AccountStruct(nonce, wei); + public void CreateAccount(Address address, UInt256 wei, ulong nonce = default) => _accounts[address] = new AccountStruct(nonce, (ulong)wei); public void InsertCode(Address address, Memory code, IReleaseSpec spec) => InsertCode(code.ToArray(), address); @@ -45,7 +45,7 @@ public void InsertCode(byte[] code, Address address) } ValueHash256 codeHash = Keccak.Compute(code); - account = new AccountStruct(account.Nonce, account.Balance, account.StorageRoot, codeHash); + account = new AccountStruct(account.Nonce, (ulong)account.Balance, account.StorageRoot, codeHash); _codes[codeHash] = code; _accounts[address] = account; } @@ -57,7 +57,7 @@ public void IncrementNonce(Address address) account = new AccountStruct(); } - account = new AccountStruct(account.Nonce + 1, account.Balance, account.StorageRoot, account.CodeHash); + account = new AccountStruct(account.Nonce + 1, (ulong)account.Balance, account.StorageRoot, account.CodeHash); _accounts[address] = account; } } diff --git a/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs b/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs index a56591896ec4..6dca105406c2 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs @@ -23,7 +23,7 @@ public static class TestTrieStoreFactory public static TrieStore Build(IKeyValueStoreWithBatching keyValueStore, IPruningStrategy pruningStrategy, IPersistenceStrategy persistenceStrategy, ILogManager logManager) { - TestFinalizedStateProvider finalizedStateProvider = new(_testPruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)_testPruningConfig.PruningBoundary); TrieStore trieStore = new(new NodeStorage(keyValueStore), pruningStrategy, persistenceStrategy, finalizedStateProvider, _testPruningConfig, logManager); finalizedStateProvider.TrieStore = trieStore; return trieStore; diff --git a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs index fc6509269481..8882f6dc4532 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs @@ -19,7 +19,7 @@ public static class TestWorldStateFactory public static IWorldState CreateForTest(IDbProvider? dbProvider = null, ILogManager? logManager = null) { PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); dbProvider ??= TestMemDbProvider.Init(); logManager ??= LimboLogs.Instance; TrieStore trieStore = new( @@ -39,7 +39,7 @@ public static (IWorldState, IStateReader) CreateForTestWithStateReader(IDbProvid logManager ??= LimboLogs.Instance; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(dbProvider.StateDb), No.Pruning, @@ -78,7 +78,7 @@ private static IContainer BuildFlatContainer() public static WorldStateManager CreateWorldStateManagerForTest(IDbProvider dbProvider, ILogManager logManager) { PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(dbProvider.StateDb), No.Pruning, diff --git a/src/Nethermind/Nethermind.Core.Test/TransactionExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/TransactionExtensionsTests.cs index 7c28ffcf52b7..64037099bb92 100644 --- a/src/Nethermind/Nethermind.Core.Test/TransactionExtensionsTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/TransactionExtensionsTests.cs @@ -80,8 +80,8 @@ public class TransactionPotentialCostsAndEffectiveGasPrice public UInt256 FeeCap { get; set; } public UInt256 GasPrice { get; set; } public TxType Type { get; set; } - public long GasLimit { get; set; } - public UInt256 Value { get; set; } + public ulong GasLimit { get; set; } + public ulong Value { get; set; } public bool IsEip1559Enabled { get; set; } public UInt256 ExpectedPotentialCostResult { get; set; } diff --git a/src/Nethermind/Nethermind.Core/Account.cs b/src/Nethermind/Nethermind.Core/Account.cs index 2ef1f1c178da..4c16bc80915a 100644 --- a/src/Nethermind/Nethermind.Core/Account.cs +++ b/src/Nethermind/Nethermind.Core/Account.cs @@ -16,7 +16,7 @@ public class Account : IEquatable private readonly Hash256? _codeHash; private readonly Hash256? _storageRoot; - public readonly UInt256 Nonce; + public readonly ulong Nonce; public readonly UInt256 Balance; public Account(in UInt256 balance) @@ -27,7 +27,7 @@ public Account(in UInt256 balance) Balance = balance; } - public Account(in UInt256 nonce, in UInt256 balance) + public Account(in ulong nonce, in UInt256 balance) { _codeHash = null; _storageRoot = null; @@ -43,7 +43,7 @@ private Account() Balance = default; } - public Account(in UInt256 nonce, in UInt256 balance, Hash256 storageRoot, Hash256 codeHash) + public Account(in ulong nonce, in UInt256 balance, Hash256 storageRoot, Hash256 codeHash) { _codeHash = codeHash == Keccak.OfAnEmptyString ? null : codeHash; _storageRoot = storageRoot == Keccak.EmptyTreeHash ? null : storageRoot; @@ -67,7 +67,7 @@ private Account(Hash256? codeHash, Account account) Balance = account.Balance; } - private Account(Account account, in UInt256 nonce, in UInt256 balance) + private Account(Account account, in ulong nonce, in UInt256 balance) { _codeHash = account._codeHash; _storageRoot = account._storageRoot; @@ -82,7 +82,7 @@ private Account(Account account, in UInt256 nonce, in UInt256 balance) public Hash256 StorageRoot => _storageRoot ?? Keccak.EmptyTreeHash; public Hash256 CodeHash => _codeHash ?? Keccak.OfAnEmptyString; public bool IsTotallyEmpty => _storageRoot is null && IsEmpty; - public bool IsEmpty => _codeHash is null && Balance.IsZero && Nonce.IsZero; + public bool IsEmpty => _codeHash is null && Balance.IsZero && Nonce == 0; public bool IsContract => _codeHash is not null; public bool Equals(Account? other) { @@ -99,7 +99,7 @@ public bool Equals(Account? other) public override int GetHashCode() => (int)BitOperations.Crc32C((uint)CodeHash.GetHashCode(), (ulong)Nonce.GetHashCode() << 8 | (uint)Balance.GetHashCode()) ^ StorageRoot.GetHashCode(); public static bool operator !=(Account? left, Account? right) => !(left == right); public Account WithChangedBalance(in UInt256 newBalance) => new(this, Nonce, newBalance); - public Account WithChangedNonce(in UInt256 newNonce) => new(this, newNonce, Balance); + public Account WithChangedNonce(in ulong newNonce) => new(this, newNonce, Balance); public Account WithChangedStorageRoot(Hash256 newStorageRoot) => new(this, newStorageRoot); public Account WithChangedCodeHash(Hash256 newCodeHash) => new(newCodeHash, this); public AccountStruct ToStruct() => new(Nonce, Balance, StorageRoot, CodeHash); @@ -112,11 +112,11 @@ public bool Equals(Account? other) public static ref readonly AccountStruct TotallyEmpty => ref _totallyEmpty; private readonly UInt256 _balance; - private readonly UInt256 _nonce = default; + private readonly ulong _nonce = default; public readonly ValueHash256 CodeHash = Keccak.OfAnEmptyString.ValueHash256; private readonly ValueHash256 _storageRoot = Keccak.EmptyTreeHash.ValueHash256; - public AccountStruct(in UInt256 nonce, in UInt256 balance, in ValueHash256 storageRoot, in ValueHash256 codeHash) + public AccountStruct(in ulong nonce, in UInt256 balance, in ValueHash256 storageRoot, in ValueHash256 codeHash) { _balance = balance; _nonce = nonce; @@ -124,7 +124,7 @@ public AccountStruct(in UInt256 nonce, in UInt256 balance, in ValueHash256 stora _storageRoot = storageRoot; } - public AccountStruct(in UInt256 nonce, in UInt256 balance) + public AccountStruct(in ulong nonce, in UInt256 balance) { _balance = balance; _nonce = nonce; @@ -133,11 +133,11 @@ public AccountStruct(in UInt256 nonce, in UInt256 balance) public AccountStruct(in UInt256 balance) => _balance = balance; public bool HasCode => CodeHash != Keccak.OfAnEmptyString.ValueHash256; public bool HasStorage => _storageRoot != Keccak.EmptyTreeHash.ValueHash256; - public UInt256 Nonce => _nonce; + public ulong Nonce => _nonce; public UInt256 Balance => _balance; public ValueHash256 StorageRoot => _storageRoot; public bool IsTotallyEmpty => IsEmpty && IsStorageEmpty; - public bool IsEmpty => Balance.IsZero && Nonce.IsZero && CodeHash == Keccak.OfAnEmptyString.ValueHash256; + public bool IsEmpty => Balance.IsZero && Nonce == 0 && CodeHash == Keccak.OfAnEmptyString.ValueHash256; public bool IsContract => CodeHash != Keccak.OfAnEmptyString.ValueHash256; public bool IsStorageEmpty => _storageRoot == Keccak.EmptyTreeHash.ValueHash256; public bool IsNull @@ -163,7 +163,7 @@ public bool IsNull // ret // ; Total bytes of code: 37 (Unsafe.As>(ref Unsafe.AsRef(in _balance)) | - Unsafe.As>(ref Unsafe.AsRef(in _nonce)) | + Unsafe.As>(ref Unsafe.AsRef(in _nonce)) | Unsafe.As>(ref Unsafe.AsRef(in CodeHash)) | Unsafe.As>(ref Unsafe.AsRef(in _storageRoot))) == default; } diff --git a/src/Nethermind/Nethermind.Core/Authentication/JwtAuthentication.cs b/src/Nethermind/Nethermind.Core/Authentication/JwtAuthentication.cs index 9ac3979b7838..cf934ec2f0cb 100644 --- a/src/Nethermind/Nethermind.Core/Authentication/JwtAuthentication.cs +++ b/src/Nethermind/Nethermind.Core/Authentication/JwtAuthentication.cs @@ -266,7 +266,7 @@ private bool TryValidateManual(string token, long nowUnixSeconds, out bool accep // Overflow-safe absolute-difference check: casting to ulong maps negative values to // large positives, so (ulong)(a - b + c) > (ulong)(2*c) is equivalent to |a - b| > c // without needing Math.Abs (which can overflow on long.MinValue). - if ((ulong)(iat - nowUnixSeconds + JwtTokenTtl) > (ulong)(JwtTokenTtl * 2)) + if ((ulong)(iat - nowUnixSeconds + JwtTokenTtl) > JwtTokenTtl * 2UL) { if (_logger.IsWarn) WarnTokenExpiredIat(iat, nowUnixSeconds); return true; @@ -402,7 +402,7 @@ private bool ValidateLibraryResult(TokenValidationResult result, string token, J long issuedAtUnix = jwtToken.IssuedAt.ToUnixTimeSeconds(); // Unsigned range check: |iat - now| <= TTL without Math.Abs overflow guard - if ((ulong)(issuedAtUnix - nowUnixSeconds + JwtTokenTtl) > (ulong)(JwtTokenTtl * 2)) + if ((ulong)(issuedAtUnix - nowUnixSeconds + JwtTokenTtl) > JwtTokenTtl * 2UL) { if (_logger.IsWarn) WarnTokenExpired(issuedAtUnix, nowUnixSeconds); return false; @@ -478,7 +478,7 @@ private bool TryLastValidationFromCache(string token, long nowUnixSeconds) return false; // Unsigned range check: |iat - now| <= TTL - if ((ulong)(_cachedTokenIat - nowUnixSeconds + JwtTokenTtl) > (ulong)(JwtTokenTtl * 2)) + if ((ulong)(_cachedTokenIat - nowUnixSeconds + JwtTokenTtl) > JwtTokenTtl * 2UL) { Volatile.Write(ref _cachedToken, null); return false; diff --git a/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs b/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs index 6987630b47f3..531347f67e1b 100644 --- a/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs +++ b/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs @@ -23,7 +23,7 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) { UInt256 parentBaseFee = parent.BaseFeePerGas; bool isForkBlockNumber = specFor1559.Eip1559TransitionBlock == parent.Number + 1; - long parentGasTarget = parent.GasLimit / specFor1559.ElasticityMultiplier; + ulong parentGasTarget = parent.GasLimit / (ulong)specFor1559.ElasticityMultiplier; if (isForkBlockNumber) parentGasTarget = parent.GasLimit; @@ -37,7 +37,7 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) } else if (parent.GasUsed > parentGasTarget) { - long gasDelta = parent.GasUsed - parentGasTarget; + ulong gasDelta = parent.GasUsed - parentGasTarget; UInt256 feeDelta = UInt256.Max( parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / specFor1559.BaseFeeMaxChangeDenominator, UInt256.One); @@ -45,7 +45,7 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) } else { - long gasDelta = parentGasTarget - parent.GasUsed; + ulong gasDelta = parentGasTarget - parent.GasUsed; UInt256 feeDelta = parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / specFor1559.BaseFeeMaxChangeDenominator; expectedBaseFee = UInt256.Max(parentBaseFee - feeDelta, 0); } diff --git a/src/Nethermind/Nethermind.Core/Block.cs b/src/Nethermind/Nethermind.Core/Block.cs index 36aabd73b520..e761ea6332a0 100644 --- a/src/Nethermind/Nethermind.Core/Block.cs +++ b/src/Nethermind/Nethermind.Core/Block.cs @@ -92,15 +92,15 @@ public Transaction[] Transactions public Hash256? ReceiptsRoot => Header.ReceiptsRoot; // do not add setter here - public long GasLimit => Header.GasLimit; // do not add setter here + public ulong GasLimit => Header.GasLimit; // do not add setter here - public long GasUsed => Header.GasUsed; // do not add setter here + public ulong GasUsed => Header.GasUsed; // do not add setter here public ulong Timestamp => Header.Timestamp; // do not add setter here public DateTime TimestampDate => Header.TimestampDate; // do not add setter here - public long Number => Header.Number; // do not add setter here + public ulong Number => Header.Number; // do not add setter here public UInt256 Difficulty => Header.Difficulty; // do not add setter here diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index bb8731ca124a..b29a8b12f5b1 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -21,8 +21,8 @@ public BlockHeader( Hash256 unclesHash, Address beneficiary, in UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[] extraData, ulong? blobGasUsed = null, @@ -46,7 +46,7 @@ public BlockHeader( SlotNumber = slotNumber; } - public virtual long GenesisBlockNumber => 0; + public virtual ulong GenesisBlockNumber => 0; public bool IsGenesis => Number == GenesisBlockNumber; public Hash256? ParentHash { get; set; } public Hash256? UnclesHash { get; set; } @@ -58,9 +58,9 @@ public BlockHeader( public Hash256? ReceiptsRoot { get; set; } public Bloom? Bloom { get; set; } public UInt256 Difficulty; - public long Number { get; set; } - public long GasUsed { get; set; } - public long GasLimit { get; set; } + public ulong Number { get; set; } + public ulong GasUsed { get; set; } + public ulong GasLimit { get; set; } public ulong Timestamp { get; set; } public DateTime TimestampDate => DateTimeOffset.FromUnixTimeSeconds((long)Timestamp).LocalDateTime; public byte[] ExtraData { get; set; } = []; diff --git a/src/Nethermind/Nethermind.Core/BlockInfo.cs b/src/Nethermind/Nethermind.Core/BlockInfo.cs index 675639485a41..d7b4ba326590 100644 --- a/src/Nethermind/Nethermind.Core/BlockInfo.cs +++ b/src/Nethermind/Nethermind.Core/BlockInfo.cs @@ -68,7 +68,7 @@ public bool IsBeaconInfo /// /// This property is not serialized /// - public long BlockNumber { get; set; } + public ulong BlockNumber { get; set; } public override string ToString() => BlockHash.ToString(); diff --git a/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs b/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs index d71b1bd24107..607bfa011d29 100644 --- a/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs @@ -57,7 +57,7 @@ public static int BinarySearch(this IList list, TSearch v return ~lower; } - public static bool TryGetForBlock(this IList list, in long blockNumber, out long item) => + public static bool TryGetForBlock(this IList list, in ulong blockNumber, out ulong item) => list.TryGetSearchedItem(blockNumber, static (b, c) => b.CompareTo(c), out item); public static bool TryGetSearchedItem(this IList list, in TComparable searchedItem, Func comparer, out T? item) diff --git a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs index 1cfd0c1efc09..301f40f10e24 100644 --- a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs @@ -18,5 +18,5 @@ public static class Eip2935Constants /// /// The HISTORY_SERVE_WINDOW parameter. /// - public static readonly long RingBufferSize = 8191; + public static readonly ulong RingBufferSize = 8191; } diff --git a/src/Nethermind/Nethermind.Core/Eip7825Constants.cs b/src/Nethermind/Nethermind.Core/Eip7825Constants.cs index beabe71dc46c..f21f5feca115 100644 --- a/src/Nethermind/Nethermind.Core/Eip7825Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip7825Constants.cs @@ -7,9 +7,9 @@ namespace Nethermind.Core; public static class Eip7825Constants { - public static readonly long DefaultTxGasLimitCap = 16_777_216; - public static long GetTxGasLimitCap(this IReleaseSpec spec) + public static readonly ulong DefaultTxGasLimitCap = 16_777_216; + public static ulong GetTxGasLimitCap(this IReleaseSpec spec) => spec.IsEip7825Enabled && !spec.IsEip8037Enabled ? DefaultTxGasLimitCap - : long.MaxValue; + : ulong.MaxValue; } diff --git a/src/Nethermind/Nethermind.Core/Eip8037Constants.cs b/src/Nethermind/Nethermind.Core/Eip8037Constants.cs index 204842413c49..39050727b129 100644 --- a/src/Nethermind/Nethermind.Core/Eip8037Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip8037Constants.cs @@ -5,8 +5,8 @@ namespace Nethermind.Core; public static class Eip8037Constants { - public const long SystemCallBaseGasLimit = 30_000_000L; - public const long SystemMaxSstoresPerCall = 16; - public const long SystemCallStateReservoir = GasCostOf.StateBytesPerStorageSet * GasCostOf.CostPerStateByte * SystemMaxSstoresPerCall; - public const long SystemCallGasLimit = SystemCallBaseGasLimit + SystemCallStateReservoir; + public const ulong SystemCallBaseGasLimit = 30_000_000; + public const ulong SystemMaxSstoresPerCall = 16; + public const ulong SystemCallStateReservoir = GasCostOf.StateBytesPerStorageSet * GasCostOf.CostPerStateByte * SystemMaxSstoresPerCall; + public const ulong SystemCallGasLimit = SystemCallBaseGasLimit + SystemCallStateReservoir; } diff --git a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs index ad77f70b1d5c..e0b0fc8b7cf1 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs @@ -88,19 +88,19 @@ public static string ToHexString(this in UInt256 value, bool skipLeadingZeros) return bytes.ToHexString(true, skipLeadingZeros, false); } - public static long ToLongFromBigEndianByteArrayWithoutLeadingZeros(this byte[]? bytes) + public static ulong ToLongFromBigEndianByteArrayWithoutLeadingZeros(this byte[]? bytes) { if (bytes is null) { return 0L; } - long value = 0; + ulong value = 0; int length = bytes.Length; for (int i = 0; i < length; i++) { - value += (long)bytes[length - 1 - i] << 8 * i; + value += (ulong)bytes[length - 1 - i] << 8 * i; } return value; diff --git a/src/Nethermind/Nethermind.Core/Extensions/SizeExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SizeExtensions.cs index c239de18eba0..56ddaad0c255 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SizeExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SizeExtensions.cs @@ -39,4 +39,14 @@ public string SizeToString(bool useSi = false, bool addSpace = false, int precis public long MiB => ((long)@this).MiB; public long KiB => ((long)@this).KiB; } + + extension(ulong @this) + { + public ulong GB => @this * 1_000_000_000UL; + public ulong MB => @this * 1_000_000UL; + public ulong KB => @this * 1_000UL; + public ulong GiB => @this * 1024UL * 1024UL * 1024UL; + public ulong MiB => @this * 1024UL * 1024UL; + public ulong KiB => @this * 1024UL; + } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/SpecProviderExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SpecProviderExtensions.cs index 593fb97824df..671df771033f 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SpecProviderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SpecProviderExtensions.cs @@ -14,7 +14,7 @@ public static class SpecProviderExtensions /// /// /// IReceiptSpec - public static IReceiptSpec GetReceiptSpec(this ISpecProvider specProvider, long blockNumber) => specProvider.GetSpec(blockNumber, null); + public static IReceiptSpec GetReceiptSpec(this ISpecProvider specProvider, ulong blockNumber) => specProvider.GetSpec(blockNumber, null); /// /// This method only retrieves the spec for 1559. @@ -23,7 +23,7 @@ public static class SpecProviderExtensions /// /// /// IEip1559Spec - public static IEip1559Spec GetSpecFor1559(this ISpecProvider specProvider, long blockNumber) => specProvider.GetSpec(blockNumber, null); + public static IEip1559Spec GetSpecFor1559(this ISpecProvider specProvider, ulong blockNumber) => specProvider.GetSpec(blockNumber, null); public static ulong GetFinalMaxBlobGasPerBlock(this ISpecProvider specProvider) => Eip4844Constants.GasPerBlob * specProvider.GetFinalSpec().MaxBlobCount; } diff --git a/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs index 2cccf2132418..e0189c5bdbe8 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs @@ -2,11 +2,26 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Buffers.Binary; +using System.Numerics; +using System.Runtime.InteropServices; namespace Nethermind.Core.Extensions; public static class UInt64Extensions { + public static ReadOnlySpan ToBigEndianSpanWithoutLeadingZeros(this ulong value, out ulong buffer) + { + // Min 7 bytes as we still want a byte if the value is 0. + int start = Math.Min(BitOperations.LeadingZeroCount(value) / sizeof(ulong), sizeof(ulong) - 1); + buffer = BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value; + ReadOnlySpan span = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref buffer, 1)); + return span[start..]; + } + + public static byte[] ToBigEndianByteArrayWithoutLeadingZeros(this ulong value) + => value.ToBigEndianSpanWithoutLeadingZeros(out _).ToArray(); + public static ulong ToULongFromBigEndianByteArrayWithoutLeadingZeros(this byte[]? bytes) => ToULongFromBigEndianByteArrayWithoutLeadingZeros(bytes.AsSpan()); @@ -27,4 +42,6 @@ public static ulong ToULongFromBigEndianByteArrayWithoutLeadingZeros(this ReadOn return value; } + + public static void WriteBigEndian(this ulong value, Span output) => BinaryPrimitives.WriteUInt64BigEndian(output, value); } diff --git a/src/Nethermind/Nethermind.Core/GasCostOf.cs b/src/Nethermind/Nethermind.Core/GasCostOf.cs index d57348f280f3..2b1b8f430eb0 100644 --- a/src/Nethermind/Nethermind.Core/GasCostOf.cs +++ b/src/Nethermind/Nethermind.Core/GasCostOf.cs @@ -5,92 +5,92 @@ namespace Nethermind.Core { public static class GasCostOf { - public const long Free = 0; - public const long Base = 2; - public const long VeryLow = 3; - public const long Low = 5; - public const long Mid = 8; - public const long High = 10; - public const long Jump = Mid; - public const long JumpI = High; - public const long ExtCode = 20; - public const long ExtCodeEip150 = 700; - public const long Balance = 20; - public const long BalanceEip150 = 400; - public const long BalanceEip1884 = 700; - public const long SLoad = 50; - public const long SLoadEip150 = 200; - public const long SLoadEip1884 = 800; - public const long JumpDest = 1; - public const long SStoreNetMeteredEip1283 = 200; - public const long SStoreNetMeteredEip2200 = 800; - public const long SSet = 20000; - public const long SReset = 5000; - public const long Create = 32000; - public const long CodeDeposit = 200; - public const long Call = 40; - public const long CallEip150 = 700; - public const long CallValue = 9000; - public const long CallStipend = 2300; - public const long NewAccount = 25000; - public const long Exp = 10; - public const long ExpByte = 10; - public const long ExpByteEip160 = 50; - public const long Memory = 3; - public const long TxCreate = 32000; - public const long TxDataZero = 4; - public const long TxDataNonZero = 68; - public const long TxDataNonZeroEip2028 = 16; - public const long Transaction = 21000; - public const long BlobHash = 3; - public const long Log = 375; - public const long LogTopic = 375; - public const long LogData = 8; - public const long Sha3 = 30; - public const long Sha3Word = 6; - public const long BlockHash = 20; - public const long SelfDestruct = 0; - public const long SelfDestructEip150 = 5000; - public const long ExtCodeHash = 400; - public const long ExtCodeHashEip1884 = 700; - public const long SelfBalance = 5; - public const long InitCodeWord = 2; //eip-3860 gas per word cost for init code size + public const ulong Free = 0; + public const ulong Base = 2; + public const ulong VeryLow = 3; + public const ulong Low = 5; + public const ulong Mid = 8; + public const ulong High = 10; + public const ulong Jump = Mid; + public const ulong JumpI = High; + public const ulong ExtCode = 20; + public const ulong ExtCodeEip150 = 700; + public const ulong Balance = 20; + public const ulong BalanceEip150 = 400; + public const ulong BalanceEip1884 = 700; + public const ulong SLoad = 50; + public const ulong SLoadEip150 = 200; + public const ulong SLoadEip1884 = 800; + public const ulong JumpDest = 1; + public const ulong SStoreNetMeteredEip1283 = 200; + public const ulong SStoreNetMeteredEip2200 = 800; + public const ulong SSet = 20000; + public const ulong SReset = 5000; + public const ulong Create = 32000; + public const ulong CodeDeposit = 200; + public const ulong Call = 40; + public const ulong CallEip150 = 700; + public const ulong CallValue = 9000; + public const ulong CallStipend = 2300; + public const ulong NewAccount = 25000; + public const ulong Exp = 10; + public const ulong ExpByte = 10; + public const ulong ExpByteEip160 = 50; + public const ulong Memory = 3; + public const ulong TxCreate = 32000; + public const ulong TxDataZero = 4; + public const ulong TxDataNonZero = 68; + public const ulong TxDataNonZeroEip2028 = 16; + public const ulong Transaction = 21000; + public const ulong BlobHash = 3; + public const ulong Log = 375; + public const ulong LogTopic = 375; + public const ulong LogData = 8; + public const ulong Sha3 = 30; + public const ulong Sha3Word = 6; + public const ulong BlockHash = 20; + public const ulong SelfDestruct = 0; + public const ulong SelfDestructEip150 = 5000; + public const ulong ExtCodeHash = 400; + public const ulong ExtCodeHashEip1884 = 700; + public const ulong SelfBalance = 5; + public const ulong InitCodeWord = 2; //eip-3860 gas per word cost for init code size - public const long ColdSLoad = 2100; // eip-2929 + public const ulong ColdSLoad = 2100; // eip-2929 - public const long ColdAccountAccess = 2600; // eip-2929 - public const long WarmStateRead = 100; // eip-2929 - public const long CallPrecompileEip2929 = 100; // eip-2929 + public const ulong ColdAccountAccess = 2600; // eip-2929 + public const ulong WarmStateRead = 100; // eip-2929 + public const ulong CallPrecompileEip2929 = 100; // eip-2929 - public const long AccessAccountListEntry = 2400; // eip-2930 - public const long AccessStorageListEntry = 1900; // eip-2930 - public const long TLoad = WarmStateRead; // eip-1153 - public const long TStore = WarmStateRead; // eip-1153 - public const long PerAuthBaseCost = 12500; // eip-7702 - public const long TotalCostFloorPerTokenEip7623 = 10; // eip-7623 - public const long TotalCostFloorPerTokenEip7976 = 16; // eip-7976 + public const ulong AccessAccountListEntry = 2400; // eip-2930 + public const ulong AccessStorageListEntry = 1900; // eip-2930 + public const ulong TLoad = WarmStateRead; // eip-1153 + public const ulong TStore = WarmStateRead; // eip-1153 + public const ulong PerAuthBaseCost = 12500; // eip-7702 + public const ulong TotalCostFloorPerTokenEip7623 = 10; // eip-7623 + public const ulong TotalCostFloorPerTokenEip7976 = 16; // eip-7976 - public const long CostPerStateByte = 1530; // eip-8037 - public const long StateBytesPerStorageSet = 64; // eip-8037 - public const long StateBytesPerNewAccount = 120; // eip-8037 - public const long StateBytesPerAuthBase = 23; // eip-8037 - public const long SSetRegular = 2_900; - public const long SSetState = StateBytesPerStorageSet * CostPerStateByte; - public const long CreateRegular = 9_000; - public const long CreateState = StateBytesPerNewAccount * CostPerStateByte; - public const long NewAccountState = StateBytesPerNewAccount * CostPerStateByte; - public const long CodeDepositRegularPerWord = 6; - public const long CodeDepositState = CostPerStateByte; - public const long PerAuthBaseRegular = 7_500; - public const long PerAuthBaseState = StateBytesPerAuthBase * CostPerStateByte; - public const long PerEmptyAccountState = StateBytesPerNewAccount * CostPerStateByte; - public const long BlockAccessListItem = Eip7928Constants.ItemCost; // eip-7928 + public const ulong CostPerStateByte = 1530; // eip-8037 + public const ulong StateBytesPerStorageSet = 64; // eip-8037 + public const ulong StateBytesPerNewAccount = 120; // eip-8037 + public const ulong StateBytesPerAuthBase = 23; // eip-8037 + public const ulong SSetRegular = 2_900; + public const ulong SSetState = StateBytesPerStorageSet * CostPerStateByte; + public const ulong CreateRegular = 9_000; + public const ulong CreateState = StateBytesPerNewAccount * CostPerStateByte; + public const ulong NewAccountState = StateBytesPerNewAccount * CostPerStateByte; + public const ulong CodeDepositRegularPerWord = 6; + public const ulong CodeDepositState = CostPerStateByte; + public const ulong PerAuthBaseRegular = 7_500; + public const ulong PerAuthBaseState = StateBytesPerAuthBase * CostPerStateByte; + public const ulong PerEmptyAccountState = StateBytesPerNewAccount * CostPerStateByte; + public const ulong BlockAccessListItem = Eip7928Constants.ItemCost; // eip-7928 - public const long TxDataNonZeroMultiplier = TxDataNonZero / TxDataZero; - public const long TxDataNonZeroMultiplierEip2028 = TxDataNonZeroEip2028 / TxDataZero; + public const ulong TxDataNonZeroMultiplier = TxDataNonZero / TxDataZero; + public const ulong TxDataNonZeroMultiplierEip2028 = TxDataNonZeroEip2028 / TxDataZero; - public const long MinModExpEip2565 = 200; // eip-2565 - public const long MinModExpEip7883 = 500; // eip-7883 + public const ulong MinModExpEip2565 = 200; // eip-2565 + public const ulong MinModExpEip7883 = 500; // eip-7883 } } diff --git a/src/Nethermind/Nethermind.Core/IAccountStateProvider.cs b/src/Nethermind/Nethermind.Core/IAccountStateProvider.cs index 5b949c67dea3..bcb9c9b6ab32 100644 --- a/src/Nethermind/Nethermind.Core/IAccountStateProvider.cs +++ b/src/Nethermind/Nethermind.Core/IAccountStateProvider.cs @@ -12,7 +12,7 @@ public interface IAccountStateProvider bool TryGetAccount(Address address, out AccountStruct account); [SkipLocalsInit] - UInt256 GetNonce(Address address) + ulong GetNonce(Address address) { TryGetAccount(address, out AccountStruct account); return account.Nonce; diff --git a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs index 0ce70eaf2238..925a76fdb555 100644 --- a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs +++ b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs @@ -49,6 +49,10 @@ public bool KeyExists(Hash256 key) public bool KeyExists(long key) => db.KeyExists(key.ToBigEndianSpanWithoutLeadingZeros(out _)); public byte[]? Get(long key) => db[key.ToBigEndianSpanWithoutLeadingZeros(out _)]; + + public bool KeyExists(ulong key) => db.KeyExists(key.ToBigEndianSpanWithoutLeadingZeros(out _)); + + public byte[]? Get(ulong key) => db[key.ToBigEndianSpanWithoutLeadingZeros(out _)]; } extension(IWriteOnlyKeyValueStore db) @@ -79,7 +83,7 @@ public void Set(Hash256 key, in CappedArray value, WriteFlags writeFlags = } } - public void Set(long blockNumber, Hash256 key, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) + public void Set(ulong blockNumber, Hash256 key, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) { Span blockNumberPrefixedKey = stackalloc byte[40]; GetBlockNumPrefixedKey(blockNumber, key, blockNumberPrefixedKey); @@ -92,8 +96,10 @@ public void Set(long blockNumber, Hash256 key, ReadOnlySpan value, WriteFl public void Delete(long key) => db.Remove(key.ToBigEndianSpanWithoutLeadingZeros(out _)); + public void Delete(ulong key) => db.Remove(key.ToBigEndianSpanWithoutLeadingZeros(out _)); + [SkipLocalsInit] - public void Delete(long blockNumber, Hash256 hash) + public void Delete(ulong blockNumber, Hash256 hash) { Span key = stackalloc byte[40]; GetBlockNumPrefixedKey(blockNumber, hash, key); @@ -101,9 +107,11 @@ public void Delete(long blockNumber, Hash256 hash) } public void Set(long key, byte[] value) => db[key.ToBigEndianSpanWithoutLeadingZeros(out _)] = value; + + public void Set(ulong key, byte[] value) => db[key.ToBigEndianSpanWithoutLeadingZeros(out _)] = value; } - public static void GetBlockNumPrefixedKey(long blockNumber, ValueHash256 blockHash, Span output) + public static void GetBlockNumPrefixedKey(ulong blockNumber, ValueHash256 blockHash, Span output) { blockNumber.WriteBigEndian(output); blockHash!.Bytes.CopyTo(output[8..]); diff --git a/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs b/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs index 9040244a27fc..9c9abb7885ab 100644 --- a/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs +++ b/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs @@ -95,7 +95,7 @@ public static string InvalidBaseFeePerGas(UInt256? expected, UInt256 actual) => public static string InvalidTxInBlock(int i) => $"InvalidTxInBlock: Tx at index {i} in body."; - public static string HeaderGasUsedMismatch(long expected, long actual) => + public static string HeaderGasUsedMismatch(ulong expected, ulong actual) => $"HeaderGasUsedMismatch: Gas used in header does not match calculated. Expected {expected}, got {actual}"; public static string BlobGasUsedAboveBlockLimit(ulong blockBlobGasLimit, int blobsCount, ulong blobGasUsed) => @@ -165,7 +165,7 @@ public static string ExceededBlockSizeLimit(int limit) => public static string InvalidBlockLevelAccessListHash(Hash256 expected, Hash256 actual) => $"InvalidBlockLevelAccessListHash: Expected {expected}, got {actual}"; - public static string BlockAccessListGasLimitExceeded(long balItems, long maxBalItems) => + public static string BlockAccessListGasLimitExceeded(int balItems, ulong maxBalItems) => $"BlockAccessListGasLimitExceeded: BAL has {balItems} items, exceeds limit of {maxBalItems} (block_gas_limit / {Eip7928Constants.ItemCost})."; public static string BlockLevelAccessListIndexOutOfRange(uint index, uint maxAllowed) => diff --git a/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs b/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs index 7c0c2eb1ae7d..ff594eb18d8f 100644 --- a/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs +++ b/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs @@ -79,10 +79,10 @@ public static string BlobTxGasLimitExceeded(ulong totalDataGas, ulong maxBlobGas public const string InvalidBlobCommitmentHash = "InvalidBlobCommitmentHash: Commitment hash does not match."; - public static string TxGasLimitCapExceeded(long gasLimit, long gasLimitCap) + public static string TxGasLimitCapExceeded(ulong gasLimit, ulong gasLimitCap) => $"TxGasLimitCapExceeded: Gas limit {gasLimit} exceeded cap of {gasLimitCap}."; - public static string TxIntrinsicGasExceedsCap(long intrinsicRegularGas, long intrinsicFloorGas, long gasLimitCap) + public static string TxIntrinsicGasExceedsCap(ulong intrinsicRegularGas, ulong intrinsicFloorGas, ulong gasLimitCap) => $"{IntrinsicGasTooLow}: Intrinsic gas (regular {intrinsicRegularGas}, floor {intrinsicFloorGas}) exceeded cap of {gasLimitCap}."; public const string NonceTooHigh = "NonceTooHigh: Nonce exceeds max nonce"; diff --git a/src/Nethermind/Nethermind.Core/ProgressLogger.cs b/src/Nethermind/Nethermind.Core/ProgressLogger.cs index b11675d371cb..ea4dcdfb46fa 100644 --- a/src/Nethermind/Nethermind.Core/ProgressLogger.cs +++ b/src/Nethermind/Nethermind.Core/ProgressLogger.cs @@ -20,7 +20,9 @@ public class ProgressLogger private readonly ILogger _logger; private readonly Action? _logAction; private string _prefix; - private (long, long, long, long) _lastReportState = (0, 0, 0, 0); + // State tuple uses ulong for block-number fields (CurrentValue, TargetValue) and long for + // CurrentQueued (uses -1 as "not enabled" sentinel) and _skipped (same sentinel). + private (ulong, ulong, long, long) _lastReportState = (0UL, 0UL, 0L, 0L); private Func? _formatter; public ProgressLogger(string prefix, ILogManager logManager, ITimestamper? timestamper = null, LogLevel logLevel = LogLevel.Info) @@ -41,7 +43,8 @@ public ProgressLogger(string prefix, ILogManager logManager, ITimestamper? times }; } - public void Update(long value) + /// Update the current progress value (a block number, always non-negative). + public void Update(ulong value) { UtcEndTime = null; @@ -82,7 +85,11 @@ public void MarkEnd() } } - public void Reset(long startValue, long total) + /// + /// Reset progress tracking. Both and are block + /// numbers (ulong) so no cast is required at call sites that deal with block heights. + /// + public void Reset(ulong startValue, ulong total) { LastMeasurement = UtcEndTime = _timestamper.UtcNow; UtcStartTime = _timestamper.UtcNow; @@ -94,7 +101,8 @@ public void Reset(long startValue, long total) private long _skipped = -1; - private long StartValue { get; set; } + // All four block-number fields are ulong — block numbers are never negative. + private ulong StartValue { get; set; } private DateTime? UtcStartTime { get; set; } @@ -102,10 +110,15 @@ public void Reset(long startValue, long total) private DateTime? LastMeasurement { get; set; } - private long LastValue { get; set; } - public long TargetValue { get; set; } + private ulong LastValue { get; set; } + public ulong TargetValue { get; set; } - public long CurrentValue { get; private set; } + public ulong CurrentValue { get; private set; } + + /// + /// Number of items currently in the processing queue. Uses -1 as "feature disabled" sentinel, + /// so this must remain long rather than ulong. + /// public long CurrentQueued { get; set; } = -1; private TimeSpan Elapsed => (UtcEndTime ?? _timestamper.UtcNow) - (UtcStartTime ?? DateTime.MinValue); @@ -121,7 +134,10 @@ public decimal TotalPerSecond return 0M; } - return (CurrentValue - StartValue) / timePassed; + // CurrentValue >= StartValue for monotonically-increasing progress; the cast to decimal + // is required because ulong subtraction yields ulong which cannot be implicitly divided + // by a decimal. + return (decimal)(CurrentValue - StartValue) / timePassed; } } @@ -160,7 +176,9 @@ public decimal CurrentPerSecond return 0M; } - return (CurrentValue - LastValue) / timePassed; + // CurrentValue >= LastValue for monotonically-increasing progress; explicit cast + // required for the same reason as TotalPerSecond above. + return (decimal)(CurrentValue - LastValue) / timePassed; } } @@ -168,7 +186,7 @@ public decimal CurrentPerSecond public void LogProgress() { - (long, long, long, long) reportState = (CurrentValue, TargetValue, CurrentQueued, _skipped); + (ulong, ulong, long, long) reportState = (CurrentValue, TargetValue, CurrentQueued, _skipped); if (reportState != _lastReportState) { _lastReportState = reportState; @@ -179,9 +197,11 @@ public void LogProgress() private string DefaultFormatter() => GenerateReport(_prefix, CurrentValue, TargetValue, CurrentQueued, CurrentPerSecond, SkippedPerSecond); - private static string GenerateReport(string prefix, long current, long total, long queue, decimal speed, decimal skippedPerSecond) + // `current` and `total` are ulong (block numbers); `queue` stays long because it uses -1 as + // a sentinel meaning "queue tracking is not enabled for this progress logger". + private static string GenerateReport(string prefix, ulong current, ulong total, long queue, decimal speed, decimal skippedPerSecond) { - float percentage = Math.Clamp(current / (float)(Math.Max(total, 1)), 0, 1); + float percentage = Math.Clamp(current / (float)Math.Max(total, 1UL), 0, 1); string queuedStr = (queue >= 0 ? $" queue {queue,QueuePaddingLength:N0} | " : " "); string skippedStr = (skippedPerSecond >= 0 ? $"skipped {skippedPerSecond,SkippedPaddingLength:N0} Blk/s | " : ""); string speedStr = $"current {speed,SpeedPaddingLength:N0} Blk/s"; diff --git a/src/Nethermind/Nethermind.Core/RefundOf.cs b/src/Nethermind/Nethermind.Core/RefundOf.cs index 3d7fb07d5e1d..690da1ed031e 100644 --- a/src/Nethermind/Nethermind.Core/RefundOf.cs +++ b/src/Nethermind/Nethermind.Core/RefundOf.cs @@ -5,16 +5,16 @@ namespace Nethermind.Core { public static class RefundOf { - public const long SSetReversedEip1283 = GasCostOf.SSet - GasCostOf.SStoreNetMeteredEip1283; - public const long SResetReversedEip1283 = GasCostOf.SReset - GasCostOf.SStoreNetMeteredEip1283; - public const long SSetReversedEip2200 = GasCostOf.SSet - GasCostOf.SStoreNetMeteredEip2200; - public const long SResetReversedEip2200 = GasCostOf.SReset - GasCostOf.SStoreNetMeteredEip2200; - public const long SSetReversedHotCold = GasCostOf.SSet - GasCostOf.WarmStateRead; - public const long SResetReversedHotCold = GasCostOf.SReset - GasCostOf.ColdSLoad - GasCostOf.WarmStateRead; - public const long SSetReversedEip8037 = GasCostOf.SSetState + GasCostOf.SSetRegular - GasCostOf.WarmStateRead; - public const long SClearAfterEip3529 = GasCostOf.SReset - GasCostOf.ColdSLoad + GasCostOf.AccessStorageListEntry; - public const long SClearBeforeEip3529 = 15000; - public const long DestroyBeforeEip3529 = 24000; - public const long DestroyAfterEip3529 = GasCostOf.Free; + public const ulong SSetReversedEip1283 = GasCostOf.SSet - GasCostOf.SStoreNetMeteredEip1283; + public const ulong SResetReversedEip1283 = GasCostOf.SReset - GasCostOf.SStoreNetMeteredEip1283; + public const ulong SSetReversedEip2200 = GasCostOf.SSet - GasCostOf.SStoreNetMeteredEip2200; + public const ulong SResetReversedEip2200 = GasCostOf.SReset - GasCostOf.SStoreNetMeteredEip2200; + public const ulong SSetReversedHotCold = GasCostOf.SSet - GasCostOf.WarmStateRead; + public const ulong SResetReversedHotCold = GasCostOf.SReset - GasCostOf.ColdSLoad - GasCostOf.WarmStateRead; + public const ulong SSetReversedEip8037 = GasCostOf.SSetState + GasCostOf.SSetRegular - GasCostOf.WarmStateRead; + public const ulong SClearAfterEip3529 = GasCostOf.SReset - GasCostOf.ColdSLoad + GasCostOf.AccessStorageListEntry; + public const ulong SClearBeforeEip3529 = 15000; + public const ulong DestroyBeforeEip3529 = 24000; + public const ulong DestroyAfterEip3529 = GasCostOf.Free; } } diff --git a/src/Nethermind/Nethermind.Core/Reorganization.cs b/src/Nethermind/Nethermind.Core/Reorganization.cs index c0e09a8d14fd..10b2626b624a 100644 --- a/src/Nethermind/Nethermind.Core/Reorganization.cs +++ b/src/Nethermind/Nethermind.Core/Reorganization.cs @@ -5,7 +5,7 @@ namespace Nethermind.Core { public static class Reorganization { - public static long MaxDepth = 64; + public static ulong MaxDepth = 64; public const long PersistenceInterval = 8192; } } diff --git a/src/Nethermind/Nethermind.Core/Specs/ForkActivation.cs b/src/Nethermind/Nethermind.Core/Specs/ForkActivation.cs index 7965f6390b20..32340644abe6 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ForkActivation.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ForkActivation.cs @@ -5,12 +5,12 @@ namespace Nethermind.Core.Specs; -public readonly struct ForkActivation(long blockNumber, ulong? timestamp = null) +public readonly struct ForkActivation(ulong blockNumber, ulong? timestamp = null) : IEquatable, IComparable { - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; public ulong? Timestamp { get; } = timestamp; - public ulong Activation => Timestamp ?? (ulong)BlockNumber; + public ulong Activation => Timestamp ?? BlockNumber; /// /// Fork activation for forks past The Merge/Paris @@ -20,20 +20,20 @@ public readonly struct ForkActivation(long blockNumber, ulong? timestamp = null) /// /// Post Merge are based only on timestamp and we can ignore block number. /// - public static ForkActivation TimestampOnly(ulong timestamp) => new(long.MaxValue, timestamp); + public static ForkActivation TimestampOnly(ulong timestamp) => new(ulong.MaxValue, timestamp); - public void Deconstruct(out long blockNumber, out ulong? timestamp) + public void Deconstruct(out ulong blockNumber, out ulong? timestamp) { blockNumber = BlockNumber; timestamp = Timestamp; } - public static explicit operator ForkActivation(long blockNumber) => new(blockNumber); + public static explicit operator ForkActivation(ulong blockNumber) => new(blockNumber); - public static implicit operator ForkActivation((long blocknumber, ulong? timestamp) forkActivation) + public static implicit operator ForkActivation((ulong blocknumber, ulong? timestamp) forkActivation) => new(forkActivation.blocknumber, forkActivation.timestamp); - public static implicit operator (long blocknumber, ulong? timestamp)(ForkActivation forkActivation) + public static implicit operator (ulong blocknumber, ulong? timestamp)(ForkActivation forkActivation) => (forkActivation.BlockNumber, forkActivation.Timestamp); public bool Equals(ForkActivation other) => BlockNumber == other.BlockNumber && Timestamp == other.Timestamp; diff --git a/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs b/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs index e0a45b3c17e2..bab13a3107ac 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs @@ -14,7 +14,7 @@ public interface IEip1559Spec /// Gas target and base fee, and fee burning. /// bool IsEip1559Enabled { get; } - public long Eip1559TransitionBlock { get; } + public ulong Eip1559TransitionBlock { get; } // Collects for both EIP-1559 and EIP-4844-Pectra public Address? FeeCollector => null; public UInt256? Eip1559BaseFeeMinValue => null; @@ -27,7 +27,7 @@ public interface IEip1559Spec public sealed class OverridableEip1559Spec(IEip1559Spec spec) : IEip1559Spec { public bool IsEip1559Enabled { get; init; } = spec.IsEip1559Enabled; - public long Eip1559TransitionBlock { get; init; } = spec.Eip1559TransitionBlock; + public ulong Eip1559TransitionBlock { get; init; } = spec.Eip1559TransitionBlock; public Address? FeeCollector { get; init; } = spec.FeeCollector; public UInt256? Eip1559BaseFeeMinValue { get; init; } = spec.Eip1559BaseFeeMinValue; public UInt256 ForkBaseFee { get; init; } = spec.ForkBaseFee; diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index e61a2763291f..d033bf70e874 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -16,14 +16,14 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec public string Name { get; } long MaximumExtraDataSize { get; } long MaxCodeSize { get; } - long MinGasLimit { get; } + ulong MinGasLimit { get; } long MinHistoryRetentionEpochs { get; } long MinBalRetentionEpochs { get; } - long GasLimitBoundDivisor { get; } + ulong GasLimitBoundDivisor { get; } UInt256 BlockReward { get; } - long DifficultyBombDelay { get; } - long DifficultyBoundDivisor { get; } - long? FixedDifficulty { get; } + ulong DifficultyBombDelay { get; } + ulong DifficultyBoundDivisor { get; } + ulong? FixedDifficulty { get; } int MaximumUncleCount { get; } /// @@ -309,7 +309,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec /// EIP-2935 ring buffer size for historical block hash storage. /// Defaults to 8,191 blocks for Ethereum mainnet. /// - public long Eip2935RingBufferSize { get; } + public ulong Eip2935RingBufferSize { get; } /// /// SELFDESTRUCT only in same transaction diff --git a/src/Nethermind/Nethermind.Core/Specs/ISpecProvider.cs b/src/Nethermind/Nethermind.Core/Specs/ISpecProvider.cs index d0b2287a3b8f..d753771f9b6f 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ISpecProvider.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ISpecProvider.cs @@ -16,7 +16,7 @@ public interface ISpecProvider /// The merge block number is different from the rest forks because we don't know the merge block before it happens. /// This function handles change of the merge block /// - void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null); + void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null); /// /// We have two different block numbers for merge transition: @@ -49,7 +49,7 @@ public interface ISpecProvider /// /// Block number at which DAO happens (only relevant for mainnet) /// - long? DaoBlockNumber { get; } + ulong? DaoBlockNumber { get; } ulong? BeaconChainGenesisTimestamp { get; } @@ -86,7 +86,7 @@ public static class SpecProviderExtensions { extension(ISpecProvider specProvider) { - public IReleaseSpec GetSpec(long blockNumber, ulong? timestamp) => specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)); + public IReleaseSpec GetSpec(ulong blockNumber, ulong? timestamp) => specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)); public IReleaseSpec GetSpec(BlockHeader blockHeader) => specProvider.GetSpec(new ForkActivation(blockHeader.Number, blockHeader.Timestamp)); /// diff --git a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs index bccc4cd62cf7..7e0d34a45fc2 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs @@ -12,14 +12,14 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual string Name => spec.Name; public virtual long MaximumExtraDataSize => spec.MaximumExtraDataSize; public virtual long MaxCodeSize => spec.MaxCodeSize; - public virtual long MinGasLimit => spec.MinGasLimit; + public virtual ulong MinGasLimit => spec.MinGasLimit; public virtual long MinHistoryRetentionEpochs => spec.MinHistoryRetentionEpochs; public virtual long MinBalRetentionEpochs => spec.MinBalRetentionEpochs; - public virtual long GasLimitBoundDivisor => spec.GasLimitBoundDivisor; + public virtual ulong GasLimitBoundDivisor => spec.GasLimitBoundDivisor; public virtual UInt256 BlockReward => spec.BlockReward; - public virtual long DifficultyBombDelay => spec.DifficultyBombDelay; - public virtual long DifficultyBoundDivisor => spec.DifficultyBoundDivisor; - public virtual long? FixedDifficulty => spec.FixedDifficulty; + public virtual ulong DifficultyBombDelay => spec.DifficultyBombDelay; + public virtual ulong DifficultyBoundDivisor => spec.DifficultyBoundDivisor; + public virtual ulong? FixedDifficulty => spec.FixedDifficulty; public virtual int MaximumUncleCount => spec.MaximumUncleCount; public virtual bool IsTimeAdjustmentPostOlympic => spec.IsTimeAdjustmentPostOlympic; public virtual bool IsEip2Enabled => spec.IsEip2Enabled; @@ -54,7 +54,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual bool IsEip2929Enabled => spec.IsEip2929Enabled; public virtual bool IsEip2930Enabled => spec.IsEip2930Enabled; public virtual bool IsEip1559Enabled => spec.IsEip1559Enabled; - public virtual long Eip1559TransitionBlock => spec.Eip1559TransitionBlock; + public virtual ulong Eip1559TransitionBlock => spec.Eip1559TransitionBlock; public virtual Address? Eip158IgnoredAccount => spec.Eip158IgnoredAccount; public virtual bool IsEip3198Enabled => spec.IsEip3198Enabled; public virtual bool IsEip3529Enabled => spec.IsEip3529Enabled; @@ -78,7 +78,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual bool IsEip2935Enabled => spec.IsEip2935Enabled; public virtual bool IsEip7709Enabled => spec.IsEip7709Enabled; public virtual Address? Eip2935ContractAddress => spec.Eip2935ContractAddress; - public virtual long Eip2935RingBufferSize => spec.Eip2935RingBufferSize; + public virtual ulong Eip2935RingBufferSize => spec.Eip2935RingBufferSize; public virtual bool IsEip6780Enabled => spec.IsEip6780Enabled; public virtual bool IsEip7702Enabled => spec.IsEip7702Enabled; public virtual bool IsEip7823Enabled => spec.IsEip7823Enabled; diff --git a/src/Nethermind/Nethermind.Core/Specs/SpecGasCosts.cs b/src/Nethermind/Nethermind.Core/Specs/SpecGasCosts.cs index 124848462b48..45072a8847fb 100644 --- a/src/Nethermind/Nethermind.Core/Specs/SpecGasCosts.cs +++ b/src/Nethermind/Nethermind.Core/Specs/SpecGasCosts.cs @@ -13,21 +13,21 @@ namespace Nethermind.Core.Specs; public sealed class SpecGasCosts : IEquatable { private readonly int _hashCode; - public readonly long SLoadCost; - public readonly long BalanceCost; - public readonly long ExtCodeCost; - public readonly long ExtCodeHashCost; - public readonly long CallCost; - public readonly long ExpByteCost; - public readonly long SStoreResetCost; - public readonly long TxDataNonZeroMultiplier; - public readonly long TotalCostFloorPerToken; - - public readonly long NetMeteredSStoreCost; - public readonly long ClearReversalRefund; - public readonly long SetReversalRefund; - public readonly long SClearRefund; - public readonly long DestroyRefund; + public readonly ulong SLoadCost; + public readonly ulong BalanceCost; + public readonly ulong ExtCodeCost; + public readonly ulong ExtCodeHashCost; + public readonly ulong CallCost; + public readonly ulong ExpByteCost; + public readonly ulong SStoreResetCost; + public readonly ulong TxDataNonZeroMultiplier; + public readonly ulong TotalCostFloorPerToken; + + public readonly ulong NetMeteredSStoreCost; + public readonly ulong ClearReversalRefund; + public readonly ulong SetReversalRefund; + public readonly ulong SClearRefund; + public readonly ulong DestroyRefund; public readonly ulong MaxBlobGasPerBlock; public readonly ulong MaxBlobGasPerTx; @@ -41,23 +41,23 @@ public SpecGasCosts(IReleaseSpec spec) bool netIstanbul = spec.UseIstanbulNetGasMetering; // EIP-2200 bool netConstantinople = spec.UseConstantinopleNetGasMetering; // EIP-1283 - long clearReversalRefund = ClearReversalRefund = + ulong clearReversalRefund = ClearReversalRefund = hotCold ? RefundOf.SResetReversedHotCold : netIstanbul ? RefundOf.SResetReversedEip2200 : netConstantinople ? RefundOf.SResetReversedEip1283 : GasCostOf.Free; - long setReversalRefund = SetReversalRefund = + ulong setReversalRefund = SetReversalRefund = hotCold ? RefundOf.SSetReversedHotCold : netIstanbul ? RefundOf.SSetReversedEip2200 : netConstantinople ? RefundOf.SSetReversedEip1283 : GasCostOf.Free; - long sStoreResetCost = SStoreResetCost = hotCold + ulong sStoreResetCost = SStoreResetCost = hotCold ? GasCostOf.SReset - GasCostOf.ColdSLoad : GasCostOf.SReset; - long netMeteredSStoreCost = NetMeteredSStoreCost = + ulong netMeteredSStoreCost = NetMeteredSStoreCost = hotCold ? GasCostOf.WarmStateRead : netIstanbul ? GasCostOf.SStoreNetMeteredEip2200 : netConstantinople ? GasCostOf.SStoreNetMeteredEip1283 @@ -121,7 +121,7 @@ public SpecGasCosts(IReleaseSpec spec) _hashCode = HashCode.Combine(hashCode1, hashCode2, DestroyRefund); } - public long RefundFromReversal(bool originalIsZero) => originalIsZero + public ulong RefundFromReversal(bool originalIsZero) => originalIsZero ? SetReversalRefund : ClearReversalRefund; diff --git a/src/Nethermind/Nethermind.Core/Threading/InterlockedEx.cs b/src/Nethermind/Nethermind.Core/Threading/InterlockedEx.cs index b5457b85cbb4..4a80a1a5f457 100644 --- a/src/Nethermind/Nethermind.Core/Threading/InterlockedEx.cs +++ b/src/Nethermind/Nethermind.Core/Threading/InterlockedEx.cs @@ -99,4 +99,49 @@ public static long Min(ref long location, long value) return current; } + + /// + /// Atomically sets a field to the maximum of the field's current value and a specified value. + /// + /// The field to update + /// The value to compare with the current value + /// The original value of the field + public static ulong Max(ref ulong location, ulong value) + { + ulong current, newValue; + do + { + current = location; + newValue = Math.Max(current, value); + + if (current >= value) + return current; + } + while (Interlocked.CompareExchange(ref location, newValue, current) != current); + + return current; + } + + /// + /// Atomically sets a field to the minimum of the field's current value and a specified value. + /// + /// The field to update + /// The value to compare with the current value + /// The original value of the field + public static ulong Min(ref ulong location, ulong value) + { + ulong current, newValue; + do + { + current = location; + newValue = Math.Min(current, value); + + if (current <= value) + return current; + } + while (Interlocked.CompareExchange(ref location, newValue, current) != current); + + return current; + } } + diff --git a/src/Nethermind/Nethermind.Core/Transaction.cs b/src/Nethermind/Nethermind.Core/Transaction.cs index 807428142efb..13b6e35d7b20 100644 --- a/src/Nethermind/Nethermind.Core/Transaction.cs +++ b/src/Nethermind/Nethermind.Core/Transaction.cs @@ -22,7 +22,7 @@ namespace Nethermind.Core public class Transaction { public const byte MaxTxType = 0x7F; - public const int BaseTxGasCost = 21000; + public const uint BaseTxGasCost = 21000; public ulong? ChainId { get; set; } @@ -43,7 +43,7 @@ public class Transaction public bool IsOPSystemTransaction { get; set; } private UInt256 _gasPrice; - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public UInt256 GasPrice { get => _gasPrice; set => _gasPrice = value; } public UInt256? GasBottleneck { get; set; } public ref readonly UInt256 MaxPriorityFeePerGas => ref _gasPrice; @@ -54,17 +54,17 @@ public class Transaction public bool Supports1559 => Type.Supports1559(); public bool SupportsBlobs => Type.SupportsBlobs(); public bool SupportsAuthorizationList => Type.SupportsAuthorizationList(); - public long GasLimit { get; set; } - private long _spentGas; - private long _blockGasUsed; + public ulong GasLimit { get; set; } + private ulong _spentGas; + private ulong _blockGasUsed; [JsonIgnore] - public long SpentGas { get => _spentGas > 0 ? _spentGas : GasLimit; set => _spentGas = value; } + public ulong SpentGas { get => _spentGas > 0 ? _spentGas : GasLimit; set => _spentGas = value; } /// /// Gas used for block accounting (pre-refund when EIP-7778 is enabled). /// Defaults to when unknown. /// [JsonIgnore] - public long BlockGasUsed { get => _blockGasUsed > 0 ? _blockGasUsed : GasLimit; set => _blockGasUsed = value; } + public ulong BlockGasUsed { get => _blockGasUsed > 0 ? _blockGasUsed : GasLimit; set => _blockGasUsed = value; } public Address? To { get; set; } private UInt256 _value; public UInt256 Value { get => _value; set => _value = value; } @@ -361,7 +361,7 @@ public sealed class GeneratedTransaction : Transaction; /// public sealed class SystemTransaction : Transaction { - private new const long GasLimit = 30_000_000L; + private new const ulong GasLimit = 30_000_000UL; } /// diff --git a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs index cca0cec19c05..65012d3e5efb 100644 --- a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs @@ -39,10 +39,10 @@ public UInt256 CalculateTransactionPotentialCost(bool eip1559Enabled, in UInt256 _ => tx.CalculateEffectiveGasPrice(eip1559Enabled, baseFee) }; - return effectiveGasPrice * (ulong)tx.GasLimit + tx.ValueRef; + return effectiveGasPrice * tx.GasLimit + tx.ValueRef; } - return tx.MaxPriorityFeePerGas * (ulong)tx.GasLimit + tx.ValueRef; + return tx.MaxPriorityFeePerGas * tx.GasLimit + tx.ValueRef; } public UInt256 CalculateEffectiveGasPrice(bool eip1559Enabled, in UInt256 baseFee) => @@ -59,11 +59,11 @@ public bool IsAboveInitCode(IReleaseSpec spec) => public ulong GetBlobGas() => (uint)tx.GetBlobCount() * Eip4844Constants.GasPerBlob; public int GetBlobCount() => tx.BlobVersionedHashes?.Length ?? 0; - public void CapGasLimit(long? gasCap) + public void CapGasLimit(ulong? gasCap) { if (gasCap is not null and not 0) { - tx.GasLimit = long.Min(tx.GasLimit, gasCap.Value); + tx.GasLimit = ulong.Min(tx.GasLimit, gasCap.Value); } } } diff --git a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs index b9e797c79951..db2cdbe59d77 100644 --- a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs +++ b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs @@ -49,12 +49,12 @@ public TxReceipt(TxReceipt other) /// EIP-658 /// public byte StatusCode { get; set; } - public long BlockNumber { get; set; } + public ulong BlockNumber { get; set; } public Hash256? BlockHash { get; set; } public Hash256? TxHash { get; set; } public int Index { get; set; } - public long GasUsed { get; set; } - public long GasUsedTotal { get; set; } + public ulong GasUsed { get; set; } + public ulong GasUsedTotal { get; set; } // Diagnostic-only fields. NOT part of the consensus receipt RLP - the receipt // encoders in Nethermind.Serialization.Rlp write only StatusCode, GasUsed, @@ -63,11 +63,11 @@ public TxReceipt(TxReceipt other) // JSON dump (BlockTraceDumper) to aid investigation of EIP-7778/EIP-8037 // gas-accounting issues. /// EIP-7778 pre-refund gas used by block-level gas accounting (regular dim). - public long BlockGasUsed { get; set; } + public ulong BlockGasUsed { get; set; } /// EIP-8037 state-dim gas (storage / state-mutating ops) used by block accounting. - public long StorageGasUsed { get; set; } + public ulong StorageGasUsed { get; set; } /// Post-refund execution gas without EIP-7976 floor adjustment (OperationGas). - public long ExecutionGasUsed { get; set; } + public ulong ExecutionGasUsed { get; set; } /// Effective gas price after EIP-1559 baseFee adjustment - computed at receipt-build time. public UInt256 EffectiveGasPrice { get; set; } @@ -102,12 +102,12 @@ public ref struct TxReceiptStructRef(TxReceipt receipt) /// EIP-658 /// public byte StatusCode { get; set; } = receipt.StatusCode; - public long BlockNumber { get; set; } = receipt.BlockNumber; + public ulong BlockNumber { get; set; } = receipt.BlockNumber; public Hash256StructRef BlockHash = (receipt.BlockHash ?? Keccak.Zero).ToStructRef(); public Hash256StructRef TxHash = (receipt.TxHash ?? Keccak.Zero).ToStructRef(); public int Index { get; set; } = receipt.Index; - public long GasUsed { get; set; } = receipt.GasUsed; - public long GasUsedTotal { get; set; } = receipt.GasUsedTotal; + public ulong GasUsed { get; set; } = receipt.GasUsed; + public ulong GasUsedTotal { get; set; } = receipt.GasUsedTotal; public AddressStructRef Sender = (receipt.Sender ?? Address.Zero).ToStructRef(); public AddressStructRef ContractAddress = (receipt.ContractAddress ?? Address.Zero).ToStructRef(); public AddressStructRef Recipient = (receipt.Recipient ?? Address.Zero).ToStructRef(); diff --git a/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs b/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs index 20e65944a55d..a9309e16c0f3 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs @@ -9,7 +9,7 @@ public class DbConfig : IDbConfig { public static DbConfig Default = new(); - public ulong SharedBlockCacheSize { get; set; } = (ulong)256.MiB; + public ulong SharedBlockCacheSize { get; set; } = 256UL.MiB; public bool SkipMemoryHintSetting { get; set; } = false; public bool WriteAheadLogSync { get; set; } = false; @@ -19,7 +19,7 @@ public class DbConfig : IDbConfig public int? MaxOpenFiles { get; set; } public bool? SkipCheckingSstFileSizesOnDbOpen { get; set; } - public ulong? ReadAheadSize { get; set; } = (ulong)256.KiB; + public ulong? ReadAheadSize { get; set; } = 256UL.KiB; public string RocksDbOptions { get; set; } = @@ -134,7 +134,7 @@ public class DbConfig : IDbConfig ""; public string? HeadersDbAdditionalRocksDbOptions { get; set; } = ""; - public ulong? BlockNumbersDbRowCacheSize { get; set; } = (ulong)16.MiB; + public ulong? BlockNumbersDbRowCacheSize { get; set; } = 16UL.MiB; public string BlockNumbersDbRocksDbOptions { get; set; } = "write_buffer_size=8000000;" + "max_bytes_for_level_base=16000000;" + @@ -159,7 +159,7 @@ public class DbConfig : IDbConfig "write_buffer_size=4000000;"; public string? PendingTxsDbAdditionalRocksDbOptions { get; set; } - public ulong? CodeDbRowCacheSize { get; set; } = (ulong)16.MiB; + public ulong? CodeDbRowCacheSize { get; set; } = 16UL.MiB; public string CodeDbRocksDbOptions { get; set; } = "write_buffer_size=16000000;" + "block_based_table_factory.block_cache=16000000;" + @@ -182,7 +182,7 @@ public class DbConfig : IDbConfig "max_bytes_for_level_base=16000000;"; public string? MetadataDbAdditionalRocksDbOptions { get; set; } - public ulong StateDbWriteBufferSize { get; set; } = (ulong)64.MB; + public ulong StateDbWriteBufferSize { get; set; } = 64UL.MB; public ulong StateDbWriteBufferNumber { get; set; } = 4; public bool? StateDbVerifyChecksum { get; set; } = true; public ulong? StateDbRowCacheSize { get; set; } @@ -268,8 +268,8 @@ public class DbConfig : IDbConfig // slight adjustment to block size, for potentially better db size. "block_based_table_factory.block_size=64000;"; - public ulong StateDbLargeMemoryWriteBufferSize { get; set; } = (ulong)128.MiB; - public ulong StateDbArchiveModeWriteBufferSize { get; set; } = (ulong)256.MiB; + public ulong StateDbLargeMemoryWriteBufferSize { get; set; } = 128UL.MiB; + public ulong StateDbArchiveModeWriteBufferSize { get; set; } = 256UL.MiB; public string? StateDbAdditionalRocksDbOptions { get; set; } diff --git a/src/Nethermind/Nethermind.Db.Rocks/Config/RocksDbConfigFactory.cs b/src/Nethermind/Nethermind.Db.Rocks/Config/RocksDbConfigFactory.cs index 52e4b82f6c8e..d6b02f3de656 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/Config/RocksDbConfigFactory.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/Config/RocksDbConfigFactory.cs @@ -93,13 +93,13 @@ public IRocksDbConfig GetForDatabase(string databaseName, string? columnName) if (pruningConfig.Mode.IsMemory()) { - ulong totalWriteBufferMb = rocksDbConfig.WriteBufferNumber!.Value * rocksDbConfig.WriteBufferSize!.Value / (ulong)1.MB; + ulong totalWriteBufferMb = rocksDbConfig.WriteBufferNumber!.Value * rocksDbConfig.WriteBufferSize!.Value / 1UL.MB; double minimumWriteBufferMb = 0.2 * pruningConfig.DirtyCacheMb; if (totalWriteBufferMb < minimumWriteBufferMb) { ulong minimumWriteBufferSize = (ulong)Math.Ceiling((minimumWriteBufferMb * 1.MB) / rocksDbConfig.WriteBufferNumber!.Value); - if (_logger.IsInfo) _logger.Info($"Adjust state DB write buffer size to {minimumWriteBufferSize / (ulong)1.MB} MB to account for pruning cache."); + if (_logger.IsInfo) _logger.Info($"Adjust state DB write buffer size to {minimumWriteBufferSize / 1UL.MB} MB to account for pruning cache."); rocksDbConfig = new AdjustedRocksdbConfig( rocksDbConfig, diff --git a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs index daa605b5c8eb..0aea052a96ff 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs @@ -668,7 +668,7 @@ protected virtual void BuildOptions(IRocksDbConfig dbConfig, Options optio if (dbConfig.ReadAheadSize != 0) { _readAheadReadOptions = CreateReadOptions(); - _readAheadReadOptions.SetReadaheadSize(dbConfig.ReadAheadSize ?? (ulong)256.KiB); + _readAheadReadOptions.SetReadaheadSize(dbConfig.ReadAheadSize ?? 256UL.KiB); _readAheadReadOptions.SetTailing(true); } #endregion @@ -1562,14 +1562,14 @@ public virtual void Tune(ITunableDb.TuneType type) case ITunableDb.TuneType.HeavyWrite: // Compaction spikes are clear at this point. Will definitely affect attestations performance. // It's unclear if it improves or slows down sync time. Seems to be the sweet spot. - ApplyOptions(GetHeavyWriteOptions((ulong)2.GiB)); + ApplyOptions(GetHeavyWriteOptions(2UL.GiB)); break; case ITunableDb.TuneType.AggressiveHeavyWrite: // For when you are desperate, but don't wanna disable compaction completely, because you don't want // peers to drop. Tend to be faster than disabling compaction completely, except if your ratelimit // is a bit low and your compaction is lagging behind, which will trigger slowdown, so sync will hang // intermittently, but at least peer count is stable. - ApplyOptions(GetHeavyWriteOptions((ulong)16.GiB)); + ApplyOptions(GetHeavyWriteOptions(16UL.GiB)); break; case ITunableDb.TuneType.DisableCompaction: // Completely disable compaction. On mainnet, the max num of l0 files for state seems to be about 10800. @@ -1665,8 +1665,8 @@ private IDictionary GetHeavyWriteOptions(ulong l0SizeTarget) // bufferSize*maxBufferNumber = 16MB*Core count, which is the max memory used, which tends to be the case as it's now // stalled by compaction instead of a flush. // The buffer is not compressed unlike l0File, so to account for it, its size needs to be slightly larger. - ulong targetFileSize = (ulong)16.MiB; - ulong bufferSize = (ulong)(targetFileSize / _perTableDbConfig.CompressibilityHint); + ulong targetFileSize = 16UL.MiB; + ulong bufferSize = targetFileSize / (ulong)_perTableDbConfig.CompressibilityHint; ulong l0FileSize = targetFileSize * (ulong)_minWriteBufferToMerge; ulong maxBufferNumber = (ulong)Environment.ProcessorCount; @@ -1697,7 +1697,7 @@ private IDictionary GetHeavyWriteOptions(ulong l0SizeTarget) private IDictionary GetDisableCompactionOptions() { - IDictionary heavyWriteOption = GetHeavyWriteOptions((ulong)32.GiB); + IDictionary heavyWriteOption = GetHeavyWriteOptions(32UL.GiB); heavyWriteOption["disable_auto_compactions"] = "true"; // Increase the size of the write buffer, which reduces the number of l0 files by 4x. This does slow down diff --git a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs index b77cafd273e5..c3627583a511 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs @@ -29,11 +29,11 @@ public class BloomStorage : IBloomStorage private readonly IBloomConfig _config; private readonly IDb _bloomInfoDb; private readonly IFileStoreFactory _fileStoreFactory; - private long _minBlockNumber; - private long _maxBlockNumber; - private long _migratedBlockNumber; + private ulong _minBlockNumber; + private ulong _maxBlockNumber; + private ulong _migratedBlockNumber; - public long MinBlockNumber + public ulong MinBlockNumber { get => _minBlockNumber; private set @@ -43,7 +43,7 @@ private set } } - public long MaxBlockNumber + public ulong MaxBlockNumber { get => _maxBlockNumber; set @@ -53,7 +53,7 @@ public long MaxBlockNumber } } - public long MigratedBlockNumber + public ulong MigratedBlockNumber { get => _migratedBlockNumber; private set @@ -65,16 +65,16 @@ private set public BloomStorage(IBloomConfig config, [KeyFilter(DbNames.Bloom)] IDb bloomDb, [KeyFilter(nameof(BloomStorage))] IFileStoreFactory fileStoreFactory) { - long Get(Hash256 key, long defaultValue) => bloomDb.Get(key)?.ToLongFromBigEndianByteArrayWithoutLeadingZeros() ?? defaultValue; + ulong Get(Hash256 key, ulong defaultValue) => bloomDb.Get(key)?.ToULongFromBigEndianByteArrayWithoutLeadingZeros() ?? defaultValue; _config = config ?? throw new ArgumentNullException(nameof(config)); _bloomInfoDb = bloomDb ?? throw new ArgumentNullException(nameof(bloomDb)); _fileStoreFactory = fileStoreFactory; _storageLevels = CreateStorageLevels(config); Levels = (byte)_storageLevels.Length; - _minBlockNumber = Get(MinBlockNumberKey, long.MaxValue); - _maxBlockNumber = Get(MaxBlockNumberKey, -1); - _migratedBlockNumber = Get(MigrationBlockNumberKey, -1); + _minBlockNumber = Get(MinBlockNumberKey, ulong.MaxValue); + _maxBlockNumber = Get(MaxBlockNumberKey, 0); + _migratedBlockNumber = Get(MigrationBlockNumberKey, ulong.MaxValue); } private BloomStorageLevel[] CreateStorageLevels(IBloomConfig config) @@ -136,15 +136,15 @@ void ValidateCurrentDbStructure(IList sizes) .ToArray(); } - private bool Contains(long blockNumber) => blockNumber >= MinBlockNumber && blockNumber <= MaxBlockNumber; + private bool Contains(ulong blockNumber) => blockNumber >= MinBlockNumber && blockNumber <= MaxBlockNumber; - public bool ContainsRange(in long fromBlockNumber, in long toBlockNumber) => Contains(fromBlockNumber) && Contains(toBlockNumber); + public bool ContainsRange(in ulong fromBlockNumber, in ulong toBlockNumber) => Contains(fromBlockNumber) && Contains(toBlockNumber); public IEnumerable Averages => _storageLevels.Select(static l => l.Average); - public void Store(long blockNumber, Bloom bloom) => Store([(blockNumber, bloom)]); + public void Store(ulong blockNumber, Bloom bloom) => Store([(blockNumber, bloom)]); - public void Store(IReadOnlyList<(long BlockNumber, Bloom Bloom)> blooms) + public void Store(IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms) { bool shouldParallelize = blooms.Count > 1; @@ -163,7 +163,7 @@ public void Store(IReadOnlyList<(long BlockNumber, Bloom Bloom)> blooms) } } - foreach ((long blockNumber, Bloom _) in blooms) + foreach ((ulong blockNumber, Bloom _) in blooms) { if (blockNumber < MinBlockNumber) { @@ -184,7 +184,8 @@ public void Migrate(IEnumerable headers) BloomStorageLevel lastLevel = _storageLevels.Last(); long i = 0; - long lastBlockNumber = -1; + ulong lastBlockNumber = 0; + bool hasBlocks = false; foreach (BlockHeader blockHeader in headers) { @@ -205,7 +206,7 @@ public void Migrate(IEnumerable headers) if (level.LevelElementSize == batchSize) { - MigratedBlockNumber += batchSize; + MigratedBlockNumber += (ulong)batchSize; } } } @@ -213,7 +214,7 @@ public void Migrate(IEnumerable headers) lastBlockNumber = blockHeader.Number; } - if (i % batchSize != 0) + if (hasBlocks && i % batchSize != 0) { for (int index = 0; index < levelBlooms.Length; index++) { @@ -221,7 +222,7 @@ public void Migrate(IEnumerable headers) level.Store((lastBlockNumber, bloom)); } - MigratedBlockNumber += i; + MigratedBlockNumber += (ulong)i; } if (MigratedBlockNumber >= MinBlockNumber - 1) @@ -230,7 +231,7 @@ public void Migrate(IEnumerable headers) } } - private void Set(Hash256 key, long value) => _bloomInfoDb.PutSpan(key.Bytes, value.ToBigEndianSpanWithoutLeadingZeros(out _)); + private void Set(Hash256 key, ulong value) => _bloomInfoDb.PutSpan(key.Bytes, value.ToBigEndianSpanWithoutLeadingZeros(out _)); public void Dispose() { @@ -240,7 +241,7 @@ public void Dispose() } } - public IBloomEnumeration GetBlooms(long fromBlock, long toBlock) => new BloomEnumeration(_storageLevels, Math.Max(fromBlock, MinBlockNumber), Math.Min(toBlock, MaxBlockNumber)); + public IBloomEnumeration GetBlooms(ulong fromBlock, ulong toBlock) => new BloomEnumeration(_storageLevels, Math.Max(fromBlock, MinBlockNumber), Math.Min(toBlock, MaxBlockNumber)); private class BloomStorageLevel(IFileStore fileStore, in byte level, in int levelElementSize, in int levelMultiplier, bool migrationStatistics) : IDisposable { @@ -255,7 +256,7 @@ private class BloomStorageLevel(IFileStore fileStore, in byte level, in int leve private readonly bool _migrationStatistics = migrationStatistics; private readonly LruCache _cache = new(levelMultiplier, levelMultiplier, "blooms"); - public void Store(params IReadOnlyList<(long BlockNumber, Bloom Bloom)> blooms) + public void Store(params IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms) { lock (_fileStore) { @@ -272,7 +273,7 @@ void WriteCurrentBloom() } } - foreach ((long blockNumber, Bloom bloom) in blooms) + foreach ((ulong blockNumber, Bloom bloom) in blooms) { try { @@ -310,11 +311,11 @@ void WriteCurrentBloom() private static uint CountBits(Bloom bloom) => bloom.Bytes.CountBits(); - public long GetBucket(long blockNumber) => blockNumber / LevelElementSize; + public long GetBucket(ulong blockNumber) => (long)(blockNumber / (ulong)LevelElementSize); public IFileReader CreateReader() => _fileStore.CreateFileReader(); - public void Migrate(in long blockNumber, Bloom bloom) + public void Migrate(in ulong blockNumber, Bloom bloom) { if (_migrationStatistics) { @@ -327,19 +328,19 @@ public void Migrate(in long blockNumber, Bloom bloom) public void Dispose() => _fileStore?.Dispose(); } - private class BloomEnumeration(BloomStorage.BloomStorageLevel[] storageLevels, long fromBlock, long toBlock) : IBloomEnumeration + private class BloomEnumeration(BloomStorageLevel[] storageLevels, ulong fromBlock, ulong toBlock) : IBloomEnumeration { private readonly BloomStorageLevel[] _storageLevels = storageLevels; - private readonly long _fromBlock = fromBlock; - private readonly long _toBlock = toBlock; + private readonly ulong _fromBlock = fromBlock; + private readonly ulong _toBlock = toBlock; private BloomEnumerator _current; - public IEnumerator GetEnumerator() => _current = new BloomEnumerator(_storageLevels, _fromBlock, _toBlock); + public IEnumerator GetEnumerator() => _current = new BloomEnumerator(_storageLevels, (long)_fromBlock, (long)_toBlock); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public bool TryGetBlockNumber(out long blockNumber) => _current.TryGetBlockNumber(out blockNumber); - public (long FromBlock, long ToBlock) CurrentIndices => _current.CurrentIndices; + public bool TryGetBlockNumber(out ulong blockNumber) => _current.TryGetBlockNumber(out blockNumber); + public (ulong FromBlock, ulong ToBlock) CurrentIndices => _current.CurrentIndices; public override string ToString() => _current.ToString(); } @@ -347,10 +348,10 @@ private class BloomEnumeration(BloomStorage.BloomStorageLevel[] storageLevels, l private class BloomEnumerator : IEnumerator { private readonly (BloomStorageLevel Storage, IFileReader Reader)[] _storageLevels; - private readonly long _fromBlock; - private readonly long _toBlock; + private readonly ulong _fromBlock; + private readonly ulong _toBlock; private readonly int _maxLevel; - private long _currentPosition; + private ulong _currentPosition; private readonly Bloom _bloom = new(); private byte CurrentLevel @@ -367,10 +368,11 @@ private byte CurrentLevel private byte _currentLevel; public BloomEnumerator(BloomStorageLevel[] storageLevels, in long fromBlock, in long toBlock) + // TODO: Change fromBlock/toBlock to ulong once callers are updated { _storageLevels = GetStorageLevels(storageLevels, fromBlock, toBlock); - _fromBlock = fromBlock; - _toBlock = toBlock; + _fromBlock = (ulong)fromBlock; + _toBlock = (ulong)toBlock; _maxLevel = _storageLevels.Length - 1; Reset(); } @@ -385,8 +387,8 @@ private static (BloomStorageLevel Storage, IFileReader Reader)[] GetStorageLevel if (i != storageLevels.Length - 1) { - long fromBucket = level.GetBucket(fromBlock); - long toBucket = level.GetBucket(toBlock); + long fromBucket = level.GetBucket((ulong)fromBlock); + long toBucket = level.GetBucket((ulong)toBlock); if (toBucket - fromBucket + 1 <= 2) { continue; @@ -413,10 +415,10 @@ public bool MoveNext() { BloomStorageLevel currentStorageLevel = _storageLevels[CurrentLevel].Storage; _currentPosition += _currentPosition == _fromBlock - ? currentStorageLevel.LevelElementSize - _currentPosition % currentStorageLevel.LevelElementSize - : currentStorageLevel.LevelElementSize; + ? (ulong)currentStorageLevel.LevelElementSize - _currentPosition % (ulong)currentStorageLevel.LevelElementSize + : (ulong)currentStorageLevel.LevelElementSize; - while (CurrentLevel > 0 && _currentPosition % _storageLevels[CurrentLevel - 1].Storage.LevelElementSize == 0) + while (CurrentLevel > 0 && _currentPosition % (ulong)_storageLevels[CurrentLevel - 1].Storage.LevelElementSize == 0) { CurrentLevel--; } @@ -443,17 +445,17 @@ public Bloom Current } } - public (long FromBlock, long ToBlock) CurrentIndices + public (ulong FromBlock, ulong ToBlock) CurrentIndices { get { BloomStorageLevel level = _storageLevels[_currentLevel].Storage; - long bucket = level.GetBucket(_currentPosition); - return (bucket * level.LevelElementSize, (bucket + 1) * level.LevelElementSize - 1); + ulong bucket = (ulong)level.GetBucket(_currentPosition); + return (bucket * (ulong)level.LevelElementSize, (bucket + 1) * (ulong)level.LevelElementSize - 1); } } - public bool TryGetBlockNumber(out long blockNumber) + public bool TryGetBlockNumber(out ulong blockNumber) { blockNumber = _currentPosition; if (CurrentLevel == _maxLevel) @@ -475,7 +477,7 @@ public void Dispose() public override string ToString() { - (long FromBlock, long ToBlock) = CurrentIndices; + (ulong FromBlock, ulong ToBlock) = CurrentIndices; return $"From: {_fromBlock}, To: {_toBlock}, MaxLevel {_maxLevel}, CurrentBloom {FromBlock}...{ToBlock}, CurrentLevelSize {ToBlock - FromBlock + 1} CurrentLevel {CurrentLevel}, LevelRead {_currentLevelRead}"; } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/IBloomEnumeration.cs b/src/Nethermind/Nethermind.Db/Blooms/IBloomEnumeration.cs index f8aab642ed4b..eaea14335e90 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/IBloomEnumeration.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/IBloomEnumeration.cs @@ -7,7 +7,7 @@ namespace Nethermind.Db.Blooms { public interface IBloomEnumeration : IEnumerable { - bool TryGetBlockNumber(out long blockNumber); - (long FromBlock, long ToBlock) CurrentIndices { get; } + bool TryGetBlockNumber(out ulong blockNumber); + (ulong FromBlock, ulong ToBlock) CurrentIndices { get; } } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/IBloomStorage.cs b/src/Nethermind/Nethermind.Db/Blooms/IBloomStorage.cs index f29633eef292..e1be8e43a199 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/IBloomStorage.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/IBloomStorage.cs @@ -9,21 +9,21 @@ namespace Nethermind.Db.Blooms { public interface IBloomStorage : IDisposable { - long MinBlockNumber { get; } + ulong MinBlockNumber { get; } - void Store(IReadOnlyList<(long BlockNumber, Bloom Bloom)> blooms); - void Store(long blockNumber, Bloom bloom); + void Store(IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms); + void Store(ulong blockNumber, Bloom bloom); void Migrate(IEnumerable blockHeaders); - IBloomEnumeration GetBlooms(long fromBlock, long toBlock); + IBloomEnumeration GetBlooms(ulong fromBlock, ulong toBlock); - bool ContainsRange(in long fromBlockNumber, in long toBlockNumber); + bool ContainsRange(in ulong fromBlockNumber, in ulong toBlockNumber); public bool NeedsMigration => MinBlockNumber != 0; IEnumerable Averages { get; } - long MigratedBlockNumber { get; } + ulong MigratedBlockNumber { get; } } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/NullBloomStorage.cs b/src/Nethermind/Nethermind.Db/Blooms/NullBloomStorage.cs index 9f7959df08b5..42eb482e3157 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/NullBloomStorage.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/NullBloomStorage.cs @@ -16,18 +16,18 @@ private NullBloomStorage() } public static NullBloomStorage Instance { get; } = new(); - public long MinBlockNumber { get; } = long.MaxValue; - public long MaxBlockNumber { get; } = 0; - public long MigratedBlockNumber { get; } = -1; + public ulong MinBlockNumber { get; } = ulong.MaxValue; + public ulong MaxBlockNumber { get; } = 0; + public ulong MigratedBlockNumber { get; } = 0; - public void Store(IReadOnlyList<(long BlockNumber, Bloom Bloom)> blooms) { } - public void Store(long blockNumber, Bloom bloom) { } + public void Store(IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms) { } + public void Store(ulong blockNumber, Bloom bloom) { } public void Migrate(IEnumerable blockHeaders) { } - public IBloomEnumeration GetBlooms(long fromBlock, long toBlock) => new NullBloomEnumerator(); + public IBloomEnumeration GetBlooms(ulong fromBlock, ulong toBlock) => new NullBloomEnumerator(); - public bool ContainsRange(in long fromBlockNumber, in long toBlockNumber) => false; + public bool ContainsRange(in ulong fromBlockNumber, in ulong toBlockNumber) => false; public IEnumerable Averages { get; } = Array.Empty(); @@ -36,13 +36,13 @@ private class NullBloomEnumerator : IBloomEnumeration { public IEnumerator GetEnumerator() => Enumerable.Empty().GetEnumerator(); - public bool TryGetBlockNumber(out long blockNumber) + public bool TryGetBlockNumber(out ulong blockNumber) { blockNumber = default; return false; } - public (long FromBlock, long ToBlock) CurrentIndices { get; } = (0, 0); + public (ulong FromBlock, ulong ToBlock) CurrentIndices { get; } = (0, 0); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } diff --git a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs index 2b1ed1ce4342..878ee55cf849 100644 --- a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs @@ -134,7 +134,7 @@ public async Task CreateEraAndVerifyAccumulators() int numOfBlocks = 12; int numOfTx = 2; - UInt256 nonce = 0; + ulong nonce = 0; List blocks = []; blocks.Add(genesis); @@ -206,7 +206,7 @@ public async Task TestEraBuilderCreatesCorrectIndex() Assert.That(fileReader.BlockCount, Is.EqualTo(numOfBlocks)); byte[] buf = new byte[2]; - for (int i = 0; i < fileReader.BlockCount; i++) + for (ulong i = 0; i < fileReader.BlockCount; i++) { long blockOffset = fileReader.BlockOffset(fileReader.First + i); @@ -237,7 +237,7 @@ public async Task TestBigBlocksExportImportHistory() int numOfBlocks = 16; int numOfTx = 1000; - UInt256 nonce = 0; + ulong nonce = 0; List blocks = [ genesis @@ -298,14 +298,14 @@ public async Task TestBigBlocksExportImportHistory() } } - [TestCase(true, 0L, 0L, 1000L, 1001L, 9999L)] - [TestCase(true, 0L, 2000L, 1000L, 1001L, 2000L)] - [TestCase(true, 3000L, 0L, 5000L, 5001L, 9999L)] - [TestCase(true, 0L, 0L, 0L, null, 0L)] - [TestCase(false, 0L, 0L, 0L, 1L, 9999L)] - [TestCase(false, 0L, 0L, 2000L, 2001L, 9999L)] + [TestCase(true, 0L, 0L, 1000UL, 1001L, 9999L)] + [TestCase(true, 0L, 2000L, 1000UL, 1001L, 2000L)] + [TestCase(true, 3000L, 0L, 5000UL, 5001L, 9999L)] + [TestCase(true, 0L, 0L, 0UL, null, 0L)] + [TestCase(false, 0L, 0L, 0UL, 1L, 9999L)] + [TestCase(false, 0L, 0L, 2000UL, 2001L, 9999L)] [CancelAfter(120_000)] // macOS ARM runners need more time for 10k-block chain - public async Task EraExportAndImport(bool fastSync, long start, long end, long headBlockNumber, long? expectedMinSuggestedBlock, long expectedMaxSuggestedBlock, CancellationToken cancellationToken) + public async Task EraExportAndImport(bool fastSync, long start, long end, ulong headBlockNumber, long? expectedMinSuggestedBlock, long expectedMaxSuggestedBlock, CancellationToken cancellationToken) { const int ChainLength = 10000; await using IContainer outCtx = await EraTestModule.CreateExportedEraEnvWithCompleteBlockBuilder(ChainLength, cancellationToken: cancellationToken); @@ -332,8 +332,8 @@ public async Task EraExportAndImport(bool fastSync, long start, long end, long h }) .AddSingleton(new EraConfig() { - From = start, - To = end, + From = (ulong)start, + To = (ulong)end, ImportDirectory = tmpDir, TrustedAccumulatorFile = Path.Join(tmpDir, EraExporter.AccumulatorFileName), MaxEra1Size = 16, @@ -341,8 +341,8 @@ public async Task EraExportAndImport(bool fastSync, long start, long end, long h }) .Build(); - long? minSuggestedNumber = null; - long maxSuggestedBlock = 0; + ulong? minSuggestedNumber = null; + ulong maxSuggestedBlock = 0; inTree.NewBestSuggestedBlock += (sender, args) => { minSuggestedNumber ??= args.Block.Number; diff --git a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs index 089dea20f57d..86c69ed68aa1 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs @@ -29,7 +29,7 @@ public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_Wit string tmpDirectory = container.ResolveTempDirPath(); IEraExporter sut = container.Resolve(); - await sut.Export(tmpDirectory, start, end); + await sut.Export(tmpDirectory, (ulong)start, (ulong)end); int fileCount = container.Resolve().Directory.GetFiles(tmpDirectory).Length; int metaFile = 2; @@ -69,7 +69,7 @@ public void Export_ExportBeyondAvailableBlocks_ThrowEraException(int chainLength IEraExporter sut = container.Resolve(); string tmpDirectory = container.ResolveTempDirPath(); - Assert.That(() => sut.Export(tmpDirectory, 0, to), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 0UL, (ulong)to), Throws.TypeOf()); } [Test] @@ -84,6 +84,6 @@ public void Export_ReceiptsAreNull_ThrowEraException() IEraExporter sut = container.Resolve(); - Assert.That(() => sut.Export(tmpDirectory, 0, 1), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 0UL, 1UL), Throws.TypeOf()); } } diff --git a/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs b/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs index 6e974b587bc6..506ad1c24be4 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs @@ -164,8 +164,8 @@ public async Task ImportAsArchiveSync_WillPaceSuggestBlock(CancellationToken tok inTree.NewBestSuggestedBlock += (sender, args) => { if (shouldUpdateMainChain) inTree.UpdateMainChain([args.Block], true); - maxSuggestedBlocks = args.Block.Number; - if (args.Block.Number == expectedStopBlock) reachedBlock11.Set(); + maxSuggestedBlocks = (long)args.Block.Number; + if ((long)args.Block.Number == expectedStopBlock) reachedBlock11.Set(); }; IEraImporter sut = inCtx.Resolve(); @@ -177,7 +177,7 @@ public async Task ImportAsArchiveSync_WillPaceSuggestBlock(CancellationToken tok Assert.That(maxSuggestedBlocks, Is.EqualTo(expectedStopBlock)); shouldUpdateMainChain = true; - inTree.UpdateMainChain([inTree.FindBlock(expectedStopBlock, BlockTreeLookupOptions.None)!], true); + inTree.UpdateMainChain([inTree.FindBlock((ulong)expectedStopBlock, BlockTreeLookupOptions.None)!], true); await importTask; } diff --git a/src/Nethermind/Nethermind.Era1.Test/EraReaderTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraReaderTests.cs index b8617bc53d95..966cfec66d64 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraReaderTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraReaderTests.cs @@ -80,10 +80,10 @@ public async Task ReadAccumulator_DoesNotThrow() Assert.That(() => sut.ReadAccumulator(), Throws.Nothing); } - [TestCase(0)] - [TestCase(1)] - [TestCase(2)] - public async Task GetBlockByNumber_DifferentNumber_ReturnsBlockWithCorrectNumber(int number) + [TestCase(0UL)] + [TestCase(1UL)] + [TestCase(2UL)] + public async Task GetBlockByNumber_DifferentNumber_ReturnsBlockWithCorrectNumber(ulong number) { using PopulatedTestFile tmpFile = await PopulatedTestFile.Create(); diff --git a/src/Nethermind/Nethermind.Era1.Test/EraStoreTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraStoreTests.cs index dec2b809e349..24398fbd4075 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraStoreTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraStoreTests.cs @@ -7,10 +7,10 @@ namespace Nethermind.Era1.Test; public class EraStoreTests { - [TestCase(1000, 16, 32)] - [TestCase(1000, 16, 64)] - [TestCase(1000, 50, 100)] - public async Task SmallestAndLowestBlock_ShouldBeCorrect(int chainLength, int start, int end) + [TestCase(1000, 16UL, 32UL)] + [TestCase(1000, 16UL, 64UL)] + [TestCase(1000, 50UL, 100UL)] + public async Task SmallestAndLowestBlock_ShouldBeCorrect(int chainLength, ulong start, ulong end) { await using IContainer ctx = await EraTestModule.CreateExportedEraEnv(chainLength, start, end); string tmpDirectory = ctx.ResolveTempDirPath(); diff --git a/src/Nethermind/Nethermind.Era1.Test/EraTestModule.cs b/src/Nethermind/Nethermind.Era1.Test/EraTestModule.cs index 5ec011d5fba4..9f6d879e66d1 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraTestModule.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraTestModule.cs @@ -36,7 +36,7 @@ public static ContainerBuilder BuildContainerBuilderWithBlockTreeOfLength(int le }); } - public static async Task CreateExportedEraEnvWithCompleteBlockBuilder(int chainLength = 512, int start = 0, int end = 0, CancellationToken cancellationToken = default) + public static async Task CreateExportedEraEnvWithCompleteBlockBuilder(int chainLength = 512, ulong start = 0, ulong end = 0, CancellationToken cancellationToken = default) { IContainer testCtx = new ContainerBuilder() .AddModule(new EraTestModule(useRealValidator: true)) @@ -54,7 +54,7 @@ public static async Task CreateExportedEraEnvWithCompleteBlockBuilde return testCtx; } - public static async Task CreateExportedEraEnv(int chainLength = 512, int start = 0, int end = 0) + public static async Task CreateExportedEraEnv(int chainLength = 512, ulong start = 0, ulong end = 0) { IContainer testCtx = BuildContainerBuilderWithBlockTreeOfLength(chainLength).Build(); await testCtx.Resolve().Export(testCtx.ResolveTempDirPath(), start, end); diff --git a/src/Nethermind/Nethermind.Era1.Test/EraWriterTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraWriterTests.cs index 91cc084daa8d..965ab6fbb9fd 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraWriterTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraWriterTests.cs @@ -47,7 +47,7 @@ public async Task Add_AddMoreThanMaximumOf8192_Throws() stream.WriteAsync(Arg.Any(), Arg.Any(), Arg.Any()).Returns(Task.CompletedTask); EraWriter sut = new(stream, Substitute.For()); - for (int i = 0; i < EraWriter.MaxEra1Size; i++) + for (uint i = 0; i < EraWriter.MaxEra1Size; i++) { Block block = Build.A.Block.WithNumber(i) .WithTotalDifficulty(BlockHeaderBuilder.DefaultDifficulty).TestObject; diff --git a/src/Nethermind/Nethermind.Era1/AdminEraService.cs b/src/Nethermind/Nethermind.Era1/AdminEraService.cs index f1cbb1d401b9..b37ef3376df6 100644 --- a/src/Nethermind/Nethermind.Era1/AdminEraService.cs +++ b/src/Nethermind/Nethermind.Era1/AdminEraService.cs @@ -20,7 +20,7 @@ public class AdminEraService( private int _canEnterImport = 1; private int _canEnterExport = 1; - public string ExportHistory(string destination, long from, long to) + public string ExportHistory(string destination, ulong from, ulong to) { if (Interlocked.Exchange(ref _canEnterExport, 0) != 1) throw new InvalidOperationException("An export job is already running."); @@ -38,7 +38,7 @@ public string ExportHistory(string destination, long from, long to) return "Started export task"; } - public string ImportHistory(string source, long from, long to, string? accumulatorFile) + public string ImportHistory(string source, ulong from, ulong to, string? accumulatorFile) { if (Interlocked.Exchange(ref _canEnterImport, 0) != 1) throw new InvalidOperationException("An import job is already running."); @@ -57,7 +57,7 @@ public string ImportHistory(string source, long from, long to, string? accumulat } - private async Task StartExportTask(string destination, long from, long to) + private async Task StartExportTask(string destination, ulong from, ulong to) { // Creating the task is outside the try block so that argument exceptions can be caught Task task = _eraExporter.Export( @@ -90,7 +90,7 @@ private async Task StartExportTask(string destination, long from, long to) } } - private async Task StartImportTask(string source, string? accumulatorFile, long from, long to) + private async Task StartImportTask(string source, string? accumulatorFile, ulong from, ulong to) { Task task = _eraImporter.Import( source, diff --git a/src/Nethermind/Nethermind.Era1/E2StoreReader.cs b/src/Nethermind/Nethermind.Era1/E2StoreReader.cs index ea49c7b04536..9fa8a99c44a7 100644 --- a/src/Nethermind/Nethermind.Era1/E2StoreReader.cs +++ b/src/Nethermind/Nethermind.Era1/E2StoreReader.cs @@ -25,10 +25,10 @@ public class E2StoreReader : IDisposable private readonly SafeFileHandle _file; - // Read these two value ahead of time instead of fetching the value everything it is needed to reduce + // Read these two values ahead of time instead of fetching the value every time it is needed to reduce // the page fault when looking up. - private long? _startBlock; - private long _blockCount; + private ulong? _startBlock; + private ulong _blockCount; private readonly long _fileLength; public E2StoreReader(string filePath) @@ -63,7 +63,7 @@ public Entry ReadEntry(long position, ushort? expectedType, CancellationToken to Entry entry = new(type, length); if (expectedType.HasValue && entry.Type != expectedType) throw new EraException($"Expected an entry of type {expectedType}, but got {entry.Type}."); - if (entry.Length + (ulong)position > (ulong)_fileLength) + if ((long)entry.Length + position > _fileLength) throw new EraFormatException($"Entry has an invalid length of {entry.Length} at position {position}, which is longer than stream length of {_fileLength}."); if (entry.Length > ValueSizeLimit) throw new EraException($"Entry exceeds the maximum size limit of {ValueSizeLimit}. Entry is {entry.Length}."); @@ -92,7 +92,7 @@ private async Task ReadEntryValueAsSnappy(long offset, ulong length, Func< public void Dispose() => _file.Dispose(); - public long BlockOffset(long blockNumber) + public long BlockOffset(ulong blockNumber) { EnsureIndexAvailable(); @@ -100,8 +100,11 @@ public long BlockOffset(long blockNumber) throw new ArgumentOutOfRangeException(nameof(blockNumber), $"Block {blockNumber} is outside the bounds of this index."); // * 8 + + // Cast to int is safe: _blockCount is bounded by era file size (max ~8192 blocks per era). int indexLength = (int)_blockCount * IndexOffsetSize + IndexSectionCount; - long offsetLocation = indexLength - (long)(blockNumber - _startBlock!) * IndexOffsetSize; + + // Cast to long is safe: blockNumber - _startBlock is bounded by _blockCount which fits in int. + long offsetLocation = indexLength - (long)(blockNumber - _startBlock!.Value) * IndexOffsetSize; //
+ + int indexSizeIncludingHeader = HeaderSize + IndexSectionStartBlock + indexLength; @@ -118,18 +121,19 @@ private void EnsureIndexAvailable() if (_fileLength < 32) throw new EraFormatException("Invalid era file. Too small to contain index."); // Read the block count - _blockCount = (long)ReadUInt64(_fileLength - IndexSectionCount); + _blockCount = ReadUInt64(_fileLength - IndexSectionCount); // + * 8 + + // Cast to int is safe: _blockCount is bounded by era file size (max ~8192 blocks per era). int indexLength = IndexSectionStartBlock + (int)_blockCount * IndexOffsetSize + IndexSectionCount; // Verify that its a block index _ = ReadEntry(_fileLength - indexLength - HeaderSize, EntryTypes.BlockIndex); - _startBlock = (long?)ReadUInt64(_fileLength - indexLength); + _startBlock = ReadUInt64(_fileLength - indexLength); } - public long First + public ulong First { get { @@ -138,7 +142,16 @@ public long First } } - public long LastBlock => First + _blockCount - 1; + public ulong LastBlock + { + get + { + EnsureIndexAvailable(); + // _blockCount >= 1 is guaranteed by EnsureIndexAvailable (empty era files are invalid), + // so this subtraction cannot underflow. + return First + _blockCount - 1; + } + } public long AccumulatorOffset { @@ -147,6 +160,7 @@ public long AccumulatorOffset EnsureIndexAvailable(); // + + * 8 + + // Cast to int is safe: _blockCount is bounded by era file size (max ~8192 blocks per era). int indexLengthIncludingHeader = HeaderSize + IndexSectionStartBlock + (int)_blockCount * IndexOffsetSize + IndexSectionCount; //
+ + @@ -156,7 +170,7 @@ public long AccumulatorOffset } } - public long BlockCount + public ulong BlockCount { get { diff --git a/src/Nethermind/Nethermind.Era1/EraConfig.cs b/src/Nethermind/Nethermind.Era1/EraConfig.cs index 74a2743816e3..feed323ab33f 100644 --- a/src/Nethermind/Nethermind.Era1/EraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/EraConfig.cs @@ -7,8 +7,8 @@ public class EraConfig : IEraConfig { public string? ImportDirectory { get; set; } public string? ExportDirectory { get; set; } - public long From { get; set; } - public long To { get; set; } + public ulong From { get; set; } + public ulong To { get; set; } public string? TrustedAccumulatorFile { get; set; } public int MaxEra1Size { get; set; } = EraWriter.MaxEra1Size; public string? NetworkName { get; set; } diff --git a/src/Nethermind/Nethermind.Era1/EraExporter.cs b/src/Nethermind/Nethermind.Era1/EraExporter.cs index 3c9702879915..db415c621340 100644 --- a/src/Nethermind/Nethermind.Era1/EraExporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraExporter.cs @@ -22,7 +22,7 @@ public class EraExporter( ILogManager logManager) : IEraExporter { - private readonly string _networkName = (string.IsNullOrWhiteSpace(eraConfig.NetworkName)) + private readonly string _networkName = string.IsNullOrWhiteSpace(eraConfig.NetworkName) ? throw new ArgumentException("Cannot be null or whitespace.", nameof(eraConfig.NetworkName)) : eraConfig.NetworkName.Trim().ToLower(); @@ -34,13 +34,13 @@ public class EraExporter( public Task Export( string destinationPath, - long from, - long to, + ulong from, + ulong to, CancellationToken cancellation = default) { if (fileSystem.File.Exists(destinationPath)) throw new ArgumentException($"Destination already exist as a file.", nameof(destinationPath)); - if (to == 0) to = blockTree.Head?.Number ?? 0; - if (to > (blockTree.Head?.Number ?? 0)) throw new ArgumentException($"Cannot export to a block after head block {blockTree.Head?.Number ?? 0}."); + if (to == 0) to = blockTree.Head?.Number ?? 0UL; + if (to > (blockTree.Head?.Number ?? 0UL)) throw new ArgumentException($"Cannot export to a block after head block {blockTree.Head?.Number ?? 0UL}."); if (from > to) throw new ArgumentException($"Start block ({from}) must be before end ({to}) block"); return DoExport(destinationPath, from, to, cancellation: cancellation); @@ -48,8 +48,8 @@ public Task Export( private async Task DoExport( string destinationPath, - long from, - long to, + ulong from, + ulong to, CancellationToken cancellation = default) { if (_logger.IsInfo) _logger.Info($"Exporting from block {from} to block {to} as Era files to {destinationPath}"); @@ -59,13 +59,20 @@ private async Task DoExport( } ProgressLogger progress = new("Era export", logManager); + // Cast to long is safe: to - from + 1 is a block count used only as a progress display + // value; no realistic chain has more than long.MaxValue blocks. progress.Reset(0, to - from + 1); int totalProcessed = 0; - long startEpoch = from / _era1Size; - long epochCount = (long)Math.Ceiling((to - from + 1) / (decimal)_era1Size); - using ArrayPoolList epochIdxs = new((int)epochCount); - for (long i = 0; i < epochCount; i++) + // Cast to long is safe: epoch numbers are small ordinals (thousands at most). + ulong era1Size = (ulong)_era1Size; + ulong startEpoch = from / era1Size; + // Ceiling division without floating point, all ulong. + ulong epochCount = (to - from + era1Size) / era1Size; + + // Cast to int is safe: epochCount is bounded by chain length / era size, well within int range. + using ArrayPoolList epochIdxs = new((int)epochCount); + for (ulong i = 0; i < epochCount; i++) { epochIdxs.Add(i); } @@ -97,16 +104,17 @@ private async Task DoExport( if (_logger.IsInfo) _logger.Info($"Finished history export from {from} to {to}"); - async Task WriteEpoch(long epochIdx) + async Task WriteEpoch(ulong epochIdx) { // Yes, it offset a bit so a block that is at the end of an epoch would be at the start of another epoch - // if the start is not of module _era1Size. This seems to match geth's behaviour. - long epoch = startEpoch + epochIdx; - long startingIndex = from + epochIdx * _era1Size; + // if the start is not a multiple of _era1Size. This seems to match geth's behaviour. + ulong epoch = startEpoch + epochIdx; + ulong startingIndex = from + epochIdx * era1Size; string filePath = Path.Combine( destinationPath, - EraPathUtils.Filename(_networkName, epoch, Keccak.Zero)); + // Cast to long is safe: epoch ordinals are small and well within long range. + EraPathUtils.Filename(_networkName, (long)epoch, Keccak.Zero)); ValueHash256 accumulator; ValueHash256 sha256; @@ -114,7 +122,7 @@ async Task WriteEpoch(long epochIdx) // Scoped using so the writer is disposed before File.Move — Windows locks open files. using (EraWriter eraWriter = new(fileSystem.File.Create(filePath), specProvider)) { - for (long y = startingIndex; y < startingIndex + _era1Size && y <= to; y++) + for (ulong y = startingIndex; y < startingIndex + era1Size && y <= to; y++) { Block? block = blockTree.FindBlock(y, BlockTreeLookupOptions.DoNotCreateLevelIfMissing) ?? throw new EraException($"Could not find a block with number {y}."); @@ -135,7 +143,7 @@ async Task WriteEpoch(long epochIdx) bool shouldLog = (Interlocked.Increment(ref totalProcessed) % 10000) == 0; if (shouldLog) { - progress.Update(totalProcessed); + progress.Update((ulong)totalProcessed); progress.LogProgress(); } } @@ -143,12 +151,13 @@ async Task WriteEpoch(long epochIdx) (accumulator, sha256) = await eraWriter.Finalize(cancellation); } + // Cast to int is safe: epochIdx is bounded by epochCount which was already cast to int above. accumulators[(int)epochIdx] = accumulator; checksums[(int)epochIdx] = sha256; fileNames[(int)epochIdx] = Path.GetFileName(filePath); string rename = Path.Combine( destinationPath, - EraPathUtils.Filename(_networkName, epoch, new Hash256(accumulator))); + EraPathUtils.Filename(_networkName, (long)epoch, new Hash256(accumulator))); // Retry to handle transient file locks on Windows (e.g. antivirus scanning). for (int attempt = 0; ; attempt++) { diff --git a/src/Nethermind/Nethermind.Era1/EraImporter.cs b/src/Nethermind/Nethermind.Era1/EraImporter.cs index 74f994e314b1..ce53a074f4f2 100644 --- a/src/Nethermind/Nethermind.Era1/EraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraImporter.cs @@ -34,7 +34,7 @@ public class EraImporter( private readonly ILogger _logger = logManager.GetClassLogger(); private readonly int _maxEra1Size = eraConfig.MaxEra1Size; - public async Task Import(string src, long from, long to, string? accumulatorFile, CancellationToken cancellation = default) + public async Task Import(string src, ulong from, ulong to, string? accumulatorFile, CancellationToken cancellation = default) { if (!fileSystem.Directory.Exists(src)) throw new ArgumentException($"Import directory {src} does not exist"); @@ -49,18 +49,18 @@ public async Task Import(string src, long from, long to, string? accumulatorFile using IEraStore eraStore = eraStoreFactory.Create(src, trustedAccumulators); - long lastBlockInStore = eraStore.LastBlock; - if (to == 0) to = long.MaxValue; - if (to != long.MaxValue && lastBlockInStore < to) + ulong lastBlockInStore = eraStore.LastBlock; + if (to == 0) to = ulong.MaxValue; + if (to != ulong.MaxValue && lastBlockInStore < to) { throw new EraImportException($"The directory given for import '{src}' have highest block number {lastBlockInStore} which is lower then last requested block {to}."); } - if (to == long.MaxValue) + if (to == ulong.MaxValue) { to = lastBlockInStore; } - long firstBlockInStore = eraStore.FirstBlock; + ulong firstBlockInStore = eraStore.FirstBlock; if (from == 0 && firstBlockInStore != 0) { from = firstBlockInStore; @@ -72,7 +72,8 @@ public async Task Import(string src, long from, long to, string? accumulatorFile if (from > to && to != 0) throw new ArgumentException($"Start block ({from}) must not be after end block ({to})"); - long headp1 = (blockTree.Head?.Number ?? 0) + 1; + // blockTree.Head?.Number is now ulong; +1 is safe as head will never be ulong.MaxValue. + ulong headp1 = (blockTree.Head?.Number ?? 0UL) + 1UL; if (from > headp1) { throw new ArgumentException($"Start block ({from}) must not be after block after head ({headp1})"); @@ -93,8 +94,8 @@ public async Task Import(string src, long from, long to, string? accumulatorFile } private async Task ImportInternal( - long from, - long to, + ulong from, + ulong to, IEraStore eraStore, CancellationToken cancellation) { @@ -103,23 +104,25 @@ private async Task ImportInternal( using IEraStore _ = eraStore; ProgressLogger progressLogger = new("Era import", logManager); - progressLogger.Reset(0, to - from + 1); - long blocksProcessed = 0; + // to - from + 1 is safe: from <= to is guaranteed by the caller. + progressLogger.Reset(0, to - from + 1UL); + ulong blocksProcessed = 0; - using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, eraConfig.ImportBlocksBufferSize - 1024); - long blockNumber = from; + using BlockTreeSuggestPacer pacer = new(blockTree, (ulong)eraConfig.ImportBlocksBufferSize, (ulong)(eraConfig.ImportBlocksBufferSize - 1024)); + ulong blockNumber = from; - long suggestFromBlock = (blockTree.Head?.Number ?? 0) + 1; - if (syncConfig.FastSync && suggestFromBlock == 1) + // blockTree.Head?.Number is ulong; +1 is safe (head never reaches ulong.MaxValue in practice). + ulong suggestFromBlock = (blockTree.Head?.Number ?? 0UL) + 1UL; + if (syncConfig.FastSync && suggestFromBlock == 1UL) { // Its syncing right now. So no state. - suggestFromBlock = long.MaxValue; + suggestFromBlock = ulong.MaxValue; } // I wish I could say that EraStore can be run used in parallel in any way you like but I could not make it so. - // This make the `blockNumber` aligned to era file boundary so that when running parallel, each thread does not + // This makes the `blockNumber` aligned to era file boundary so that when running parallel, each thread does not // work on the same era file as other thread. - long nextEraStart = eraStore.NextEraStart(blockNumber); + ulong nextEraStart = eraStore.NextEraStart(blockNumber); if (nextEraStart <= to) { for (; blockNumber < nextEraStart; blockNumber++) @@ -129,10 +132,10 @@ private async Task ImportInternal( } // Earlier part can be parallelized - long partitionSize = _maxEra1Size; + ulong partitionSize = (ulong)_maxEra1Size; if (blockNumber + partitionSize < suggestFromBlock) { - ConcurrentQueue partitionStartBlocks = new(); + ConcurrentQueue partitionStartBlocks = new(); for (; blockNumber + partitionSize < suggestFromBlock && blockNumber + partitionSize < to; blockNumber += partitionSize) { partitionStartBlocks.Enqueue(blockNumber); @@ -142,9 +145,9 @@ private async Task ImportInternal( { return Task.Run(async () => { - while (partitionStartBlocks.TryDequeue(out long partitionStartBlock)) + while (partitionStartBlocks.TryDequeue(out ulong partitionStartBlock)) { - for (long i = 0; i < partitionSize; i++) + for (ulong i = 0; i < partitionSize; i++) { await ImportBlock(i + partitionStartBlock); } @@ -163,7 +166,7 @@ private async Task ImportInternal( if (_logger.IsInfo) _logger.Info($"Finished history import from {from} to {to}"); - async Task ImportBlock(long blockNumber) + async Task ImportBlock(ulong blockNumber) { if (_logger.IsTrace) _logger.Trace($"Importing block {blockNumber}"); cancellation.ThrowIfCancellationRequested(); @@ -177,6 +180,7 @@ async Task ImportBlock(long blockNumber) { throw new EraImportException($"Unable to find receipt for block {blockNumber}"); } + // block.Number is ulong; no cast needed. if (block.Number != blockNumber) { throw new EraImportException($"Unexpected block number. Expected {blockNumber}. Got {block.Number}"); @@ -200,7 +204,7 @@ async Task ImportBlock(long blockNumber) else InsertBlockAndReceipts(block, receipt, to); - long processed = Interlocked.Increment(ref blocksProcessed); + ulong processed = Interlocked.Increment(ref blocksProcessed); if (processed % 10000 == 0) { progressLogger.Update(processed); @@ -209,7 +213,7 @@ async Task ImportBlock(long blockNumber) } } - private void InsertBlockAndReceipts(Block b, TxReceipt[] r, long lastBlockNumber) + private void InsertBlockAndReceipts(Block b, TxReceipt[] r, ulong lastBlockNumber) { if (blockTree.FindBlock(b.Number) is null) blockTree.Insert(b, BlockTreeInsertBlockOptions.SaveHeader | BlockTreeInsertBlockOptions.SkipCanAcceptNewBlocks, bodiesWriteFlags: WriteFlags.DisableWAL); diff --git a/src/Nethermind/Nethermind.Era1/EraReader.cs b/src/Nethermind/Nethermind.Era1/EraReader.cs index 8b8ba3436c62..069f5e4295a5 100644 --- a/src/Nethermind/Nethermind.Era1/EraReader.cs +++ b/src/Nethermind/Nethermind.Era1/EraReader.cs @@ -26,9 +26,8 @@ public class EraReader(E2StoreReader e2) : IAsyncEnumerable<(Block, TxReceipt[]) private readonly HeaderDecoder _headerDecoder = new(); private readonly E2StoreReader _fileReader = e2; - public long FirstBlock => _fileReader.First; - public long LastBlock => _fileReader.LastBlock; - + public ulong FirstBlock => _fileReader.First; + public ulong LastBlock => _fileReader.LastBlock; public EraReader(string fileName) : this(new E2StoreReader(fileName)) { @@ -36,16 +35,16 @@ public EraReader(string fileName) : this(new E2StoreReader(fileName)) public async IAsyncEnumerator<(Block, TxReceipt[])> GetAsyncEnumerator(CancellationToken cancellation = default) { - foreach (long blockNumber in EnumerateBlockNumber()) + foreach (ulong blockNumber in EnumerateBlockNumber()) { EntryReadResult result = await ReadBlockAndReceipts(blockNumber, false, cancellation); yield return (result.Block, result.Receipts); } } - private IEnumerable EnumerateBlockNumber() + private IEnumerable EnumerateBlockNumber() { - long blockNumber = _fileReader.First; + ulong blockNumber = _fileReader.First; while (blockNumber <= _fileReader.LastBlock) { yield return blockNumber; @@ -67,15 +66,15 @@ public async Task VerifyContent(ISpecProvider specProvider, IBlock ValueHash256 accumulator = ReadAccumulator(); - long startBlock = _fileReader.First; + ulong startBlock = _fileReader.First; int blockCount = (int)_fileReader.BlockCount; using ArrayPoolList<(Hash256, UInt256)> blockHashes = new(blockCount, blockCount); - ConcurrentQueue blockNumbers = new(EnumerateBlockNumber()); + ConcurrentQueue blockNumbers = new(EnumerateBlockNumber()); using ArrayPoolList workers = Enumerable.Range(0, verifyConcurrency).Select((_) => Task.Run(async () => { - while (blockNumbers.TryDequeue(out long blockNumber)) + while (blockNumbers.TryDequeue(out ulong blockNumber)) { EntryReadResult? result = await ReadBlockAndReceipts(blockNumber, true, cancellation); EntryReadResult err = result.Value; @@ -96,8 +95,9 @@ public async Task VerifyContent(ISpecProvider specProvider, IBlock throw new EraVerificationException($"Mismatched receipt root. Block number {blockNumber}."); } - // Note: Header.Hash is calculated by HeaderDecoder. + // Cast to int is safe: blockCount fits in int (checked above), and the difference + // between a block number and startBlock is bounded by blockCount. blockHashes[(int)(err.Block.Header.Number - startBlock)] = (err.Block.Header.Hash!, err.Block.TotalDifficulty!.Value); } }, cancellation)).ToPooledList(verifyConcurrency); @@ -128,7 +128,7 @@ public ValueHash256 ReadAccumulator() return hash; } - public async Task<(Block, TxReceipt[])> GetBlockByNumber(long number, CancellationToken cancellation = default) + public async Task<(Block, TxReceipt[])> GetBlockByNumber(ulong number, CancellationToken cancellation = default) { if (number < _fileReader.First) throw new ArgumentOutOfRangeException(nameof(number), $"Cannot be less than the first block number {_fileReader.First}. Number is {number}."); @@ -138,7 +138,7 @@ public ValueHash256 ReadAccumulator() return (result.Block, result.Receipts); } - private async Task ReadBlockAndReceipts(long blockNumber, bool computeHeaderHash, CancellationToken cancellationToken) + private async Task ReadBlockAndReceipts(ulong blockNumber, bool computeHeaderHash, CancellationToken cancellationToken) { if (blockNumber < _fileReader.First || blockNumber > _fileReader.LastBlock) diff --git a/src/Nethermind/Nethermind.Era1/EraStore.cs b/src/Nethermind/Nethermind.Era1/EraStore.cs index 072490bd40d3..054731b53398 100644 --- a/src/Nethermind/Nethermind.Era1/EraStore.cs +++ b/src/Nethermind/Nethermind.Era1/EraStore.cs @@ -43,8 +43,8 @@ public class EraStore : IEraStore private int LastEpoch { get; set; } private int FirstEpoch { get; set; } = int.MaxValue; - private long? _firstBlock = null; - public long FirstBlock + private ulong? _firstBlock = null; + public ulong FirstBlock { get { @@ -57,10 +57,10 @@ public long FirstBlock } } - private long? _lastBlock = null; + private ulong? _lastBlock = null; private readonly int _verifyConcurrency; - public long LastBlock + public ulong LastBlock { get { @@ -118,10 +118,11 @@ public EraStore( } } - private long GetEpochNumber(long blockNumber) + private long GetEpochNumber(ulong blockNumber) { // This seems to be the geth way of encoding blocks. - long epochOffset = (blockNumber - FirstBlock) / _maxEraFile; + // Cast to long is safe here: epoch numbers are small integers well within long range. + long epochOffset = (long)((blockNumber - FirstBlock) / (ulong)_maxEraFile); return FirstEpoch + epochOffset; } @@ -163,17 +164,15 @@ private async ValueTask EnsureEpochVerified(long epoch, EraReader reader, Cancel } } - public long NextEraStart(long blockNumber) + public ulong NextEraStart(ulong blockNumber) { long epoch = GetEpochNumber(blockNumber); using EraRenter _ = RentReader(epoch, out EraReader reader); return reader.LastBlock + 1; } - public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(long number, bool ensureValidated = true, CancellationToken cancellation = default) + public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(ulong number, bool ensureValidated = true, CancellationToken cancellation = default) { - ThrowIfNegative(number); - long partOfEpoch = GetEpochNumber(number); if (!_epochs.ContainsKey(partOfEpoch)) return (null, null); @@ -227,14 +226,6 @@ private void ReturnReader(long epoch, EraReader reader) reader.Dispose(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ThrowIfNegative(long number) - { - if (number < 0) - throw new ArgumentOutOfRangeException(nameof(number), number, "Cannot be negative."); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GuardMissingEpoch(long epoch) { diff --git a/src/Nethermind/Nethermind.Era1/EraWriter.cs b/src/Nethermind/Nethermind.Era1/EraWriter.cs index 9facbbac375d..e1a8b0956f2d 100644 --- a/src/Nethermind/Nethermind.Era1/EraWriter.cs +++ b/src/Nethermind/Nethermind.Era1/EraWriter.cs @@ -62,7 +62,7 @@ public async Task Add(Block block, TxReceipt[] receipts, CancellationToken cance if (_firstBlock) { - _startNumber = block.Number; + _startNumber = (long)block.Number; _totalWritten += await WriteVersion(); _firstBlock = false; } diff --git a/src/Nethermind/Nethermind.Era1/IAdminEraService.cs b/src/Nethermind/Nethermind.Era1/IAdminEraService.cs index a366270cc1ae..ec659543167b 100644 --- a/src/Nethermind/Nethermind.Era1/IAdminEraService.cs +++ b/src/Nethermind/Nethermind.Era1/IAdminEraService.cs @@ -5,6 +5,6 @@ namespace Nethermind.Era1; public interface IAdminEraService { - string ExportHistory(string destination, long from, long to); - string ImportHistory(string source, long from, long to, string? accumulatorFile); + string ExportHistory(string destination, ulong from, ulong to); + string ImportHistory(string source, ulong from, ulong to, string? accumulatorFile); } diff --git a/src/Nethermind/Nethermind.Era1/IEraConfig.cs b/src/Nethermind/Nethermind.Era1/IEraConfig.cs index 34377127f615..473138cf6b54 100644 --- a/src/Nethermind/Nethermind.Era1/IEraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/IEraConfig.cs @@ -14,10 +14,10 @@ public interface IEraConfig : IConfig string? ExportDirectory { get; set; } [ConfigItem(Description = "Block number to import/export from.", DefaultValue = "0", HiddenFromDocs = false)] - long From { get; set; } + ulong From { get; set; } [ConfigItem(Description = "Block number to import/export to.", DefaultValue = "0", HiddenFromDocs = false)] - long To { get; set; } + ulong To { get; set; } [ConfigItem(Description = "Accumulator file to be used for trusting era files.", DefaultValue = "null", HiddenFromDocs = false)] string? TrustedAccumulatorFile { get; set; } diff --git a/src/Nethermind/Nethermind.Era1/IEraExporter.cs b/src/Nethermind/Nethermind.Era1/IEraExporter.cs index 196c7be18f9e..37962c3c8c18 100644 --- a/src/Nethermind/Nethermind.Era1/IEraExporter.cs +++ b/src/Nethermind/Nethermind.Era1/IEraExporter.cs @@ -5,5 +5,5 @@ namespace Nethermind.Era1; public interface IEraExporter { - Task Export(string destinationPath, long from, long to, CancellationToken cancellation = default); + Task Export(string destinationPath, ulong from, ulong to, CancellationToken cancellation = default); } diff --git a/src/Nethermind/Nethermind.Era1/IEraImporter.cs b/src/Nethermind/Nethermind.Era1/IEraImporter.cs index 5692b4fea800..d32bf9e5f696 100644 --- a/src/Nethermind/Nethermind.Era1/IEraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/IEraImporter.cs @@ -5,5 +5,5 @@ namespace Nethermind.Era1; public interface IEraImporter { - Task Import(string src, long from, long to, string? accumulatorFile = null, CancellationToken cancellation = default); + Task Import(string src, ulong from, ulong to, string? accumulatorFile = null, CancellationToken cancellation = default); } diff --git a/src/Nethermind/Nethermind.Era1/IEraStore.cs b/src/Nethermind/Nethermind.Era1/IEraStore.cs index 17d736e81975..00acd07bbefb 100644 --- a/src/Nethermind/Nethermind.Era1/IEraStore.cs +++ b/src/Nethermind/Nethermind.Era1/IEraStore.cs @@ -13,11 +13,11 @@ namespace Nethermind.Era1; ///
public interface IEraStore : IDisposable { - Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(long number, bool ensureValidated = true, CancellationToken cancellation = default); - long LastBlock { get; } - long FirstBlock { get; } + Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(ulong number, bool ensureValidated = true, CancellationToken cancellation = default); + ulong LastBlock { get; } + ulong FirstBlock { get; } /// Used for optimization where multiple tasks should not read on the same era file. /// Ideally not necessary in the future. - long NextEraStart(long blockNumber); + ulong NextEraStart(ulong blockNumber); } diff --git a/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs b/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs index ac20b4cba2b7..f314e16879b4 100644 --- a/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs +++ b/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs @@ -7,7 +7,7 @@ namespace Nethermind.Era1.JsonRpc; public class EraAdminRpcModule(IAdminEraService eraService) : IEraAdminRpcModule { - public Task> admin_exportHistory(string destination, int start = 0, int end = 0) => ResultWrapper.Success(eraService.ExportHistory(destination, start, end)); + public Task> admin_exportHistory(string destination, int start = 0, int end = 0) => ResultWrapper.Success(eraService.ExportHistory(destination, (ulong)start, (ulong)end)); - public Task> admin_importHistory(string source, int start = 0, int end = 0, string? accumulatorFile = null) => ResultWrapper.Success(eraService.ImportHistory(source, start, end, accumulatorFile)); + public Task> admin_importHistory(string source, int start = 0, int end = 0, string? accumulatorFile = null) => ResultWrapper.Success(eraService.ImportHistory(source, (ulong)start, (ulong)end, accumulatorFile)); } diff --git a/src/Nethermind/Nethermind.EraE.Test/Archive/AccumulatorCalculatorTests.cs b/src/Nethermind/Nethermind.EraE.Test/Archive/AccumulatorCalculatorTests.cs index ed7db259154e..a64a108596d6 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Archive/AccumulatorCalculatorTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Archive/AccumulatorCalculatorTests.cs @@ -77,18 +77,18 @@ public void GetProof_WhenCalled_Returns15Elements() Assert.That(sut.GetProof(0), Has.Length.EqualTo(15)); } - [TestCase(0)] - [TestCase(1)] - [TestCase(7)] - public void GetProof_WhenCalled_ProofZeroIsTotalDifficultyLE(int blockIndex) + [TestCase(0U)] + [TestCase(1U)] + [TestCase(7U)] + public void GetProof_WhenCalled_ProofZeroIsTotalDifficultyLE(uint blockIndex) { using AccumulatorCalculator sut = new(); - for (int i = 0; i <= blockIndex; i++) - sut.Add(Keccak.Zero, (ulong)(i + 1)); + for (uint i = 0; i <= blockIndex; i++) + sut.Add(Keccak.Zero, i + 1); byte[] expected = new byte[32]; expected[0] = (byte)(blockIndex + 1); - Assert.That(sut.GetProof(blockIndex)[0].ToByteArray(), Is.EqualTo(expected)); + Assert.That(sut.GetProof((int)blockIndex)[0].ToByteArray(), Is.EqualTo(expected)); } [Test] diff --git a/src/Nethermind/Nethermind.EraE.Test/Archive/EraReaderTests.cs b/src/Nethermind/Nethermind.EraE.Test/Archive/EraReaderTests.cs index cf33130c53f0..36dad4ba4005 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Archive/EraReaderTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Archive/EraReaderTests.cs @@ -14,15 +14,15 @@ namespace Nethermind.EraE.Test.Archive; internal class EraReaderTests { - [TestCase(3, 0)] - [TestCase(0, 3)] - public async Task GetBlockByNumber_ReturnsCorrectBlockNumbers(int preMergeCount, int postMergeCount) + [TestCase(3U, 0U)] + [TestCase(0U, 3U)] + public async Task GetBlockByNumber_ReturnsCorrectBlockNumbers(uint preMergeCount, uint postMergeCount) { - int totalCount = preMergeCount + postMergeCount; + ulong totalCount = preMergeCount + postMergeCount; using TestEraFile file = await TestEraFile.Create(preMergeCount: preMergeCount, postMergeCount: postMergeCount); using EraReader sut = new(file.FilePath); - for (int i = 0; i < totalCount; i++) + for (ulong i = 0; i < totalCount; i++) { (Block block, _) = await sut.GetBlockByNumber(i); Assert.That(block.Number, Is.EqualTo(i)); @@ -35,7 +35,7 @@ public async Task GetBlockByNumber_InPreMergeEpoch_TotalDifficultyIsRestored() using TestEraFile file = await TestEraFile.Create(preMergeCount: 3, postMergeCount: 0); using EraReader sut = new(file.FilePath); - (Block block, _) = await sut.GetBlockByNumber(2); + (Block block, _) = await sut.GetBlockByNumber(2UL); Assert.That(block.TotalDifficulty, Is.EqualTo(file.Contents[2].Block.TotalDifficulty)); } @@ -118,7 +118,7 @@ public async Task GetBlockByNumber_InTransitionEpoch_FirstPostMergeBlockHasIsPos using TestEraFile file = await TestEraFile.Create(preMergeCount: 2, postMergeCount: 2); using EraReader sut = new(file.FilePath); - (Block postMergeBlock, _) = await sut.GetBlockByNumber(2); + (Block postMergeBlock, _) = await sut.GetBlockByNumber(2UL); Assert.That(postMergeBlock.Header.IsPostMerge, Is.True); } @@ -128,7 +128,7 @@ public async Task GetBlockByNumber_WithBelowRangeNumber_ThrowsArgumentOutOfRange using TestEraFile file = await TestEraFile.Create(preMergeCount: 2, postMergeCount: 0); using EraReader sut = new(file.FilePath); - Assert.That(async () => await sut.GetBlockByNumber(-1), Throws.TypeOf()); + Assert.That(async () => await sut.GetBlockByNumber(ulong.MaxValue), Throws.TypeOf()); } [Test] @@ -137,7 +137,7 @@ public async Task GetBlockByNumber_WithAboveRangeNumber_ThrowsArgumentOutOfRange using TestEraFile file = await TestEraFile.Create(preMergeCount: 2, postMergeCount: 0); using EraReader sut = new(file.FilePath); - Assert.That(async () => await sut.GetBlockByNumber(999), Throws.TypeOf()); + Assert.That(async () => await sut.GetBlockByNumber(999UL), Throws.TypeOf()); } [Test] @@ -146,7 +146,7 @@ public async Task GetBlockByNumber_WithSlimEncodedReceipts_BloomIsReconstructedF using TestEraFile file = await TestEraFile.Create(preMergeCount: 1, postMergeCount: 0); using EraReader sut = new(file.FilePath); - (_, TxReceipt[] receipts) = await sut.GetBlockByNumber(0); + (_, TxReceipt[] receipts) = await sut.GetBlockByNumber(0UL); Assert.That(receipts, Is.Not.Empty); Assert.That(receipts[0].Bloom, Is.Not.Null, "bloom must be auto-computed from logs"); diff --git a/src/Nethermind/Nethermind.EraE.Test/Archive/EraWriterTests.cs b/src/Nethermind/Nethermind.EraE.Test/Archive/EraWriterTests.cs index e7fe792b434b..f7b92b9bdc03 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Archive/EraWriterTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Archive/EraWriterTests.cs @@ -87,7 +87,7 @@ public async Task Add_WhenExceedingMaxEraSize_ThrowsArgumentException() { using EraWriter sut = CreateSut(); - for (int i = 0; i < EraWriter.MaxEraSize; i++) + for (ulong i = 0; i < EraWriter.MaxEraSize; i++) { Block block = Build.A.Block.WithNumber(i).WithTotalDifficulty(BlockHeaderBuilder.DefaultDifficulty).TestObject; await sut.Add(block, []); diff --git a/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs b/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs index 1091101b89b5..608f560b112d 100644 --- a/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs +++ b/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs @@ -61,7 +61,7 @@ public static ContainerBuilder BuildContainerBuilderWithPostMergeBlockTreeOfLeng // Post-merge blocks have TotalDifficulty=0, which never satisfies // HeadImprovementRequirementsSatisfied (0 < MainnetTTD). Force-update head // so the exporter can resolve blockTree.Head correctly. - Block? lastBlock = blockTreeBuilder.BlockTree.FindBlock(length - 1, BlockTreeLookupOptions.None); + Block? lastBlock = blockTreeBuilder.BlockTree.FindBlock((ulong)(length - 1), BlockTreeLookupOptions.None); if (lastBlock is not null) blockTreeBuilder.BlockTree.UpdateMainChain(new[] { lastBlock }, true, forceUpdateHeadBlock: true); }); @@ -71,7 +71,7 @@ public static ContainerBuilder BuildContainerBuilderWithPostMergeBlockTreeOfLeng public static ManualTimestamper PostMerge => new(DateTimeOffset.FromUnixTimeSeconds((long)PostMergeGenesisTimestamp).UtcDateTime); - public static async Task CreateExportedEraEnv(int chainLength = 512, long from = 0, long to = 0) + public static async Task CreateExportedEraEnv(int chainLength = 512, ulong from = 0, ulong to = 0) { IContainer testCtx = BuildContainerBuilderWithBlockTreeOfLength(chainLength).Build(); await testCtx.Resolve().Export(testCtx.ResolveTempDirPath(), from, to); @@ -82,7 +82,7 @@ public static async Task CreateExportedPostMergeEraEnv(int chainLeng { IContainer testCtx = BuildContainerBuilderWithPostMergeBlockTreeOfLength(chainLength).Build(); // Start from block 1: genesis is pre-merge in all block trees. - await testCtx.Resolve().Export(testCtx.ResolveTempDirPath(), from: 1, to: 0); + await testCtx.Resolve().Export(testCtx.ResolveTempDirPath(), from: 1UL, to: 0UL); return testCtx; } diff --git a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs index 8cc4c7e47147..e38c79bae40e 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs @@ -18,13 +18,13 @@ namespace Nethermind.EraE.Test.Export; public class EraExporterTests { - [TestCase(1, 0, 0, 1, 1)] - [TestCase(3, 0, 2, 1, 3)] - [TestCase(16, 0, 15, 16, 1)] - [TestCase(32, 0, 31, 16, 2)] - [TestCase(48, 8, 39, 16, 3)] + [TestCase(1, 0UL, 0UL, 1, 1)] + [TestCase(3, 0UL, 2UL, 1, 3)] + [TestCase(16, 0UL, 15UL, 16, 1)] + [TestCase(32, 0UL, 31UL, 16, 2)] + [TestCase(48, 8UL, 39UL, 16, 3)] public async Task Export_WithVaryingChainLength_CreatesCorrectNumberOfEpochFiles( - int chainLength, int from, int to, int eraSize, int expectedEraFiles) + int chainLength, ulong from, ulong to, int eraSize, int expectedEraFiles) { await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(chainLength) .AddSingleton(new EraEConfig @@ -51,7 +51,7 @@ public async Task Export_WhenCalled_CreatesMetadataFile(string fileName) await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(32).Build(); string tmpDirectory = container.ResolveTempDirPath(); - await container.Resolve().Export(tmpDirectory, 0, 0); + await container.Resolve().Export(tmpDirectory, 0UL, 0UL); Assert.That(System.IO.File.Exists(System.IO.Path.Combine(tmpDirectory, fileName)), Is.True); } @@ -62,7 +62,7 @@ public async Task Export_WhenCalled_ChecksumsFileHasCorrectFormat() await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(32).Build(); string tmpDirectory = container.ResolveTempDirPath(); - await container.Resolve().Export(tmpDirectory, 0, 0); + await container.Resolve().Export(tmpDirectory, 0UL, 0UL); string[] lines = await System.IO.File.ReadAllLinesAsync( System.IO.Path.Combine(tmpDirectory, EraExporter.ChecksumsSHA256FileName)); @@ -82,7 +82,7 @@ public async Task Export_WhenCalled_EraFilesHaveCorrectExtension() await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(16).Build(); string tmpDirectory = container.ResolveTempDirPath(); - await container.Resolve().Export(tmpDirectory, 0, 0); + await container.Resolve().Export(tmpDirectory, 0UL, 0UL); string[] eraFiles = System.IO.Directory.GetFiles(tmpDirectory, $"*{EraPathUtils.FileExtension}"); Assert.That(eraFiles, Is.Not.Empty); @@ -100,7 +100,7 @@ public async Task Export_WithToExceedingHeadBlock_ThrowsArgumentException() string tmpDirectory = container.ResolveTempDirPath(); IEraExporter sut = container.Resolve(); - Assert.That(() => sut.Export(tmpDirectory, 0, 999), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 0UL, 999UL), Throws.TypeOf()); } [Test] @@ -111,7 +111,7 @@ public async Task Export_WithFromExceedingTo_ThrowsArgumentException() string tmpDirectory = container.ResolveTempDirPath(); IEraExporter sut = container.Resolve(); - Assert.That(() => sut.Export(tmpDirectory, 20, 10), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 20UL, 10UL), Throws.TypeOf()); } [Test] @@ -128,7 +128,7 @@ public async Task Export_WhenReceiptsStorageReturnsNull_ThrowsEraException() IEraExporter sut = container.Resolve(); string tmpDirectory = container.ResolveTempDirPath(); - Assert.That(() => sut.Export(tmpDirectory, 0, 1), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 0UL, 1UL), Throws.TypeOf()); } [Test] @@ -138,7 +138,7 @@ public async Task Export_WithToZero_ExportsUpToHead() await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(chainLength).Build(); string tmpDirectory = container.ResolveTempDirPath(); - await container.Resolve().Export(tmpDirectory, 0, to: 0); + await container.Resolve().Export(tmpDirectory, 0UL, to: 0UL); string[] eraFiles = System.IO.Directory.GetFiles(tmpDirectory, $"*{EraPathUtils.FileExtension}"); Assert.That(eraFiles, Is.Not.Empty, "exporting to 0 should default to head"); @@ -153,7 +153,7 @@ public void Export_WithDestinationAsExistingFile_ThrowsArgumentException() System.IO.File.WriteAllText(tmpFile, "existing"); IEraExporter sut = container.Resolve(); - Assert.That(() => sut.Export(tmpFile, 0, 0), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpFile, 0UL, 0UL), Throws.TypeOf()); } [Test] @@ -164,7 +164,7 @@ public async Task Export_WithPostMergeChain_ProducesEpochWithNoTdProofOrAccumula string tmpDirectory = container.ResolveTempDirPath(); // Export from block 1: genesis is pre-merge in all block trees, so starting at 1 ensures a pure post-merge epoch. - await container.Resolve().Export(tmpDirectory, 1, 0); + await container.Resolve().Export(tmpDirectory, 1UL, 0UL); string[] eraFiles = Directory.GetFiles(tmpDirectory, $"*{EraPathUtils.FileExtension}"); Assert.That(eraFiles, Has.Length.EqualTo(1), "one epoch for blocks 1-15"); @@ -190,7 +190,7 @@ public void Export_WhenLastBlockBodyNotAvailable_ThrowsInvalidOperationException string tmpDirectory = container.ResolveTempDirPath(); IEraExporter sut = container.Resolve(); - Assert.That(() => sut.Export(tmpDirectory, 0, 10), Throws.TypeOf()); + Assert.That(() => sut.Export(tmpDirectory, 0UL, 10UL), Throws.TypeOf()); } [Test] @@ -201,7 +201,7 @@ public async Task Export_WithPartialRange_CreatesOnlyEpochsInRange() .Build(); string tmpDirectory = container.ResolveTempDirPath(); - await container.Resolve().Export(tmpDirectory, 16, 31); + await container.Resolve().Export(tmpDirectory, 16UL, 31UL); string[] eraFiles = System.IO.Directory.GetFiles(tmpDirectory, $"*{EraPathUtils.FileExtension}"); Assert.That(eraFiles.Length, Is.EqualTo(1), "only one epoch covers blocks 16-31"); diff --git a/src/Nethermind/Nethermind.EraE.Test/Import/EraImporterTests.cs b/src/Nethermind/Nethermind.EraE.Test/Import/EraImporterTests.cs index ac793fc37483..86d014cbc585 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Import/EraImporterTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Import/EraImporterTests.cs @@ -40,9 +40,9 @@ public async Task Import_WithValidEraFiles_ImportsAllBlocksIntoTree() const int chainLength = 32; await using ImportEnvironment env = await CreateImportEnvironment(chainLength); - await env.Sut.Import(env.ExportPath, 0, long.MaxValue, null); + await env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null); - for (long i = 1; i < chainLength; i++) + for (ulong i = 1; i < chainLength; i++) { Assert.That(env.TargetTree.FindBlock(i, BlockTreeLookupOptions.None), Is.Not.Null, $"block {i} should have been imported"); } @@ -55,7 +55,7 @@ public async Task Import_WithTrustedAccumulators_Succeeds() string accumulatorPath = System.IO.Path.Combine(env.ExportPath, EraExporter.AccumulatorFileName); Assert.That( - () => env.Sut.Import(env.ExportPath, 0, long.MaxValue, accumulatorPath), + () => env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, accumulatorPath), Throws.Nothing); } @@ -71,7 +71,7 @@ public async Task Import_WithModifiedChecksum_ThrowsEraVerificationException() await System.IO.File.WriteAllLinesAsync(checksumPath, lines); Assert.That( - () => env.Sut.Import(env.ExportPath, 0, long.MaxValue, null), + () => env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null), Throws.TypeOf()); } @@ -90,7 +90,7 @@ public async Task Import_WithWrongTrustedAccumulator_ThrowsEraVerificationExcept await System.IO.File.WriteAllLinesAsync(fakeAccumulatorPath, fakeLines); Assert.That( - () => env.Sut.Import(env.ExportPath, 0, long.MaxValue, fakeAccumulatorPath), + () => env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, fakeAccumulatorPath), Throws.TypeOf()); } @@ -101,7 +101,7 @@ public async Task Import_WithPartialRange_ImportsOnlyRequestedBlocks() await env.Sut.Import(env.ExportPath, 0, 15, null); - for (long i = 1; i <= 15; i++) + for (ulong i = 1; i <= 15; i++) Assert.That(env.TargetTree.FindBlock(i, BlockTreeLookupOptions.None), Is.Not.Null, $"block {i} should have been imported"); Assert.That(env.TargetTree.FindBlock(16, BlockTreeLookupOptions.None), Is.Null, "block 16 is outside the requested range"); @@ -112,9 +112,9 @@ public async Task Import_WhenCalledTwice_DoesNotThrowAndIsIdempotent() { await using ImportEnvironment env = await CreateImportEnvironment(); - await env.Sut.Import(env.ExportPath, 0, long.MaxValue, null); + await env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null); - Assert.That(() => env.Sut.Import(env.ExportPath, 0, long.MaxValue, null), Throws.Nothing, + Assert.That(() => env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null), Throws.Nothing, "re-importing the same range must be idempotent"); } @@ -128,12 +128,12 @@ public async Task ExportThenImport_RoundTrip_BlocksAndReceiptsMatchOriginal() IReceiptStorage sourceReceipts = env.SourceCtx.Resolve(); - await env.Sut.Import(env.ExportPath, 0, long.MaxValue, null); + await env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null); IReceiptStorage targetReceipts = env.TargetCtx.Resolve(); IBlockTree sourceTree = env.SourceCtx.Resolve(); - for (long i = 1; i < chainLength; i++) + for (ulong i = 1; i < chainLength; i++) { Block? original = sourceTree.FindBlock(i, BlockTreeLookupOptions.None); Block? imported = env.TargetTree.FindBlock(i, BlockTreeLookupOptions.None); @@ -165,12 +165,12 @@ public async Task ExportThenImport_PostMergeRoundTrip_BlocksAndReceiptsMatchOrig .AddSingleton(new SyncConfig { FastSync = true }) .Build(); - await targetCtx.Resolve().Import(exportPath, 0, long.MaxValue, null); + await targetCtx.Resolve().Import(exportPath, 0, ulong.MaxValue, null); IReceiptStorage sourceReceipts = sourceCtx.Resolve(); IReceiptStorage targetReceipts = targetCtx.Resolve(); - for (long i = 1; i < chainLength; i++) + for (ulong i = 1; i < chainLength; i++) { Block? original = sourceTree.FindBlock(i, BlockTreeLookupOptions.None); Block? imported = targetTree.FindBlock(i, BlockTreeLookupOptions.None); @@ -200,7 +200,7 @@ public async Task Import_WhenBlocksPrePopulatedWithoutTotalDifficulty_SetsCorrec .WithBlocks(sourceTree.FindBlock(0, BlockTreeLookupOptions.None)!) .TestObject; - for (long i = 1; i < chainLength; i++) + for (ulong i = 1; i < chainLength; i++) { Block block = sourceTree.FindBlock(i, BlockTreeLookupOptions.TotalDifficultyNotNeeded)!; targetTree.Insert(block, @@ -212,9 +212,9 @@ public async Task Import_WhenBlocksPrePopulatedWithoutTotalDifficulty_SetsCorrec .AddSingleton(targetTree) .Build(); - await targetCtx.Resolve().Import(exportPath, 0, long.MaxValue, null); + await targetCtx.Resolve().Import(exportPath, 0, ulong.MaxValue, null); - for (long i = 1; i < chainLength; i++) + for (ulong i = 1; i < chainLength; i++) { Block? imported = targetTree.FindBlock(i, BlockTreeLookupOptions.None); Assert.That(imported, Is.Not.Null, $"block {i} should exist"); @@ -229,7 +229,7 @@ public async Task Import_WhenBlockFailsValidation_ThrowsEraVerificationException configure: b => b.AddSingleton(Always.Invalid)); Assert.That( - () => env.Sut.Import(env.ExportPath, 0, long.MaxValue, null), + () => env.Sut.Import(env.ExportPath, 0, ulong.MaxValue, null), Throws.TypeOf()); } diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/EraStoreTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/EraStoreTests.cs index 23f1dbb2b067..d39154dccfde 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/EraStoreTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/EraStoreTests.cs @@ -14,10 +14,10 @@ namespace Nethermind.EraE.Test.Store; public class EraStoreTests { - [TestCase(100, 16, 32)] - [TestCase(100, 16, 64)] - [TestCase(200, 50, 100)] - public async Task FirstAndLastBlock_AfterExport_MatchSpecifiedRange(int chainLength, int from, int to) + [TestCase(100, 16UL, 32UL)] + [TestCase(100, 16UL, 64UL)] + [TestCase(200, 50UL, 100UL)] + public async Task FirstAndLastBlock_AfterExport_MatchSpecifiedRange(int chainLength, ulong from, ulong to) { await using IContainer ctx = await EraETestModule.CreateExportedEraEnv(chainLength, from, to); string tmpDirectory = ctx.ResolveTempDirPath(); @@ -55,20 +55,21 @@ public async Task FindBlockAndReceipts_WithValidBlockNumber_ReturnsCorrectBlock( { await using EraStoreEnv env = await CreateDefaultEraStoreEnv(); - long targetBlock = env.EraStore.BlockRange.First + 5; + ulong targetBlock = env.EraStore.BlockRange.First + 5; (Block? block, _) = await env.EraStore.FindBlockAndReceipts(targetBlock, ensureValidated: false); Assert.That(block!.Number, Is.EqualTo(targetBlock)); } [Test] - public async Task FindBlockAndReceipts_WithNegativeBlockNumber_ThrowsArgumentOutOfRangeException() + public async Task FindBlockAndReceipts_WithHugeBlockNumber_ReturnsNull() { await using EraStoreEnv env = await CreateDefaultEraStoreEnv(); - Assert.That( - async () => await env.EraStore.FindBlockAndReceipts(-1, ensureValidated: false), - Throws.TypeOf()); + (Block? block, TxReceipt[]? receipts) = await env.EraStore.FindBlockAndReceipts(ulong.MaxValue, ensureValidated: false); + + Assert.That(block, Is.Null); + Assert.That(receipts, Is.Null); } [Test] @@ -87,7 +88,7 @@ public async Task NextEraStart_WhenCalled_ReturnsCorrectBoundary() string tmpDirectory = ctx.ResolveTempDirPath(); using IEraStore eraStore = ctx.Resolve().Create(tmpDirectory, null); - long nextStart = eraStore.NextEraStart(eraStore.BlockRange.First); + ulong nextStart = eraStore.NextEraStart(eraStore.BlockRange.First); Assert.That(nextStart, Is.EqualTo(eraSize), "first era covers blocks 0..eraSize-1"); } diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs index e7b56854aa07..6d2eeae4e8f5 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs @@ -41,7 +41,7 @@ public async Task FindBlockAndReceipts_WhenEpochMissingLocally_DownloadsAndRetur using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16); - (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts(epoch * 16, ensureValidated: false); + (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: false); Assert.That(block, Is.Not.Null); Assert.That(receipts, Is.Not.Null); @@ -71,7 +71,7 @@ public async Task FindBlockAndReceipts_WhenLocalStoreReturnsBlock_SkipsRemoteCli public async Task FindBlockAndReceipts_WhenEpochAbsentFromManifest_ThrowsEraException() { IEraStore localStore = Substitute.For(); - localStore.FindBlockAndReceipts(Arg.Any(), Arg.Any(), Arg.Any()) + localStore.FindBlockAndReceipts(Arg.Any(), Arg.Any(), Arg.Any()) .Returns((null, null)); _client.FetchManifestAsync(Arg.Any()) @@ -79,7 +79,7 @@ public async Task FindBlockAndReceipts_WhenEpochAbsentFromManifest_ThrowsEraExce using RemoteEraStoreDecorator sut = CreateDecorator(localStore, maxEraSize: 16); - Assert.That(async () => await sut.FindBlockAndReceipts(5, ensureValidated: false), + Assert.That(async () => await sut.FindBlockAndReceipts(5UL, ensureValidated: false), Throws.TypeOf().With.Message.Contains("Epoch 0").And.Message.Contains("not available")); } @@ -101,7 +101,7 @@ public async Task FindBlockAndReceipts_WhenDownloadedFileHasWrongChecksum_Throws string expectedFilePath = Path.Join(_downloadDir.Path, filename); using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16); - Assert.That(async () => await sut.FindBlockAndReceipts(0, ensureValidated: false), Throws.TypeOf().With.Message.Contains(@"SHA-256")); + Assert.That(async () => await sut.FindBlockAndReceipts(0UL, ensureValidated: false), Throws.TypeOf().With.Message.Contains(@"SHA-256")); Assert.That(File.Exists(expectedFilePath), Is.False); } @@ -124,14 +124,14 @@ public async Task FindBlockAndReceipts_WhenEnsureValidated_EnforcesContentTrust( if (contentValid && accumulatorTrusted) { - (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts(epoch * 16); + (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts((ulong)epoch * 16); Assert.That(block, Is.Not.Null); Assert.That(receipts, Is.Not.Null); Assert.That(block!.Number, Is.EqualTo(epoch * 16)); } else { - Assert.That(async () => await sut.FindBlockAndReceipts(epoch * 16), Throws.TypeOf()); + Assert.That(async () => await sut.FindBlockAndReceipts((ulong)epoch * 16), Throws.TypeOf()); // Rejected content caches nothing: the file is removed so a retry re-downloads. Assert.That(File.Exists(Path.Join(_downloadDir.Path, filename)), Is.False); } @@ -149,12 +149,12 @@ public async Task FindBlockAndReceipts_WhenUnvalidatedReadPrecedesValidatedRead_ using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16, ctx.Resolve(), blockValidator); // An unvalidated read caches availability only and must not run content validation. - await sut.FindBlockAndReceipts(epoch * 16, ensureValidated: false); + await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: false); blockValidator.DidNotReceiveWithAnyArgs().ValidateBodyAgainstHeader(default!, default!, out Arg.Any()); // A later validated read on the same epoch must still run VerifyContent — the availability // cache alone cannot satisfy it. - await sut.FindBlockAndReceipts(epoch * 16, ensureValidated: true); + await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: true); blockValidator.ReceivedWithAnyArgs().ValidateBodyAgainstHeader(default!, default!, out Arg.Any()); } @@ -194,7 +194,7 @@ public async Task FindBlockAndReceipts_WhenManifestFilenameEscapesDownloadDir_Th string escapedPath = Path.GetFullPath(Path.Join(_downloadDir.Path, filename)); using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16); - Assert.That(async () => await sut.FindBlockAndReceipts(0, ensureValidated: false), Throws.TypeOf().With.Message.Contains("escapes the download directory")); + Assert.That(async () => await sut.FindBlockAndReceipts(0UL, ensureValidated: false), Throws.TypeOf().With.Message.Contains("escapes the download directory")); await _client.DidNotReceive().DownloadFileAsync(Arg.Any(), Arg.Any(), Arg.Any()); Assert.That(File.Exists(escapedPath), Is.False); diff --git a/src/Nethermind/Nethermind.EraE.Test/TestEraFile.cs b/src/Nethermind/Nethermind.EraE.Test/TestEraFile.cs index cf1e81bdae30..2c2bd844a252 100644 --- a/src/Nethermind/Nethermind.EraE.Test/TestEraFile.cs +++ b/src/Nethermind/Nethermind.EraE.Test/TestEraFile.cs @@ -23,8 +23,8 @@ internal sealed class TestEraFile : IDisposable private TestEraFile(TempPath tmpFile) => _tmpFile = tmpFile; public static async Task Create( - int preMergeCount, - int postMergeCount, + uint preMergeCount, + uint postMergeCount, ISpecProvider? specProvider = null) { specProvider ??= MainnetSpecProvider.Instance; @@ -33,10 +33,10 @@ public static async Task Create( TestEraFile file = new(tmpFile); HeaderDecoder headerDecoder = new(); - long number = 0; + ulong number = 0; UInt256 td = BlockHeaderBuilder.DefaultDifficulty; - for (int i = 0; i < preMergeCount; i++, number++, td += BlockHeaderBuilder.DefaultDifficulty) + for (uint i = 0; i < preMergeCount; i++, number++, td += BlockHeaderBuilder.DefaultDifficulty) { TxReceipt receipt = Build.A.Receipt.WithTxType(TxType.EIP1559).TestObject; Block block = Build.A.Block.WithNumber(number).WithTotalDifficulty(td).TestObject; @@ -47,7 +47,7 @@ public static async Task Create( await writer.Add(block, [receipt]); } - for (int i = 0; i < postMergeCount; i++, number++) + for (uint i = 0; i < postMergeCount; i++, number++) { TxReceipt receipt = Build.A.Receipt.WithTxType(TxType.EIP1559).TestObject; Block block = Build.A.Block.WithNumber(number).WithPostMergeRules().TestObject; diff --git a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs index e4aebd3d6db2..78b3721e60bc 100644 --- a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs +++ b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs @@ -25,7 +25,7 @@ public ResultWrapper ExportHistory(string destination, long from, long t return ResultWrapper.Fail("An export job is already running."); _ = EraJobRunner.RunProtected( - ct => eraExporter.Export(destination, from, to, ct), + ct => eraExporter.Export(destination, (ulong)from, (ulong)to, ct), $"EraE export was cancelled. Archives in '{destination}' may be incomplete.", "EraE export error", _logger, @@ -41,7 +41,7 @@ public ResultWrapper ImportHistory(string source, long from, long to, st return ResultWrapper.Fail("An import job is already running."); _ = EraJobRunner.RunProtected( - ct => eraImporter.Import(source, from, to, accumulatorFile, ct), + ct => eraImporter.Import(source, (ulong)from, (ulong)to, accumulatorFile, ct), $"EraE import was cancelled. State from '{source}' may be incomplete.", "EraE import error", _logger, diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs index a6803f195874..81993d9820cc 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs @@ -25,25 +25,25 @@ public sealed class EraReader(E2StoreReader e2) : IAsyncEnumerable<(Block, TxRec private readonly BlockBodyDecoder _blockBodyDecoder = BlockBodyDecoder.Instance; private readonly HeaderDecoder _headerDecoder = new(); - public long FirstBlock => e2.First; - public long LastBlock => e2.LastBlock; + public ulong FirstBlock => (ulong)e2.First; + public ulong LastBlock => (ulong)e2.LastBlock; public EraReader(string fileName) : this(new E2StoreReader(fileName)) { } public async IAsyncEnumerator<(Block, TxReceipt[])> GetAsyncEnumerator(CancellationToken cancellation = default) { - for (long blockNumber = e2.First; blockNumber <= e2.LastBlock; blockNumber++) + for (ulong blockNumber = (ulong)e2.First; blockNumber <= (ulong)e2.LastBlock; blockNumber++) { (Block block, TxReceipt[] receipts) = await ReadBlockAndReceipts(blockNumber, cancellation); yield return (block, receipts); } } - public async Task<(Block, TxReceipt[])> GetBlockByNumber(long number, CancellationToken cancellation = default) + public async Task<(Block, TxReceipt[])> GetBlockByNumber(ulong number, CancellationToken cancellation = default) { - if (number < e2.First) + if (number < (ulong)e2.First) throw new ArgumentOutOfRangeException(nameof(number), $"Cannot be less than first block {e2.First}."); - if (number > e2.LastBlock) + if (number > (ulong)e2.LastBlock) throw new ArgumentOutOfRangeException(nameof(number), $"Cannot exceed last block {e2.LastBlock}."); return await ReadBlockAndReceipts(number, cancellation); @@ -77,14 +77,14 @@ public async Task VerifyContent( if (verifyConcurrency <= 0) verifyConcurrency = Environment.ProcessorCount; - long startBlock = e2.First; + ulong startBlock = (ulong)e2.First; int blockCount = (int)e2.BlockCount; (Hash256 Hash, UInt256 Td, bool IsPreMerge)[] blockMeta = new (Hash256 Hash, UInt256 Td, bool IsPreMerge)[blockCount]; - ConcurrentQueue blockNumbers = new(); - for (long n = startBlock; n <= e2.LastBlock; n++) + ConcurrentQueue blockNumbers = new(); + for (ulong n = startBlock; n <= (ulong)e2.LastBlock; n++) { blockNumbers.Enqueue(n); } @@ -94,7 +94,7 @@ public async Task VerifyContent( { workers[i] = Task.Run(async () => { - while (blockNumbers.TryDequeue(out long blockNumber)) + while (blockNumbers.TryDequeue(out ulong blockNumber)) { (Block block, TxReceipt[] receipts) = await ReadBlockAndReceipts(blockNumber, cancellation); @@ -107,7 +107,7 @@ public async Task VerifyContent( throw new EraVerificationException($"Mismatched receipt root at block {blockNumber}."); // Safe: each dequeued blockNumber is unique, so each idx is written by exactly one worker. - int idx = (int)(block.Header.Number - startBlock); + int idx = (int)(block.Header.Number - (ulong)startBlock); blockMeta[idx] = ( block.Header.Hash!, block.TotalDifficulty ?? UInt256.Zero, @@ -148,7 +148,7 @@ public async Task VerifyContent( public void Dispose() => e2.Dispose(); - private async Task<(Block, TxReceipt[])> ReadBlockAndReceipts(long blockNumber, CancellationToken cancellation) + private async Task<(Block, TxReceipt[])> ReadBlockAndReceipts(ulong blockNumber, CancellationToken cancellation) { long headerPos = e2.HeaderOffset(blockNumber); (BlockHeader header, _) = await e2.ReadSnappyCompressedEntryAndDecode( diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraSlimReceiptDecoder.cs b/src/Nethermind/Nethermind.EraE/Archive/EraSlimReceiptDecoder.cs index e3f56bd0439b..b55e043b48f3 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraSlimReceiptDecoder.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraSlimReceiptDecoder.cs @@ -64,7 +64,7 @@ private static TxReceipt DecodeSlimReceipt(ref Rlp.ValueDecoderContext ctx) $"Invalid slim receipt status encoding length: {statusBytes.Length}"); } - receipt.GasUsedTotal = ctx.DecodePositiveLong(); + receipt.GasUsedTotal = ctx.DecodeULong(); int logsLength = ctx.ReadSequenceLength(); int logsEnd = ctx.Position + logsLength; diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs b/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs index caa76e894c86..95f9ce17c92c 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs @@ -57,7 +57,7 @@ public sealed class EraWriter : IDisposable private readonly ArrayPoolList _totalDifficulties = new(MaxEraSize); - private long _startNumber; + private ulong _startNumber; private bool _firstBlock = true; private bool _finalized; private int _preMergeBlockCount; @@ -110,10 +110,10 @@ public async Task Add(Block block, TxReceipt[] receipts, CancellationToken cance _firstBlock = false; await _e2StoreWriter.WriteEntry(EntryTypes.Version, Memory.Empty, cancellation); } - else if (block.Number != _startNumber + _headers.Count) + else if (block.Number != _startNumber + (ulong)_headers.Count) { throw new ArgumentException( - $"Blocks must be added in sequential order. Expected block {_startNumber + _headers.Count}, got {block.Number}.", + $"Blocks must be added in sequential order. Expected block {_startNumber + (ulong)_headers.Count}, got {block.Number}.", nameof(block)); } @@ -239,7 +239,7 @@ await _e2StoreWriter.WriteEntry( using ArrayPoolList indexBytes = new(indexDataLength, indexDataLength); Span span = indexBytes.AsSpan(); - WriteInt64(span, 0, _startNumber); + WriteInt64(span, 0, (long)_startNumber); for (int i = 0; i < blockCount; i++) { diff --git a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs index 51db5abc1484..109f9dc20739 100644 --- a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs +++ b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs @@ -30,7 +30,7 @@ public sealed class E2StoreReader : IDisposable private readonly SafeFileHandle _file; private readonly long _fileLength; - private long _startBlock; + private ulong _startBlock; private long _blockCount; private int _componentCount; // 3 (post-merge) or 4 (pre-merge/transition) private bool _indexLoaded; @@ -42,7 +42,7 @@ public E2StoreReader(string filePath) _fileLength = RandomAccess.GetLength(_file); } - public long First + public ulong First { get { @@ -51,7 +51,7 @@ public long First } } - public long LastBlock => First + _blockCount - 1; + public ulong LastBlock => First + (ulong)_blockCount - 1; public long BlockCount { @@ -71,13 +71,13 @@ public bool HasTotalDifficulty } } - public long HeaderOffset(long blockNumber) => ComponentOffset(blockNumber, 0); + public long HeaderOffset(ulong blockNumber) => ComponentOffset(blockNumber, 0); - public long BodyOffset(long blockNumber) => ComponentOffset(blockNumber, 1); + public long BodyOffset(ulong blockNumber) => ComponentOffset(blockNumber, 1); - public long SlimReceiptsOffset(long blockNumber) => ComponentOffset(blockNumber, 2); + public long SlimReceiptsOffset(ulong blockNumber) => ComponentOffset(blockNumber, 2); - public long TotalDifficultyOffset(long blockNumber) + public long TotalDifficultyOffset(ulong blockNumber) { EnsureIndexLoaded(); if (_componentCount < ComponentsWithTotalDifficulty) @@ -179,20 +179,20 @@ private void EnsureIndexLoaded() _componentIndexTlvStart = indexEntryStart; // Read starting block number (first field of index data) - _startBlock = ReadInt64(indexEntryStart + EntryHeaderSize); + _startBlock = (ulong)ReadInt64(indexEntryStart + EntryHeaderSize); _indexLoaded = true; } - private long ComponentOffset(long blockNumber, int componentIdx) + private long ComponentOffset(ulong blockNumber, int componentIdx) { EnsureIndexLoaded(); - if (blockNumber < _startBlock || blockNumber >= _startBlock + _blockCount) - throw new ArgumentOutOfRangeException(nameof(blockNumber), $"Block {blockNumber} is outside range [{_startBlock}, {_startBlock + _blockCount - 1}]."); + if (blockNumber < _startBlock || blockNumber >= _startBlock + (ulong)_blockCount) + throw new ArgumentOutOfRangeException(nameof(blockNumber), $"Block {blockNumber} is outside range [{_startBlock}, {_startBlock + (ulong)_blockCount - 1}]."); ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(componentIdx, _componentCount); - long blockIdx = blockNumber - _startBlock; + long blockIdx = (long)(blockNumber - _startBlock); // Offset table starts at: indexEntryStart + EntryHeaderSize + IndexFieldSize (starting_number) long offsetFieldPos = _componentIndexTlvStart + EntryHeaderSize + IndexFieldSize + blockIdx * _componentCount * IndexFieldSize diff --git a/src/Nethermind/Nethermind.EraE/EraCliRunner.cs b/src/Nethermind/Nethermind.EraE/EraCliRunner.cs index 68718acbda8b..57ca1266228f 100644 --- a/src/Nethermind/Nethermind.EraE/EraCliRunner.cs +++ b/src/Nethermind/Nethermind.EraE/EraCliRunner.cs @@ -27,11 +27,11 @@ public async Task Run(CancellationToken token) "Either disable history pruning or remove the import directory."); } - await eraImporter.Import(eraConfig.ImportDirectory!, eraConfig.From, eraConfig.To, eraConfig.TrustedAccumulatorFile, token); + await eraImporter.Import(eraConfig.ImportDirectory!, (ulong)eraConfig.From, (ulong)eraConfig.To, eraConfig.TrustedAccumulatorFile, token); } else if (!string.IsNullOrEmpty(eraConfig.ExportDirectory)) { - await eraExporter.Export(eraConfig.ExportDirectory!, eraConfig.From, eraConfig.To, token); + await eraExporter.Export(eraConfig.ExportDirectory!, (ulong)eraConfig.From, (ulong)eraConfig.To, token); } } } diff --git a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs index fe400a9a23ae..a5f0cc768a63 100644 --- a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs +++ b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs @@ -46,13 +46,13 @@ public sealed class EraExporter( private const int ProgressLogInterval = 10000; private const int RetryDelayMs = 100; - public Task Export(string destinationPath, long from, long to, CancellationToken cancellation = default) + public Task Export(string destinationPath, ulong from, ulong to, CancellationToken cancellation = default) { if (fileSystem.File.Exists(destinationPath)) throw new ArgumentException("Destination already exists as a file.", nameof(destinationPath)); - if (to == 0) to = blockTree.Head?.Number ?? 0; - if (to > (blockTree.Head?.Number ?? 0)) - throw new ArgumentException($"Cannot export beyond head block {blockTree.Head?.Number ?? 0}."); + if (to == 0) to = blockTree.Head?.Number ?? 0UL; + if (to > (blockTree.Head?.Number ?? 0UL)) + throw new ArgumentException($"Cannot export beyond head block {blockTree.Head?.Number ?? 0UL}."); if (from > to) throw new ArgumentException($"Start block ({from}) must not be after end block ({to})."); @@ -62,7 +62,7 @@ public Task Export(string destinationPath, long from, long to, CancellationToken return DoExport(destinationPath, from, to, cancellation); } - private async Task DoExport(string destinationPath, long from, long to, CancellationToken cancellation) + private async Task DoExport(string destinationPath, ulong from, ulong to, CancellationToken cancellation) { int concurrency = CalculateConcurrency(eraConfig.Concurrency); if (_logger.IsInfo) _logger.Info($"Exporting EraE blocks {from}–{to} to {destinationPath} (concurrency={concurrency})"); @@ -74,12 +74,12 @@ private async Task DoExport(string destinationPath, long from, long to, Cancella progress.Reset(0, to - from + 1); int totalProcessed = 0; - long startEpoch = from / _eraSize; - long endEpoch = to / _eraSize; - long epochCount = endEpoch - startEpoch + 1; + ulong startEpoch = from / (ulong)_eraSize; + ulong endEpoch = to / (ulong)_eraSize; + ulong epochCount = endEpoch - startEpoch + 1; using ArrayPoolList epochIdxs = new((int)epochCount); - for (long i = 0; i < epochCount; i++) epochIdxs.Add(i); + for (long i = 0; i < (long)epochCount; i++) epochIdxs.Add(i); using ArrayPoolList accumulators = new((int)epochCount, (int)epochCount); using ArrayPoolList checksums = new((int)epochCount, (int)epochCount); @@ -115,17 +115,17 @@ private async Task DoExport(string destinationPath, long from, long to, Cancella async Task WriteEpoch(long epochIdx, CancellationToken cancel) { int idx = (int)epochIdx; - long epoch = startEpoch + epochIdx; + ulong epoch = startEpoch + (ulong)epochIdx; // Each epoch covers [epoch * eraSize, epoch * eraSize + eraSize - 1]. // Clamp to [from, to] to handle partial first and last epochs. - long epochBlockStart = epoch * _eraSize; - long writeFrom = Math.Max(epochBlockStart, from); - long writeTo = Math.Min(epochBlockStart + _eraSize - 1, to); + ulong epochBlockStart = epoch * (ulong)_eraSize; + ulong writeFrom = Math.Max(epochBlockStart, from); + ulong writeTo = Math.Min(epochBlockStart + (ulong)_eraSize - 1, to); if (TrySkipExistingEpoch(destinationPath, epoch, idx, writeFrom, writeTo, accumulators, checksums, fileNames, cachedChecksums, cachedAccumulators, ref totalProcessed)) return; - string placeholderPath = Path.Combine(destinationPath, EraPathUtils.Filename(_networkName, epoch, Keccak.Zero)); + string placeholderPath = Path.Combine(destinationPath, EraPathUtils.Filename(_networkName, (long)epoch, Keccak.Zero)); ValueHash256 accumulator; ValueHash256 sha256; @@ -133,7 +133,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) using (EraWriter eraWriter = new(fileSystem.File.Create(placeholderPath), specProvider, beaconRootsProvider)) { - for (long blockNumber = writeFrom; blockNumber <= writeTo; blockNumber++) + for (ulong blockNumber = writeFrom; blockNumber <= writeTo; blockNumber++) { Block block = blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.DoNotCreateLevelIfMissing) ?? throw new EraException($"Could not find block {blockNumber}. The node may not have finished syncing block bodies for this range."); @@ -163,7 +163,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) if (Interlocked.Increment(ref totalProcessed) % ProgressLogInterval == 0) { - progress.Update(totalProcessed); + progress.Update((ulong)totalProcessed); progress.LogProgress(); } } @@ -176,7 +176,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) accumulators[idx] = accumulator; checksums[idx] = sha256; // Filename uses the last block hash as the epoch identifier — same convention as go-ethereum execdb. - string finalName = EraPathUtils.Filename(_networkName, epoch, lastBlockHash); + string finalName = EraPathUtils.Filename(_networkName, (long)epoch, lastBlockHash); fileNames[idx] = finalName; string finalPath = Path.Combine(destinationPath, finalName); @@ -216,10 +216,10 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) private bool TrySkipExistingEpoch( string destinationPath, - long epoch, + ulong epoch, int idx, - long writeFrom, - long writeTo, + ulong writeFrom, + ulong writeTo, ArrayPoolList accumulators, ArrayPoolList checksums, ArrayPoolList fileNames, diff --git a/src/Nethermind/Nethermind.EraE/Export/IEraExporter.cs b/src/Nethermind/Nethermind.EraE/Export/IEraExporter.cs index cde8037f483f..bc5b7ccf7cb4 100644 --- a/src/Nethermind/Nethermind.EraE/Export/IEraExporter.cs +++ b/src/Nethermind/Nethermind.EraE/Export/IEraExporter.cs @@ -5,5 +5,5 @@ namespace Nethermind.EraE.Export; public interface IEraExporter { - Task Export(string destinationPath, long from, long to, CancellationToken cancellation = default); + Task Export(string destinationPath, ulong from, ulong to, CancellationToken cancellation = default); } diff --git a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs index 25b706cff0c3..73b25d0009ef 100644 --- a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs +++ b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs @@ -38,7 +38,7 @@ public sealed class EraImporter( private const int ProgressLogInterval = 10000; - public async Task Import(string src, long from, long to, string? accumulatorFile, CancellationToken cancellation = default) + public async Task Import(string src, ulong from, ulong to, string? accumulatorFile, CancellationToken cancellation = default) { if (!fileSystem.Directory.Exists(src)) { @@ -60,8 +60,8 @@ public async Task Import(string src, long from, long to, string? accumulatorFile using IEraStore eraStore = eraStoreFactory.Create(src, trustedAccumulators); - (long firstBlockInStore, long lastBlockInStore) = eraStore.BlockRange; - if (to is 0 or long.MaxValue) + (ulong firstBlockInStore, ulong lastBlockInStore) = eraStore.BlockRange; + if (to is 0 or ulong.MaxValue) to = lastBlockInStore; else if (to > lastBlockInStore) throw new EraImportException($"Store highest block {lastBlockInStore} is lower than requested end {to}."); @@ -87,7 +87,7 @@ public async Task Import(string src, long from, long to, string? accumulatorFile } } - private async Task ImportInternal(long from, long to, IEraStore eraStore, CancellationToken cancellation) + private async Task ImportInternal(ulong from, ulong to, IEraStore eraStore, CancellationToken cancellation) { if (_logger.IsInfo) _logger.Info($"Starting EraE import from {from} to {to}"); @@ -95,15 +95,15 @@ private async Task ImportInternal(long from, long to, IEraStore eraStore, Cancel progressLogger.Reset(0, to - from + 1); long blocksProcessed = 0; - using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, eraConfig.ImportBlocksBufferSize - 1024); - long blockNumber = from; + using BlockTreeSuggestPacer pacer = new(blockTree, (ulong)eraConfig.ImportBlocksBufferSize, (ulong)(eraConfig.ImportBlocksBufferSize - 1024)); + ulong blockNumber = from; - long suggestFromBlock = (blockTree.Head?.Number ?? 0) + 1; + ulong suggestFromBlock = (blockTree.Head?.Number ?? 0UL) + 1; if (syncConfig.FastSync && suggestFromBlock == 1) - suggestFromBlock = long.MaxValue; + suggestFromBlock = ulong.MaxValue; // Align to era boundary for parallel section - long nextEraStart = eraStore.NextEraStart(blockNumber); + ulong nextEraStart = eraStore.NextEraStart(blockNumber); if (nextEraStart <= to) { for (; blockNumber < nextEraStart; blockNumber++) @@ -111,10 +111,10 @@ private async Task ImportInternal(long from, long to, IEraStore eraStore, Cancel } // Parallel historical import (blocks without state) - long partitionSize = _maxEraSize; + ulong partitionSize = (ulong)_maxEraSize; if (blockNumber + partitionSize < suggestFromBlock) { - ConcurrentQueue partitionStartBlocks = new(); + ConcurrentQueue partitionStartBlocks = new(); for (; blockNumber + partitionSize < suggestFromBlock && blockNumber + partitionSize < to; blockNumber += partitionSize) partitionStartBlocks.Enqueue(blockNumber); @@ -124,9 +124,9 @@ private async Task ImportInternal(long from, long to, IEraStore eraStore, Cancel { workers[i] = Task.Run(async () => { - while (partitionStartBlocks.TryDequeue(out long partStart)) + while (partitionStartBlocks.TryDequeue(out ulong partStart)) { - for (long j = 0; j < partitionSize; j++) + for (ulong j = 0; j < partitionSize; j++) { await ImportBlock(partStart + j); } @@ -144,7 +144,7 @@ private async Task ImportInternal(long from, long to, IEraStore eraStore, Cancel progressLogger.LogProgress(); if (_logger.IsInfo) _logger.Info($"Finished EraE import from {from} to {to}"); - async Task ImportBlock(long number) + async Task ImportBlock(ulong number) { if (_logger.IsTrace) _logger.Trace($"Importing EraE block {number}"); cancellation.ThrowIfCancellationRequested(); @@ -175,13 +175,13 @@ async Task ImportBlock(long number) long processed = Interlocked.Increment(ref blocksProcessed); if (processed % ProgressLogInterval == 0) { - progressLogger.Update(processed); + progressLogger.Update((ulong)processed); progressLogger.LogProgress(); } } } - private void InsertBlockAndReceipts(Block block, TxReceipt[] receipts, long lastBlockNumber) + private void InsertBlockAndReceipts(Block block, TxReceipt[] receipts, ulong lastBlockNumber) { Block? existing = blockTree.FindBlock(block.Number); if (existing is null) diff --git a/src/Nethermind/Nethermind.EraE/Import/IEraImporter.cs b/src/Nethermind/Nethermind.EraE/Import/IEraImporter.cs index bf438d67ec49..56d3031f5d01 100644 --- a/src/Nethermind/Nethermind.EraE/Import/IEraImporter.cs +++ b/src/Nethermind/Nethermind.EraE/Import/IEraImporter.cs @@ -5,5 +5,5 @@ namespace Nethermind.EraE.Import; public interface IEraImporter { - Task Import(string src, long from, long to, string? accumulatorFile = null, CancellationToken cancellation = default); + Task Import(string src, ulong from, ulong to, string? accumulatorFile = null, CancellationToken cancellation = default); } diff --git a/src/Nethermind/Nethermind.EraE/Proofs/BlocksRootContext.cs b/src/Nethermind/Nethermind.EraE/Proofs/BlocksRootContext.cs index 7d2b675d1cd5..8a696e1feb66 100644 --- a/src/Nethermind/Nethermind.EraE/Proofs/BlocksRootContext.cs +++ b/src/Nethermind/Nethermind.EraE/Proofs/BlocksRootContext.cs @@ -32,7 +32,7 @@ public sealed class BlocksRootContext : IDisposable private ValueHash256? _historicalRoot; public bool Populated { get; private set; } - public long StartingBlockNumber { get; } + public ulong StartingBlockNumber { get; } public ulong? StartingBlockTimestamp { get; } public ValueHash256 AccumulatorRoot => @@ -44,7 +44,7 @@ public sealed class BlocksRootContext : IDisposable public ValueHash256 HistoricalRoot => _historicalRoot ?? throw new InvalidOperationException("Historical root not set or not finalized."); - public BlocksRootContext(long startingBlockNumber, ulong? startingBlockTimestamp = null, ISpecProvider? specProvider = null) + public BlocksRootContext(ulong startingBlockNumber, ulong? startingBlockTimestamp = null, ISpecProvider? specProvider = null) { StartingBlockNumber = startingBlockNumber; StartingBlockTimestamp = startingBlockTimestamp; diff --git a/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs b/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs index e380714c22ba..8bd21d8d4ab2 100644 --- a/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs +++ b/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs @@ -39,10 +39,10 @@ public Validator( _historicalSummariesProvider = historicalSummariesProvider; } - public bool VerifyAccumulator(long blockNumber, ValueHash256 accumulatorRoot) + public bool VerifyAccumulator(ulong blockNumber, ValueHash256 accumulatorRoot) { if (!TrustedAccumulatorsProvided()) return true; - ValueHash256? trusted = GetAccumulatorForEpoch(blockNumber / HistoricalRootConstants.SlotsPerHistoricalRoot); + ValueHash256? trusted = GetAccumulatorForEpoch((long)(blockNumber / (ulong)HistoricalRootConstants.SlotsPerHistoricalRoot)); return trusted is null ? throw new EraVerificationException("Trusted accumulator root was not provided.") : trusted.Equals(accumulatorRoot); diff --git a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs index 33f5c46ca3bc..248060b90ad5 100644 --- a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs +++ b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs @@ -38,9 +38,9 @@ public sealed class EraStore : IEraStore private readonly int _verifyConcurrency; private volatile bool _disposed; - private readonly Lazy<(long First, long Last)> _blockRange; + private readonly Lazy<(ulong First, ulong Last)> _blockRange; - public (long First, long Last) BlockRange => _blockRange.Value; + public (ulong First, ulong Last) BlockRange => _blockRange.Value; private int LastEpoch { get; } private int FirstEpoch { get; } = int.MaxValue; @@ -93,15 +93,15 @@ public EraStore( if (!hasEraFile) throw new EraException($"No relevant erae files in directory {directory}."); - _blockRange = new Lazy<(long, long)>(() => + _blockRange = new Lazy<(ulong, ulong)>(() => { using EraRenter f = RentReader(FirstEpoch, out EraReader firstReader); using EraRenter l = RentReader(LastEpoch, out EraReader lastReader); - return (firstReader.FirstBlock, lastReader.LastBlock); + return ((ulong)firstReader.FirstBlock, (ulong)lastReader.LastBlock); }); } - private long GetEpochNumber(long blockNumber) => blockNumber / _maxEraSize; + private long GetEpochNumber(ulong blockNumber) => (long)(blockNumber / (ulong)_maxEraSize); private EraReader GetReader(long epoch) => !_epochs.TryGetValue(epoch, out string? path) ? throw new ArgumentOutOfRangeException(nameof(epoch), epoch, "Epoch not available.") @@ -145,19 +145,17 @@ private async ValueTask EnsureEpochVerified(long epoch, EraReader reader, Cancel } } - public bool HasEpoch(long blockNumber) => _epochs.ContainsKey(GetEpochNumber(blockNumber)); + public bool HasEpoch(ulong blockNumber) => _epochs.ContainsKey(GetEpochNumber(blockNumber)); - public long NextEraStart(long blockNumber) + public ulong NextEraStart(ulong blockNumber) { long epoch = GetEpochNumber(blockNumber); using EraRenter _ = RentReader(epoch, out EraReader reader); - return reader.LastBlock + 1; + return (ulong)reader.LastBlock + 1; } - public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(long number, bool ensureValidated = true, CancellationToken cancellation = default) + public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(ulong number, bool ensureValidated = true, CancellationToken cancellation = default) { - ArgumentOutOfRangeException.ThrowIfNegative(number); - long epoch = GetEpochNumber(number); if (!_epochs.ContainsKey(epoch)) return (null, null); diff --git a/src/Nethermind/Nethermind.EraE/Store/IEraStore.cs b/src/Nethermind/Nethermind.EraE/Store/IEraStore.cs index 20dfee04e9a0..2ba9ea6f3756 100644 --- a/src/Nethermind/Nethermind.EraE/Store/IEraStore.cs +++ b/src/Nethermind/Nethermind.EraE/Store/IEraStore.cs @@ -7,11 +7,11 @@ namespace Nethermind.EraE.Store; public interface IEraStore : IDisposable { - Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(long number, bool ensureValidated = true, CancellationToken cancellation = default); - (long First, long Last) BlockRange { get; } + Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(ulong number, bool ensureValidated = true, CancellationToken cancellation = default); + (ulong First, ulong Last) BlockRange { get; } - bool HasEpoch(long blockNumber); + bool HasEpoch(ulong blockNumber); /// Used for alignment when parallelizing imports so different tasks work on different files. - long NextEraStart(long blockNumber); + ulong NextEraStart(ulong blockNumber); } diff --git a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs index 0df3e2218f19..9e67020d2f24 100644 --- a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs +++ b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs @@ -54,7 +54,7 @@ public sealed class RemoteEraStoreDecorator : IEraStore private readonly ConcurrentDictionary _openedReaders = new(); // Setup path — sequential, sync-over-async is safe (see thread-safety model above) - public (long First, long Last) BlockRange => GetBlockRangeAsync().GetAwaiter().GetResult(); + public (ulong First, ulong Last) BlockRange => GetBlockRangeAsync().GetAwaiter().GetResult(); public RemoteEraStoreDecorator( IEraStore? localStore, @@ -87,7 +87,7 @@ public RemoteEraStoreDecorator( } public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts( - long number, bool ensureValidated = true, CancellationToken cancellation = default) + ulong number, bool ensureValidated = true, CancellationToken cancellation = default) { if (_localStore is not null) { @@ -95,26 +95,26 @@ public RemoteEraStoreDecorator( if (b is not null) return (b, r); } - int epoch = (int)(number / _maxEraSize); + int epoch = (int)(number / (ulong)_maxEraSize); string localPath = await EnsureEpochAvailableAsync(epoch, ensureValidated, cancellation).ConfigureAwait(false); using EraRenter renter = RentReader(epoch, localPath); - if (number > renter.Reader.LastBlock) return (null, null); + if (number > (ulong)renter.Reader.LastBlock) return (null, null); (Block block, TxReceipt[] receipts) = await renter.Reader.GetBlockByNumber(number, cancellation).ConfigureAwait(false); return (block, receipts); } - public bool HasEpoch(long blockNumber) => _localStore is not null && _localStore.HasEpoch(blockNumber); + public bool HasEpoch(ulong blockNumber) => _localStore is not null && _localStore.HasEpoch(blockNumber); - public long NextEraStart(long blockNumber) + public ulong NextEraStart(ulong blockNumber) { if (_localStore is not null && _localStore.HasEpoch(blockNumber)) return _localStore.NextEraStart(blockNumber); - int epoch = (int)(blockNumber / _maxEraSize); + int epoch = (int)(blockNumber / (ulong)_maxEraSize); string localPath = EnsureEpochAvailableAsync(epoch, ensureValidated: false).GetAwaiter().GetResult(); using EraReader reader = new(localPath); - return reader.LastBlock + 1; + return (ulong)reader.LastBlock + 1; } public void Dispose() @@ -161,7 +161,7 @@ private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reade public void Dispose() => store.ReturnReader(epoch, reader); } - private async Task<(long First, long Last)> GetBlockRangeAsync(CancellationToken cancellation = default) + private async Task<(ulong First, ulong Last)> GetBlockRangeAsync(CancellationToken cancellation = default) { if (_localStore is not null) return _localStore.BlockRange; @@ -175,7 +175,7 @@ private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reade // The actual last block may be slightly lower for a non-full final epoch. // FindBlockAndReceipts returns (null, null) when number > reader.LastBlock, so importers that // rely on this value (to=0 / auto mode) will stop naturally at the real end. - return ((long)minEpoch * _maxEraSize, (long)(maxEpoch + 1) * _maxEraSize - 1); + return ((ulong)minEpoch * (ulong)_maxEraSize, (ulong)(maxEpoch + 1) * (ulong)_maxEraSize - 1); } private async Task> GetManifestAsync(CancellationToken cancellation = default) diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsIntegrationTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsIntegrationTests.cs index 4a64f5386bdc..11f7fd8de70e 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsIntegrationTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsIntegrationTests.cs @@ -23,26 +23,22 @@ namespace Nethermind.EthStats.Test; public class EthStatsIntegrationTests { - [TestCase(3, 1, true, 1, 3, TestName = "TryNormalizeHistoryRange_swaps_min_and_max")] - [TestCase(-3, -1, false, 0, 0, TestName = "TryNormalizeHistoryRange_rejects_negative_range")] - [TestCase(-3, 3, true, 0, 3, TestName = "TryNormalizeHistoryRange_clamps_negative_min")] - [TestCase(0, 100, true, 37, 100, TestName = "TryNormalizeHistoryRange_limits_oversized_range")] - [TestCase(0, long.MaxValue, true, long.MaxValue - 63, long.MaxValue, TestName = "TryNormalizeHistoryRange_handles_max_long_without_overflow")] + [TestCase(3UL, 1UL, 1UL, 3UL, TestName = "TryNormalizeHistoryRange_swaps_min_and_max")] + [TestCase(0UL, 100UL, 37UL, 100UL, TestName = "TryNormalizeHistoryRange_limits_oversized_range")] + [TestCase(ulong.MaxValue - 63, ulong.MaxValue, ulong.MaxValue - 63, ulong.MaxValue, TestName = "TryNormalizeHistoryRange_handles_max_ulong_without_overflow")] public void TryNormalizeHistoryRange_handles_edges( - long requestMin, - long requestMax, - bool expectedResult, - long expectedMin, - long expectedMax) + ulong requestMin, + ulong requestMax, + ulong expectedMin, + ulong expectedMax) { - bool result = EthStatsIntegration.TryNormalizeHistoryRange( + EthStatsIntegration.TryNormalizeHistoryRange( new EthStatsHistoryRequest(requestMin, requestMax), - out long min, - out long max); + out ulong min, + out ulong max); using (Assert.EnterMultipleScope()) { - Assert.That(result, Is.EqualTo(expectedResult)); Assert.That(min, Is.EqualTo(expectedMin)); Assert.That(max, Is.EqualTo(expectedMax)); } @@ -57,8 +53,8 @@ public async Task HandleIncomingMessageAsync_sends_history_in_ascending_order() CoreBlock firstBlock = Build.A.Block.WithNumber(1).TestObject; CoreBlock secondBlock = Build.A.Block.WithNumber(2).TestObject; - blockTree.FindBlock(1, BlockTreeLookupOptions.RequireCanonical).Returns(firstBlock); - blockTree.FindBlock(2, BlockTreeLookupOptions.RequireCanonical).Returns(secondBlock); + blockTree.FindBlock(1UL, BlockTreeLookupOptions.RequireCanonical).Returns(firstBlock); + blockTree.FindBlock(2UL, BlockTreeLookupOptions.RequireCanonical).Returns(secondBlock); sender.SendAsync(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(Task.CompletedTask); @@ -93,9 +89,9 @@ private static EthStatsIntegration CreateIntegration(IMessageSender sender, IBlo TimeSpan.FromSeconds(1), LimboLogs.Instance); - private static bool HasHistoryBlocks(HistoryMessage message, long firstBlockNumber, long secondBlockNumber) + private static bool HasHistoryBlocks(HistoryMessage message, ulong firstBlockNumber, ulong secondBlockNumber) { - List numbers = []; + List numbers = []; foreach (EthStatsBlock block in message.History) { numbers.Add(block.Number); diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsMessageParserTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsMessageParserTests.cs index 21be7ccea7e3..0d0767e3bb9c 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsMessageParserTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsMessageParserTests.cs @@ -13,8 +13,8 @@ private static IEnumerable ParseCases() yield return new TestCaseData( """{"emit":["history",{"min":1,"max":3}]}""", (int)EthStatsIncomingMessageType.History, - 1L, - 3L, + 1UL, + 3UL, null) .SetName("Can_parse_history_request"); @@ -39,8 +39,8 @@ private static IEnumerable ParseCases() public void Can_parse_message( string json, int expectedMessageType, - long? expectedHistoryMin, - long? expectedHistoryMax, + ulong? expectedHistoryMin, + ulong? expectedHistoryMax, long? expectedClientTime) { bool parsed = EthStatsMessageParser.TryParse(json, out EthStatsIncomingMessage message); diff --git a/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs b/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs index 817c90a621aa..6850df6a02b0 100644 --- a/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs +++ b/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs @@ -17,7 +17,7 @@ internal enum EthStatsIncomingMessageType NodePong } -internal readonly record struct EthStatsHistoryRequest(long Min, long Max); +internal readonly record struct EthStatsHistoryRequest(ulong Min, ulong Max); internal readonly record struct EthStatsNodeTiming(long? ClientTime); @@ -191,8 +191,8 @@ private static bool TryParseCore(ReadOnlySpan utf8Bytes, out EthStatsIncom private static bool TryReadHistoryRequest(ref Utf8JsonReader reader, out EthStatsHistoryRequest historyRequest) { historyRequest = default; - long? min = null; - long? max = null; + ulong? min = null; + ulong? max = null; while (reader.Read()) { @@ -216,7 +216,7 @@ private static bool TryReadHistoryRequest(ref Utf8JsonReader reader, out EthStat if (isMin) { - if (!TryReadInt64(ref reader, out long value)) + if (!TryReadUInt64(ref reader, out ulong value)) { return false; } @@ -224,7 +224,7 @@ private static bool TryReadHistoryRequest(ref Utf8JsonReader reader, out EthStat } else if (isMax) { - if (!TryReadInt64(ref reader, out long value)) + if (!TryReadUInt64(ref reader, out ulong value)) { return false; } @@ -281,6 +281,21 @@ private static EthStatsNodeTiming ReadNodeTiming(ref Utf8JsonReader reader) return new EthStatsNodeTiming(clientTime); } + private static bool TryReadUInt64(ref Utf8JsonReader reader, out ulong value) + { + value = 0; + + switch (reader.TokenType) + { + case JsonTokenType.Number: + return reader.TryGetUInt64(out value); + case JsonTokenType.String: + return TryParseUInt64String(ref reader, out value); + default: + return false; + } + } + private static bool TryReadInt64(ref Utf8JsonReader reader, out long value) { value = 0; @@ -296,6 +311,30 @@ private static bool TryReadInt64(ref Utf8JsonReader reader, out long value) } } + private static bool TryParseUInt64String(ref Utf8JsonReader reader, out ulong value) + { + // An unsigned 64-bit integer is at most 20 ASCII bytes ("18446744073709551615") + const int maxUInt64Digits = 20; + + if (reader.HasValueSequence) + { + long sequenceLength = reader.ValueSequence.Length; + if (sequenceLength > maxUInt64Digits) + { + value = 0; + return false; + } + + Span sequenceBuffer = stackalloc byte[maxUInt64Digits]; + reader.ValueSequence.CopyTo(sequenceBuffer); + ReadOnlySpan sequenceRaw = sequenceBuffer[..(int)sequenceLength]; + return Utf8Parser.TryParse(sequenceRaw, out value, out int sequenceConsumed) && sequenceConsumed == sequenceRaw.Length; + } + + ReadOnlySpan raw = reader.ValueSpan; + return Utf8Parser.TryParse(raw, out value, out int consumed) && consumed == raw.Length; + } + private static bool TryParseInt64String(ref Utf8JsonReader reader, out long value) { // A signed 64-bit integer is at most 20 ASCII bytes ("-9223372036854775808"); anything diff --git a/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs b/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs index 4fb6908bdfe8..f3174353d825 100644 --- a/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs +++ b/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs @@ -195,14 +195,14 @@ private async Task ReconnectHelloAsync() private Task SendHistoryAsync(EthStatsHistoryRequest request) { - if (!TryNormalizeHistoryRange(request, out long min, out long max)) + if (!TryNormalizeHistoryRange(request, out ulong min, out ulong max)) { if (_logger.IsDebug) _logger.Debug($"Ignoring invalid ETH Stats history range {request.Min}-{request.Max}."); return Task.CompletedTask; } List history = new((int)(max - min + 1)); - for (long blockNumber = min; blockNumber <= max; blockNumber++) + for (ulong blockNumber = min; blockNumber <= max; blockNumber++) { CoreBlock? block = _blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical); if (block is not null) @@ -210,7 +210,7 @@ private Task SendHistoryAsync(EthStatsHistoryRequest request) history.Add(CreateBlockModel(block)); } - // Prevent long.MaxValue + 1 overflow on the for-loop increment. + // Prevent ulong.MaxValue + 1 overflow on the for-loop increment. if (blockNumber == max) { break; @@ -300,7 +300,7 @@ private Task HandleUnknownMessageAsync(string eventType) return Task.CompletedTask; } - internal static bool TryNormalizeHistoryRange(EthStatsHistoryRequest request, out long min, out long max) + internal static bool TryNormalizeHistoryRange(EthStatsHistoryRequest request, out ulong min, out ulong max) { min = Math.Min(request.Min, request.Max); max = Math.Max(request.Min, request.Max); diff --git a/src/Nethermind/Nethermind.EthStats/Messages/Models/Block.cs b/src/Nethermind/Nethermind.EthStats/Messages/Models/Block.cs index b3f1df14e065..938426307bbc 100644 --- a/src/Nethermind/Nethermind.EthStats/Messages/Models/Block.cs +++ b/src/Nethermind/Nethermind.EthStats/Messages/Models/Block.cs @@ -5,17 +5,17 @@ namespace Nethermind.EthStats.Messages.Models { - public class Block(long number, string hash, string parentHash, long timestamp, string miner, long gasUsed, - long gasLimit, string difficulty, string totalDifficulty, IEnumerable transactions, + public class Block(ulong number, string hash, string parentHash, long timestamp, string miner, ulong gasUsed, + ulong gasLimit, string difficulty, string totalDifficulty, IEnumerable transactions, string transactionsRoot, string stateRoot, IEnumerable uncles) { - public long Number { get; } = number; + public ulong Number { get; } = number; public string Hash { get; } = hash; public string ParentHash { get; } = parentHash; public long Timestamp { get; } = timestamp; public string Miner { get; } = miner; - public long GasUsed { get; } = gasUsed; - public long GasLimit { get; } = gasLimit; + public ulong GasUsed { get; } = gasUsed; + public ulong GasLimit { get; } = gasLimit; public string Difficulty { get; } = difficulty; public string TotalDifficulty { get; } = totalDifficulty; public IEnumerable Transactions { get; } = transactions; diff --git a/src/Nethermind/Nethermind.Ethash.Test/ChainSpecTest.cs b/src/Nethermind/Nethermind.Ethash.Test/ChainSpecTest.cs index 4ce4bafdf121..202758b3f704 100644 --- a/src/Nethermind/Nethermind.Ethash.Test/ChainSpecTest.cs +++ b/src/Nethermind/Nethermind.Ethash.Test/ChainSpecTest.cs @@ -23,7 +23,7 @@ public void Bound_divisors_set_correctly() { ChainSpec chainSpec = new() { - Parameters = new ChainParameters { GasLimitBoundDivisor = 17 } + Parameters = new ChainParameters { GasLimitBoundDivisor = 17UL } }; chainSpec.EngineChainSpecParametersProvider = @@ -32,7 +32,7 @@ public void Bound_divisors_set_correctly() ChainSpecBasedSpecProvider provider = new(chainSpec); Assert.That(provider.GenesisSpec.DifficultyBoundDivisor, Is.EqualTo(19)); - Assert.That(provider.GenesisSpec.GasLimitBoundDivisor, Is.EqualTo(17)); + Assert.That(provider.GenesisSpec.GasLimitBoundDivisor, Is.EqualTo(17UL)); } [Test] @@ -45,13 +45,13 @@ public void Difficulty_bomb_delays_loaded_correctly() chainSpec.EngineChainSpecParametersProvider = new TestChainSpecParametersProvider( new EthashChainSpecEngineParameters { - DifficultyBombDelays = new Dictionary + DifficultyBombDelays = new Dictionary { - { 3, 100 }, - { 7, 200 }, - { 13, 300 }, - { 17, 400 }, - { 19, 500 }, + { 3UL, 100UL }, + { 7UL, 200UL }, + { 13UL, 300UL }, + { 17UL, 400UL }, + { 19UL, 500UL }, } }); @@ -78,10 +78,10 @@ public void Eip_transitions_loaded_correctly() MaxCodeSizeTransition = maxCodeTransition, MaxCodeSize = maxCodeSize, Registrar = Address.Zero, - MinGasLimit = 11, + MinGasLimit = 11UL, MinHistoryRetentionEpochs = 11, MinBalRetentionEpochs = 7, - GasLimitBoundDivisor = 13, + GasLimitBoundDivisor = 13UL, MaximumExtraDataSize = 17, Eip140Transition = 1400L, Eip145Transition = 1450L, @@ -153,10 +153,10 @@ void TestTransitions(ForkActivation activation, Action c TestTransitions((ForkActivation)0L, r => { r.DifficultyBoundDivisor = 0x800; - r.MinGasLimit = 11L; + r.MinGasLimit = 11UL; r.MinHistoryRetentionEpochs = 11L; r.MinBalRetentionEpochs = 7L; - r.GasLimitBoundDivisor = 13L; + r.GasLimitBoundDivisor = 13UL; r.MaximumExtraDataSize = 17L; r.MaxCodeSize = long.MaxValue; r.Eip1559TransitionBlock = 15590L; diff --git a/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs b/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs index 0f4c9039051a..a91baf320733 100644 --- a/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs @@ -17,8 +17,8 @@ public class DifficultyCalculatorTests public void Calculate_should_returns_expected_results() { IReleaseSpec releaseSpec = ReleaseSpecSubstitute.Create(); - releaseSpec.DifficultyBombDelay.Returns(0); - releaseSpec.DifficultyBoundDivisor.Returns(2048); + releaseSpec.DifficultyBombDelay.Returns(0UL); + releaseSpec.DifficultyBoundDivisor.Returns(2048UL); releaseSpec.IsEip2Enabled.Returns(true); releaseSpec.IsEip100Enabled.Returns(true); releaseSpec.IsTimeAdjustmentPostOlympic.Returns(true); @@ -80,12 +80,12 @@ private void Calculation_should_not_be_equal_on_different_difficulty_hard_forks( ISpecProvider firstHardForkSpecProvider = Substitute.For(); firstHardForkSpecProvider.GetSpec(Arg.Any()).Returns(firstHardfork); EthashDifficultyCalculator firstHardforkDifficultyCalculator = new(firstHardForkSpecProvider); - UInt256 firstHardforkResult = firstHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, blocksAbove, false); + UInt256 firstHardforkResult = firstHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, (ulong)blocksAbove, false); ISpecProvider secondHardforkSpecProvider = Substitute.For(); secondHardforkSpecProvider.GetSpec(Arg.Any()).Returns(secondHardfork); EthashDifficultyCalculator secondHardforkDifficultyCalculator = new(secondHardforkSpecProvider); - UInt256 secondHardforkResult = secondHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, blocksAbove, false); + UInt256 secondHardforkResult = secondHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, (ulong)blocksAbove, false); Assert.That(secondHardforkResult, Is.Not.EqualTo(firstHardforkResult)); } diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs index 29eefec364a2..929624222270 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs @@ -347,7 +347,7 @@ private Transaction[] BuildLegacyTransfers(int count, int startNonce) for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((UInt256)(startNonce + i)) + .WithNonce((ulong)(startNonce + i)) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(21_000) @@ -358,14 +358,14 @@ private Transaction[] BuildLegacyTransfers(int count, int startNonce) return txs; } - private Transaction[] BuildEip1559Transfers(int count, int startNonce) + private Transaction[] BuildEip1559Transfers(int count, uint startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction .WithType(TxType.EIP1559) - .WithNonce((UInt256)(startNonce + i)) + .WithNonce(startNonce + i) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(21_000) @@ -384,7 +384,7 @@ private Transaction[] BuildAccessListTxs(int count, int startNonce) { txs[i] = Build.A.Transaction .WithType(TxType.AccessList) - .WithNonce((UInt256)(startNonce + i)) + .WithNonce((ulong)(startNonce + i)) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(50_000) @@ -402,7 +402,7 @@ private Transaction[] BuildContractDeploys(int count, int startNonce) for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((UInt256)(startNonce + i)) + .WithNonce((ulong)(startNonce + i)) .WithTo(null) .WithData(ContractCode) .WithGasLimit(100_000) @@ -419,7 +419,7 @@ private Transaction[] BuildContractCalls(int count, int startNonce) for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((UInt256)(startNonce + i)) + .WithNonce((ulong)(startNonce + i)) .WithTo(TestItem.AddressB) .WithGasLimit(50_000) .WithGasPrice(2.GWei) diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 66edf661917c..09453d5ffe1e 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -58,7 +58,7 @@ public void GlobalSetup() inputData: default ); - _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromLong(long.MaxValue), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); + _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromULong(ulong.MaxValue), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); } [GlobalCleanup] diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmOpcodesBenchmark.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmOpcodesBenchmark.cs index a836375483b3..a63d6df89602 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmOpcodesBenchmark.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmOpcodesBenchmark.cs @@ -132,7 +132,7 @@ Instruction.LOG0 or Instruction.LOG1 or Instruction.LOG2 or Instruction.LOG3 or public void Setup() { (_stackBuffer, _stackOffset, _stackLength) = CreateStackBuffer(); - _gas = EthereumGasPolicy.FromLong(long.MaxValue); + _gas = EthereumGasPolicy.FromULong(ulong.MaxValue); // Pre-fill 20 stack slots with unique values for DUP/SWAP tests for (int i = 0; i < 20; i++) @@ -200,7 +200,7 @@ public void Setup() inputData: default); _vmState = VmState.RentTopLevel( - EthereumGasPolicy.FromLong(long.MaxValue), + EthereumGasPolicy.FromULong(ulong.MaxValue), ExecutionType.TRANSACTION, _env, new StackAccessTracker(), @@ -645,7 +645,7 @@ private long ExecuteOpcodeOnceForGas() _ = _opcodes[(int)Opcode](_vm, ref stack, ref gas, ref pc); DisposeNestedReturnFrame(); - return _gas.Value - gas.Value; + return (long)(_gas.Value - gas.Value); } private void DisposeNestedReturnFrame() @@ -908,7 +908,7 @@ public void SetExecutionDependencies(IWorldState state, ICodeInfoRepository code private class NoOpBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) => Keccak.Zero; + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) => Keccak.Zero; public Task Prefetch(BlockHeader currentBlock, CancellationToken token) => Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index de3397036649..8f6a2f702660 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -90,7 +90,7 @@ public void GlobalSetup() inputData: default ); - _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromLong(100_000_000L), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); + _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromULong(100_000_000UL), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); } [GlobalCleanup] diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index 306116689a23..2f0fd56177e9 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -100,7 +100,7 @@ public void GlobalSetup() inputData: default ); - _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromLong(100_000_000L), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); + _evmState = VmState.RentTopLevel(EthereumGasPolicy.FromULong(100_000_000UL), ExecutionType.TRANSACTION, _environment, new StackAccessTracker(), _stateProvider.TakeSnapshot()); } [GlobalCleanup] diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs index 08df54447958..217c16a20bf8 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm.Benchmark { public class TestBlockhashProvider() : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) => Keccak.Compute(spec.IsBlockHashInStateAvailable + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) => Keccak.Compute(spec.IsBlockHashInStateAvailable ? (Eip2935Constants.RingBufferSize + number).ToString() : (number).ToString()); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs index 03901e719b34..ea9007407045 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs @@ -26,7 +26,7 @@ private IdentityPrecompile() public long BaseGasCost(IReleaseSpec releaseSpec) => 15L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - 3L * EvmCalculations.Div32Ceiling((ulong)inputData.Length); + (long)(3UL * EvmCalculations.Div32Ceiling(inputData.Length)); public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => inputData.ToArray(); } diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs index 37c835c230be..28f8f511f55f 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs @@ -87,8 +87,8 @@ public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) if (baseLength == uint.MaxValue || modulusLength == uint.MaxValue || (baseLength == 0 && modulusLength == 0)) return inputData[..LengthsLengths]; - ulong end = (ulong)LengthsLengths + baseLength + expLength + modulusLength; - return end < (ulong)inputData.Length ? inputData[..(int)end] : inputData; + long end = (long)LengthsLengths + baseLength + expLength + modulusLength; + return end < inputData.Length ? inputData[..(int)end] : inputData; } public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec); @@ -131,7 +131,7 @@ private static long DataGasCostInternal(ReadOnlySpan inputData, IReleaseSp return result > long.MaxValue || overflow ? long.MaxValue - : Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (long)result); + : (long)Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (ulong)result); } /// @@ -148,7 +148,7 @@ private static ulong MultComplexity(uint baseLength, uint modulusLength, bool is // Compute ceil(max/8) via a single add + shift // (max + 7) >> 3 == (max + 7) / 8, rounding up - ulong words = ((ulong)max + 7u) >> 3; + ulong words = (max + 7UL) >> 3; // Square it once ulong sq = words * words; diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs index 46f97a593c62..afa0fecae8c6 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs @@ -20,7 +20,7 @@ private Ripemd160Precompile() { } public long BaseGasCost(IReleaseSpec releaseSpec) => 600L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - 120L * EvmCalculations.Div32Ceiling((ulong)inputData.Length); + (long)(120UL * EvmCalculations.Div32Ceiling(inputData.Length)); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); } diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs index 5de584d3c064..554b12a9eea2 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs @@ -20,7 +20,7 @@ private Sha256Precompile() { } public long BaseGasCost(IReleaseSpec releaseSpec) => 60L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => - 12L * EvmCalculations.Div32Ceiling((ulong)inputData.Length); + (long)(12UL * EvmCalculations.Div32Ceiling(inputData.Length)); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); } diff --git a/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs b/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs index 43d398cf0f40..df27a3953c3c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs @@ -14,7 +14,7 @@ namespace Nethermind.Evm.Test; [Parallelizable(ParallelScope.Self)] public class CallDataLoadTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.CancunBlockTimestamp; // Forces the OffFlag specialization of InstructionCallDataLoad; the default tracer diff --git a/src/Nethermind/Nethermind.Evm.Test/CallTests.cs b/src/Nethermind/Nethermind.Evm.Test/CallTests.cs index 086752b11ad9..02c130642444 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CallTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CallTests.cs @@ -8,7 +8,7 @@ namespace Nethermind.Evm.Test { public class CallTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.OsakaBlockTimestamp; [Test] diff --git a/src/Nethermind/Nethermind.Evm.Test/CmpTests.cs b/src/Nethermind/Nethermind.Evm.Test/CmpTests.cs index 84c3c9448993..a892a04b7dec 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CmpTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CmpTests.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm.Test [Parallelizable(ParallelScope.Self)] public class CmpTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; [TestCase(Instruction.GT, "0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0ff", @@ -49,7 +49,7 @@ private void AssertCmp(TestAllTracerWithOutput receipt, byte[] result) AssertGas(receipt, result.IsZero() ? ZeroResultGas : NonZeroResultGas); } - private const long ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SReset; - private const long NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; + private const ulong ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SReset; + private const ulong NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; } } diff --git a/src/Nethermind/Nethermind.Evm.Test/CoinbaseTests.cs b/src/Nethermind/Nethermind.Evm.Test/CoinbaseTests.cs index 22ae1763a233..8e662382e913 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CoinbaseTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CoinbaseTests.cs @@ -13,7 +13,7 @@ public class CoinbaseTests : VirtualMachineTestsBase { private bool _setAuthor; - protected override Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner, Transaction transaction, long blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) + protected override Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner, Transaction transaction, ulong blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) { senderRecipientAndMiner ??= new SenderRecipientAndMiner(); Block block = base.BuildBlock(activation, senderRecipientAndMiner, transaction, blockGasLimit); diff --git a/src/Nethermind/Nethermind.Evm.Test/DataCopyGasTests.cs b/src/Nethermind/Nethermind.Evm.Test/DataCopyGasTests.cs index f8b16b98c757..3372010a9e23 100644 --- a/src/Nethermind/Nethermind.Evm.Test/DataCopyGasTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/DataCopyGasTests.cs @@ -57,7 +57,7 @@ public void Copy_ZeroLength_ConsumesBaseGas(Instruction instruction) public void Copy_ZeroLength_InsufficientGas_ReturnsOutOfGas(Instruction instruction) { byte[] code = BuildCopyCode(instruction, 0); - long gasLimit = GetBaseGas(instruction) - 1; + ulong gasLimit = GetBaseGas(instruction) - 1UL; TestAllTracerWithOutput result = Execute(Activation, gasLimit, code); @@ -74,7 +74,7 @@ public void Copy_OneWord_ConsumesMemoryGas(Instruction instruction) TestAllTracerWithOutput result = Execute(code); Assert.That(result.Error, Is.Null); - Assert.That(result.GasSpent, Is.EqualTo(GetBaseGas(instruction) + 2 * GasCostOf.Memory)); + Assert.That(result.GasSpent, Is.EqualTo(GetBaseGas(instruction) + 2UL * GasCostOf.Memory)); } private static byte[] BuildCopyCode(Instruction instruction, int length) @@ -90,7 +90,7 @@ private static byte[] BuildCopyCode(Instruction instruction, int length) return prepare.Op(instruction).Done; } - private static long GetBaseGas(Instruction instruction) => instruction == Instruction.EXTCODECOPY - ? GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.ExtCodeEip150 - : GasCostOf.Transaction + 3 * GasCostOf.VeryLow + GasCostOf.VeryLow; + private static ulong GetBaseGas(Instruction instruction) => instruction == Instruction.EXTCODECOPY + ? GasCostOf.Transaction + 4UL * GasCostOf.VeryLow + GasCostOf.ExtCodeEip150 + : GasCostOf.Transaction + 3UL * GasCostOf.VeryLow + GasCostOf.VeryLow; } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1014Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1014Tests.cs index 6833b0bb5ea4..cbd8bd2a4c4f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1014Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1014Tests.cs @@ -16,7 +16,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip1014Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; private static readonly byte[] _defaultSalt = [4, 5, 6]; private static readonly byte[] _defaultDeployedCode = [1, 2, 3]; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1052Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1052Tests.cs index abb1dd49b9ab..f71bc28c964a 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1052Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1052Tests.cs @@ -17,7 +17,7 @@ namespace Nethermind.Evm.Test; public class Eip1052Tests : VirtualMachineTestsBase { - protected override long BlockNumber => 10000001; + protected override ulong BlockNumber => 10000001; protected override ISpecProvider SpecProvider => new CustomSpecProvider( ((ForkActivation)0, Byzantium.Instance), ((ForkActivation)10000001, Constantinople.Instance)); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs index c6c6a241b730..6d7c43ed6b14 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm.Test; public class Eip1108Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber + _blockNumberAdjustment; + protected override ulong BlockNumber => (ulong)((long)MainnetSpecProvider.IstanbulBlockNumber + _blockNumberAdjustment); private int _blockNumberAdjustment; @@ -32,7 +32,7 @@ public void Test_add(int blockAdjustment, long expectedPrecompileGas) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); + AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); } [TestCase(-1, 50000L, 40000L, Description = "Before Istanbul")] @@ -45,7 +45,7 @@ public void Test_mul(int blockAdjustment, long gasLimit, long expectedPrecompile .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); + AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); } [TestCase(-1, 180000L, Description = "Before Istanbul")] @@ -58,6 +58,6 @@ public void Test_pairing(int blockAdjustment, long expectedPrecompileGas) .Done; TestAllTracerWithOutput result = Execute(BlockNumber, 1000000L, code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 6 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); + AssertGas(result, 21000 + 6 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1153Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1153Tests.cs index 814b4639d27c..170e6f84e175 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1153Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1153Tests.cs @@ -16,7 +16,7 @@ namespace Nethermind.Evm.Test; /// internal class Eip1153Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.CancunBlockTimestamp; /// @@ -81,10 +81,10 @@ public void tload_uninitialized_returns_zero() [Test] public void transient_storage_performance_test() { - long blockGasLimit = 30000000; - long numOfOps = (long)(blockGasLimit * .95) / (GasCostOf.TLoad + GasCostOf.TStore + GasCostOf.VeryLow * 4); + ulong blockGasLimit = 30000000; + ulong numOfOps = (blockGasLimit * 95UL / 100UL) / (GasCostOf.TLoad + GasCostOf.TStore + GasCostOf.VeryLow * 4); Prepare prepare = Prepare.EvmCode; - for (long i = 0; i < numOfOps; i++) + for (ulong i = 0; i < numOfOps; i++) { prepare.StoreDataInTransientStorage(1, 8); prepare.LoadDataFromTransientStorage(1); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1283Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1283Tests.cs index 0f75f89071d1..c6b78681d9d3 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1283Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1283Tests.cs @@ -16,29 +16,29 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip1283Tests : VirtualMachineTestsBase { - protected override long BlockNumber => 1; + protected override ulong BlockNumber => 1; protected override ISpecProvider SpecProvider => new CustomSpecProvider( ((ForkActivation)0, Byzantium.Instance), ((ForkActivation)1, Constantinople.Instance)); - [TestCase("0x60006000556000600055", 412, 0, 0)] - [TestCase("0x60006000556001600055", 20212, 0, 0)] - [TestCase("0x60016000556000600055", 20212, 19800, 0)] - [TestCase("0x60016000556002600055", 20212, 0, 0)] - [TestCase("0x60016000556001600055", 20212, 0, 0)] - [TestCase("0x60006000556000600055", 5212, 15000, 1)] - [TestCase("0x60006000556001600055", 5212, 4800, 1)] - [TestCase("0x60006000556002600055", 5212, 0, 1)] - [TestCase("0x60026000556000600055", 5212, 15000, 1)] - [TestCase("0x60026000556003600055", 5212, 0, 1)] - [TestCase("0x60026000556001600055", 5212, 4800, 1)] - [TestCase("0x60026000556002600055", 5212, 0, 1)] - [TestCase("0x60016000556000600055", 5212, 15000, 1)] - [TestCase("0x60016000556002600055", 5212, 0, 1)] - [TestCase("0x60016000556001600055", 412, 0, 1)] - [TestCase("0x600160005560006000556001600055", 40218, 19800, 0)] - [TestCase("0x600060005560016000556000600055", 10218, 19800, 1)] - public void Test(string codeHex, long gasUsed, long refund, byte originalValue) + [TestCase("0x60006000556000600055", 412UL, 0UL, 0)] + [TestCase("0x60006000556001600055", 20212UL, 0UL, 0)] + [TestCase("0x60016000556000600055", 20212UL, 19800UL, 0)] + [TestCase("0x60016000556002600055", 20212UL, 0UL, 0)] + [TestCase("0x60016000556001600055", 20212UL, 0UL, 0)] + [TestCase("0x60006000556000600055", 5212UL, 15000UL, 1)] + [TestCase("0x60006000556001600055", 5212UL, 4800UL, 1)] + [TestCase("0x60006000556002600055", 5212UL, 0UL, 1)] + [TestCase("0x60026000556000600055", 5212UL, 15000UL, 1)] + [TestCase("0x60026000556003600055", 5212UL, 0UL, 1)] + [TestCase("0x60026000556001600055", 5212UL, 4800UL, 1)] + [TestCase("0x60026000556002600055", 5212UL, 0UL, 1)] + [TestCase("0x60016000556000600055", 5212UL, 15000UL, 1)] + [TestCase("0x60016000556002600055", 5212UL, 0UL, 1)] + [TestCase("0x60016000556001600055", 412UL, 0UL, 1)] + [TestCase("0x600160005560006000556001600055", 40218UL, 19800UL, 0)] + [TestCase("0x600060005560016000556000600055", 10218UL, 19800UL, 1)] + public void Test(string codeHex, ulong gasUsed, ulong refund, byte originalValue) { TestState.CreateAccount(Recipient, 0); TestState.Set(new StorageCell(Recipient, 0), new[] { originalValue }); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1344Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1344Tests.cs index 5fbf62e1927b..d497eea285a6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1344Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1344Tests.cs @@ -12,7 +12,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip1344Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; [Test] @@ -26,7 +26,7 @@ public void Chain_id_opcode_puts_expected_value_onto_the_stack() .Op(Instruction.SSTORE) .Done; TestAllTracerWithOutput result = Execute(code); - long setCost = expectedChainId == 0 ? GasCostOf.SStoreNetMeteredEip2200 : GasCostOf.SSet; + ulong setCost = expectedChainId == 0 ? GasCostOf.SStoreNetMeteredEip2200 : GasCostOf.SSet; Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); AssertGas(result, 21000 + GasCostOf.VeryLow + GasCostOf.Base + setCost); AssertStorage(0, ((UInt256)expectedChainId).ToBigEndian()); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip145Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip145Tests.cs index 1278e06d3dfe..950473575434 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip145Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip145Tests.cs @@ -14,7 +14,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip145Tests : VirtualMachineTestsBase { - protected override long BlockNumber => 1; + protected override ulong BlockNumber => 1; protected override ISpecProvider SpecProvider => new CustomSpecProvider( ((ForkActivation)0, Byzantium.Instance), ((ForkActivation)1, Constantinople.Instance)); @@ -27,8 +27,8 @@ private void AssertEip145(TestAllTracerWithOutput receipt, ReadOnlySpan re AssertGas(receipt, result.IsZero() ? ZeroResultGas : NonZeroResultGas); } - private const long ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SStoreNetMeteredEip1283; - private const long NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; + private const ulong ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SStoreNetMeteredEip1283; + private const ulong NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; // SHL test cases [TestCase(Instruction.SHL, "0x0000000000000000000000000000000000000000000000000000000000000001", "0x00", "0x0000000000000000000000000000000000000000000000000000000000000001")] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs index dae7f1845b30..82af46f840c9 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs @@ -12,7 +12,11 @@ namespace Nethermind.Evm.Test; public class Eip152Tests : VirtualMachineTestsBase { private const int InputLength = 213; - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber + _blockNumberAdjustment; + + protected override ulong BlockNumber => + _blockNumberAdjustment >= 0 + ? MainnetSpecProvider.IstanbulBlockNumber + (ulong)_blockNumberAdjustment + : MainnetSpecProvider.IstanbulBlockNumber - (ulong)-_blockNumberAdjustment; private int _blockNumberAdjustment; @@ -38,7 +42,9 @@ public void after_istanbul() byte[] code = Prepare.EvmCode .CallWithInput(Blake2FPrecompile.Address, 1000L, new byte[InputLength]) .Done; + TestAllTracerWithOutput result = Execute(code); + Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1884Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1884Tests.cs index d4f8855a69f7..a0a2f7c61416 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1884Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1884Tests.cs @@ -14,7 +14,7 @@ namespace Nethermind.Evm.Test { public class Eip1884Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; private TestAllTracerWithOutput Execute(bool isIstanbul, byte[] code) => @@ -55,7 +55,7 @@ public void after_istanbul_selfbalance_opcode_puts_current_address_balance_onto_ [TestCase(true, GasCostOf.ExtCodeHashEip1884)] [TestCase(false, GasCostOf.ExtCodeHash)] - public void Extcodehash_cost_depends_on_istanbul(bool isIstanbul, long expectedOpGasCost) + public void Extcodehash_cost_depends_on_istanbul(bool isIstanbul, ulong expectedOpGasCost) { TestState.CreateAccount(TestItem.AddressC, 100.Ether); @@ -70,7 +70,7 @@ public void Extcodehash_cost_depends_on_istanbul(bool isIstanbul, long expectedO [TestCase(true, GasCostOf.BalanceEip1884)] [TestCase(false, GasCostOf.BalanceEip150)] - public void Balance_cost_depends_on_istanbul(bool isIstanbul, long expectedOpGasCost) + public void Balance_cost_depends_on_istanbul(bool isIstanbul, ulong expectedOpGasCost) { TestState.CreateAccount(TestItem.AddressC, 100.Ether); @@ -85,7 +85,7 @@ public void Balance_cost_depends_on_istanbul(bool isIstanbul, long expectedOpGas [TestCase(true, GasCostOf.SLoadEip1884)] [TestCase(false, GasCostOf.SLoadEip150)] - public void Sload_cost_depends_on_istanbul(bool isIstanbul, long expectedOpGasCost) + public void Sload_cost_depends_on_istanbul(bool isIstanbul, ulong expectedOpGasCost) { TestState.CreateAccount(TestItem.AddressC, 100.Ether); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2028Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2028Tests.cs index dfc775d82349..31f8f6b9e66b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2028Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2028Tests.cs @@ -13,12 +13,12 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip2028Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; protected override ISpecProvider SpecProvider => new CustomSpecProvider(((ForkActivation)0, Istanbul.Instance)); [TestCase(true, GasCostOf.TxDataNonZeroEip2028, Description = "After Istanbul non-zero cost is 16")] [TestCase(false, GasCostOf.TxDataNonZero, Description = "Before Istanbul non-zero cost is 68")] - public void Non_zero_transaction_data_cost(bool isIstanbul, long expectedNonZeroCost) + public void Non_zero_transaction_data_cost(bool isIstanbul, ulong expectedNonZeroCost) { IReleaseSpec spec = isIstanbul ? Istanbul.Instance diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs index 7629c4453f62..dca34d16c187 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs @@ -14,59 +14,59 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip2200Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; - [TestCase("0x60006000556000600055", 1612, 0, 0)] - [TestCase("0x60006000556001600055", 20812, 0, 0)] - [TestCase("0x60016000556000600055", 20812, 19200, 0)] - [TestCase("0x60016000556002600055", 20812, 0, 0)] - [TestCase("0x60016000556001600055", 20812, 0, 0)] - [TestCase("0x60006000556000600055", 5812, 15000, 1)] - [TestCase("0x60006000556001600055", 5812, 4200, 1)] - [TestCase("0x60006000556002600055", 5812, 0, 1)] - [TestCase("0x60026000556000600055", 5812, 15000, 1)] - [TestCase("0x60026000556003600055", 5812, 0, 1)] - [TestCase("0x60026000556001600055", 5812, 4200, 1)] - [TestCase("0x60026000556002600055", 5812, 0, 1)] - [TestCase("0x60016000556000600055", 5812, 15000, 1)] - [TestCase("0x60016000556002600055", 5812, 0, 1)] - [TestCase("0x60016000556001600055", 1612, 0, 1)] - [TestCase("0x600160005560006000556001600055", 40818, 19200, 0)] - [TestCase("0x600060005560016000556000600055", 10818, 19200, 1)] - public void Test(string codeHex, long gasUsed, long refund, byte originalValue) + [TestCase("0x60006000556000600055", 1612UL, 0, 0)] + [TestCase("0x60006000556001600055", 20812UL, 0, 0)] + [TestCase("0x60016000556000600055", 20812UL, 19200, 0)] + [TestCase("0x60016000556002600055", 20812UL, 0, 0)] + [TestCase("0x60016000556001600055", 20812UL, 0, 0)] + [TestCase("0x60006000556000600055", 5812UL, 15000, 1)] + [TestCase("0x60006000556001600055", 5812UL, 4200, 1)] + [TestCase("0x60006000556002600055", 5812UL, 0, 1)] + [TestCase("0x60026000556000600055", 5812UL, 15000, 1)] + [TestCase("0x60026000556003600055", 5812UL, 0, 1)] + [TestCase("0x60026000556001600055", 5812UL, 4200, 1)] + [TestCase("0x60026000556002600055", 5812UL, 0, 1)] + [TestCase("0x60016000556000600055", 5812UL, 15000, 1)] + [TestCase("0x60016000556002600055", 5812UL, 0, 1)] + [TestCase("0x60016000556001600055", 1612UL, 0, 1)] + [TestCase("0x600160005560006000556001600055", 40818UL, 19200, 0)] + [TestCase("0x600060005560016000556000600055", 10818UL, 19200, 1)] + public void Test(string codeHex, ulong gasUsed, long refund, byte originalValue) { SetupStorage(originalValue); TestAllTracerWithOutput receipt = Execute(Bytes.FromHexString(codeHex)); - AssertGas(receipt, gasUsed + GasCostOf.Transaction - Math.Min((gasUsed + GasCostOf.Transaction) / 2, refund)); + AssertGas(receipt, gasUsed + GasCostOf.Transaction - Math.Min((gasUsed + GasCostOf.Transaction) / 2, (ulong)refund)); } - [TestCase("0x60006000556000600055", 1612, 0, 2300, true)] - [TestCase("0x60016000556000600055", 20812, 0, 2300, true)] - [TestCase("0x60016000556002600055", 20812, 0, 2300, true)] - [TestCase("0x60016000556001600055", 20812, 0, 2300, true)] - [TestCase("0x60006000556000600055", 5812, 1, 2300, true)] - [TestCase("0x60006000556001600055", 5812, 1, 2300, true)] - [TestCase("0x60026000556000600055", 5812, 1, 2300, true)] - [TestCase("0x60026000556003600055", 5812, 1, 2300, true)] - [TestCase("0x60026000556001600055", 5812, 1, 2300, true)] - [TestCase("0x60026000556002600055", 5812, 1, 2300, true)] - [TestCase("0x60016000556001600055", 1612, 1, 2300, true)] - [TestCase("0x60006000556002600055", 5812, 1, 2300, true)] - [TestCase("0x60016000556000600055", 5812, 1, 2300, false)] - [TestCase("0x60016000556002600055", 5812, 1, 2300, false)] - [TestCase("0x600160005560006000556001600055", 40818, 0, 2300, false)] - [TestCase("0x600060005560016000556000600055", 10818, 1, 2300, false)] - [TestCase("0x60006000556001600055", 20812, 0, 2300, false)] - [TestCase("0x60006000556000600055", 1612, 0, 2301, false)] - [TestCase("0x60016000556001600055", 1612, 1, 2301, false)] - [TestCase("0x60006000556000600055", 1612, 0, 2299, true)] - [TestCase("0x60016000556001600055", 1612, 1, 2299, true)] - public void Test_at_stipend_boundary(string codeHex, long gasUsed, byte originalValue, int stipend, bool outOfGasExpected) + [TestCase("0x60006000556000600055", 1612UL, 0, 2300, true)] + [TestCase("0x60016000556000600055", 20812UL, 0, 2300, true)] + [TestCase("0x60016000556002600055", 20812UL, 0, 2300, true)] + [TestCase("0x60016000556001600055", 20812UL, 0, 2300, true)] + [TestCase("0x60006000556000600055", 5812UL, 1, 2300, true)] + [TestCase("0x60006000556001600055", 5812UL, 1, 2300, true)] + [TestCase("0x60026000556000600055", 5812UL, 1, 2300, true)] + [TestCase("0x60026000556003600055", 5812UL, 1, 2300, true)] + [TestCase("0x60026000556001600055", 5812UL, 1, 2300, true)] + [TestCase("0x60026000556002600055", 5812UL, 1, 2300, true)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2300, true)] + [TestCase("0x60006000556002600055", 5812UL, 1, 2300, true)] + [TestCase("0x60016000556000600055", 5812UL, 1, 2300, false)] + [TestCase("0x60016000556002600055", 5812UL, 1, 2300, false)] + [TestCase("0x600160005560006000556001600055", 40818UL, 0, 2300, false)] + [TestCase("0x600060005560016000556000600055", 10818UL, 1, 2300, false)] + [TestCase("0x60006000556001600055", 20812UL, 0, 2300, false)] + [TestCase("0x60006000556000600055", 1612UL, 0, 2301, false)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2301, false)] + [TestCase("0x60006000556000600055", 1612UL, 0, 2299, true)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2299, true)] + public void Test_at_stipend_boundary(string codeHex, ulong gasUsed, byte originalValue, int stipend, bool outOfGasExpected) { SetupStorage(originalValue); - TestAllTracerWithOutput receipt = Execute(BlockNumber, 21000 + gasUsed + (stipend - 800), Bytes.FromHexString(codeHex)); + TestAllTracerWithOutput receipt = Execute(BlockNumber, 21000 + gasUsed + (ulong)(stipend - 800), Bytes.FromHexString(codeHex)); Assert.That(receipt.StatusCode, Is.EqualTo(outOfGasExpected ? 0 : 1)); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2315Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2315Tests.cs index 7e51b61cce91..826f605d8a98 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2315Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2315Tests.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm.Test { public class Eip2315Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.BerlinBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.BerlinBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; [TestCase("0x60045e005c5d", Description = "Simple routine")] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs index 6bd3b00ff696..da7128624c39 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm.Test; public class Eip2537Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => (ulong)((long)MainnetSpecProvider.PragueBlockTimestamp + _timestampAdjustment); private long _timestampAdjustment; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2929Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2929Tests.cs index d9e5fef14972..0329fe4b3e12 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2929Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2929Tests.cs @@ -15,14 +15,14 @@ namespace Nethermind.Evm.Test /// public class Eip2929Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.BerlinBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.BerlinBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; - [TestCase("0x60013f5060023b506003315060f13f5060f23b5060f3315060f23f5060f33b5060f1315032315030315000", 8653)] - [TestCase("0x60006000600060ff3c60006000600060ff3c600060006000303c00", 2835)] - [TestCase("0x60015450601160015560116002556011600255600254600154", 44529)] - [TestCase("0x60008080808060046000f15060008080808060ff6000f15060008080808060ff6000fa50", 2869)] - public void Eip2929_gas_cost(string codeHex, long expectedGasExcludingTx) + [TestCase("0x60013f5060023b506003315060f13f5060f23b5060f3315060f23f5060f33b5060f1315032315030315000", 8653ul)] + [TestCase("0x60006000600060ff3c60006000600060ff3c600060006000303c00", 2835ul)] + [TestCase("0x60015450601160015560116002556011600255600254600154", 44529ul)] + [TestCase("0x60008080808060046000f15060008080808060ff6000f15060008080808060ff6000fa50", 2869ul)] + public void Eip2929_gas_cost(string codeHex, ulong expectedGasExcludingTx) { TestState.CreateAccount(TestItem.AddressC, 100.Ether); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2935Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2935Tests.cs index d18acb1a3e3d..edabfc645d19 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2935Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2935Tests.cs @@ -15,7 +15,7 @@ namespace Nethermind.Evm.Test; [TestFixture] public class Eip2935Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.PragueBlockTimestamp; @@ -32,7 +32,7 @@ public override void Setup() [TestCase(MainnetSpecProvider.PragueBlockTimestamp)] public void CorrectBlockhashBeingUsed(ulong timestamp) { - const long blockNumber = 256; + const ulong blockNumber = 256; byte[] bytecode = Prepare.EvmCode .PushData(blockNumber) @@ -49,7 +49,7 @@ public void CorrectBlockhashBeingUsed(ulong timestamp) CallOutputTracer callOutputTracer = new(); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(new ForkActivation(BlockNumber, timestamp))), callOutputTracer); - long expected = blockNumber; + ulong expected = blockNumber; Assert.That(callOutputTracer.ReturnValue!, Is.EqualTo(Keccak.Compute(expected.ToString()).BytesToArray())); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs index fbae2a2c9213..809efd35990b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs @@ -33,12 +33,12 @@ public void Base_fee_opcode_should_return_expected_results(bool eip3198Enabled, .Op(Instruction.SSTORE) .Done; - long blockNumber = eip3198Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; - (Block block, Transaction transaction) = PrepareTx((blockNumber, 0), 100000, code); + ulong blockNumber = eip3198Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; + (Block block, Transaction transaction) = PrepareTx((blockNumber, 0UL), 100000UL, code); block.Header.BaseFeePerGas = (UInt256)baseFee; if (send1559Tx) { - transaction.DecodedMaxFeePerGas = (UInt256)baseFee; + transaction.DecodedMaxFeePerGas = (ulong)baseFee; transaction.Type = TxType.EIP1559; } else diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs index f02f4acbdfef..c07c34ef08c4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs @@ -21,45 +21,40 @@ namespace Nethermind.Evm.Test public class Eip3529Tests : VirtualMachineTestsBase { - [TestCase("0x60006000556000600055", 212, 0, 0)] - [TestCase("0x60006000556001600055", 20112, 0, 0)] - [TestCase("0x60016000556000600055", 20112, 19900, 0)] - [TestCase("0x60016000556002600055", 20112, 0, 0)] - [TestCase("0x60016000556001600055", 20112, 0, 0)] - [TestCase("0x60006000556000600055", 3012, 15000, 1)] - [TestCase("0x60006000556001600055", 3012, 2800, 1)] - [TestCase("0x60006000556002600055", 3012, 0, 1)] - [TestCase("0x60026000556000600055", 3012, 15000, 1)] - [TestCase("0x60026000556003600055", 3012, 0, 1)] - [TestCase("0x60026000556001600055", 3012, 2800, 1)] - [TestCase("0x60026000556002600055", 3012, 0, 1)] - [TestCase("0x60016000556000600055", 3012, 15000, 1)] - [TestCase("0x60016000556002600055", 3012, 0, 1)] - [TestCase("0x60016000556001600055", 212, 0, 1)] - [TestCase("0x600160005560006000556001600055", 40118, 19900, 0)] - [TestCase("0x600060005560016000556000600055", 5918, 17800, 1)] - public void Before_introducing_eip3529(string codeHex, long gasUsed, long refund, byte originalValue) => Test(codeHex, gasUsed, refund, originalValue, false); - - [TestCase("0x60006000556000600055", 212, 0, 0)] - [TestCase("0x60006000556001600055", 20112, 0, 0)] - [TestCase("0x60016000556000600055", 20112, 19900, 0)] - [TestCase("0x60016000556002600055", 20112, 0, 0)] - [TestCase("0x60016000556001600055", 20112, 0, 0)] - [TestCase("0x60006000556000600055", 3012, 4800, 1)] - [TestCase("0x60006000556001600055", 3012, 2800, 1)] - [TestCase("0x60006000556002600055", 3012, 0, 1)] - [TestCase("0x60026000556000600055", 3012, 4800, 1)] - [TestCase("0x60026000556003600055", 3012, 0, 1)] - [TestCase("0x60026000556001600055", 3012, 2800, 1)] - [TestCase("0x60026000556002600055", 3012, 0, 1)] - [TestCase("0x60016000556000600055", 3012, 4800, 1)] - [TestCase("0x60016000556002600055", 3012, 0, 1)] - [TestCase("0x60016000556001600055", 212, 0, 1)] - [TestCase("0x600160005560006000556001600055", 40118, 19900, 0)] - [TestCase("0x600060005560016000556000600055", 5918, 7600, 1)] - public void After_introducing_eip3529(string codeHex, long gasUsed, long refund, byte originalValue) => Test(codeHex, gasUsed, refund, originalValue, true); - - private void Test(string codeHex, long gasUsed, long refund, byte originalValue, bool eip3529Enabled) + [TestCase("0x60006000556000600055", 3012UL, 15000UL, 1)] + [TestCase("0x60006000556001600055", 3012UL, 2800UL, 1)] + [TestCase("0x60006000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60026000556000600055", 3012UL, 15000UL, 1)] + [TestCase("0x60026000556003600055", 3012UL, 0UL, 1)] + [TestCase("0x60026000556001600055", 3012UL, 2800UL, 1)] + [TestCase("0x60026000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60016000556000600055", 3012UL, 15000UL, 1)] + [TestCase("0x60016000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60016000556001600055", 212UL, 0UL, 1)] + [TestCase("0x600160005560006000556001600055", 40118UL, 19900UL, 0)] + [TestCase("0x600060005560016000556000600055", 5918UL, 17800UL, 1)] + public void Before_introducing_eip3529(string codeHex, ulong gasUsed, ulong refund, byte originalValue) => Test(codeHex, gasUsed, refund, originalValue, false); + + [TestCase("0x60006000556000600055", 212UL, 0UL, 0)] + [TestCase("0x60006000556001600055", 20112UL, 0UL, 0)] + [TestCase("0x60016000556000600055", 20112UL, 19900UL, 0)] + [TestCase("0x60016000556002600055", 20112UL, 0UL, 0)] + [TestCase("0x60016000556001600055", 20112UL, 0UL, 0)] + [TestCase("0x60006000556000600055", 3012UL, 4800UL, 1)] + [TestCase("0x60006000556001600055", 3012UL, 2800UL, 1)] + [TestCase("0x60006000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60026000556000600055", 3012UL, 4800UL, 1)] + [TestCase("0x60026000556003600055", 3012UL, 0UL, 1)] + [TestCase("0x60026000556001600055", 3012UL, 2800UL, 1)] + [TestCase("0x60026000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60016000556000600055", 3012UL, 4800UL, 1)] + [TestCase("0x60016000556002600055", 3012UL, 0UL, 1)] + [TestCase("0x60016000556001600055", 212UL, 0UL, 1)] + [TestCase("0x600160005560006000556001600055", 40118UL, 19900UL, 0)] + [TestCase("0x600060005560016000556000600055", 5918UL, 7600UL, 1)] + public void After_introducing_eip3529(string codeHex, ulong gasUsed, ulong refund, byte originalValue) => Test(codeHex, gasUsed, refund, originalValue, true); + + private void Test(string codeHex, ulong gasUsed, ulong refund, byte originalValue, bool eip3529Enabled) { // the account value = 1.Ether here because you cannot set a storageRoot for an empty account. // EmptyAccount => Balance.IsZero && Nonce == _accountStartNonce && CodeHash == Keccak.OfAnEmptyString @@ -70,7 +65,7 @@ private void Test(string codeHex, long gasUsed, long refund, byte originalValue, TestState.Set(new StorageCell(Recipient, 0), new[] { originalValue }); TestState.Commit(eip3529Enabled ? London.Instance : Berlin.Instance); _processor = new EthereumTransactionProcessor(BlobBaseFeeCalculator.Instance, SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); - long blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; + ulong blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; (Block block, Transaction transaction) = PrepareTx(blockNumber, 100000, Bytes.FromHexString(codeHex)); transaction.GasPrice = 20.GWei; @@ -78,7 +73,9 @@ private void Test(string codeHex, long gasUsed, long refund, byte originalValue, _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); Assert.That(tracer.Refund, Is.EqualTo(refund)); - AssertGas(tracer, gasUsed + GasCostOf.Transaction - Math.Min((gasUsed + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), refund)); + ulong uGasUsed = gasUsed; + ulong uRefund = refund; + AssertGas(tracer, uGasUsed + GasCostOf.Transaction - Math.Min((uGasUsed + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), uRefund)); } [TestCase(true)] @@ -140,7 +137,7 @@ public void After_3529_self_destruct_has_zero_refund(bool eip3529Enabled) .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; - long gasLimit = 1000000; + ulong gasLimit = 1000000; EthereumEcdsa ecdsa = new(1); // deploy create 2 @@ -151,9 +148,9 @@ public void After_3529_self_destruct_has_zero_refund(bool eip3529Enabled) Transaction tx2 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // self destruct contract Transaction tx3 = Build.A.Transaction.WithCode(byteCode2).WithGasLimit(gasLimit).WithNonce(3).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; - int gasUsedByTx3 = 37767; + uint gasUsedByTx3 = 37839; - long blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; + ulong blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx0, tx1, tx2, tx3).WithGasLimit(2 * gasLimit).TestObject; ParityLikeTxTracer tracer0 = new(block, tx0, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); @@ -168,10 +165,12 @@ public void After_3529_self_destruct_has_zero_refund(bool eip3529Enabled) tracer = CreateTracer(); _processor.Execute(tx3, blCtx, tracer); - long expectedRefund = eip3529Enabled ? 0 : 24000; + ulong expectedRefund = eip3529Enabled ? 0UL : 24000UL; Assert.That(tracer.Refund, Is.EqualTo(expectedRefund)); - AssertGas(tracer, gasUsedByTx3 + GasCostOf.Transaction - Math.Min((gasUsedByTx3 + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), expectedRefund)); + ulong uGasUsedByTx3 = gasUsedByTx3; + ulong uExpectedRefund = expectedRefund; + AssertGas(tracer, uGasUsedByTx3 + GasCostOf.Transaction - Math.Min((uGasUsedByTx3 + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), uExpectedRefund)); } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs index 262e8aadf146..4d358550e829 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs @@ -84,7 +84,7 @@ void DeployCodeAndAssertTx(string code, bool eip3541Enabled, ContractDeployment _ => byteCode, }; _processor = new EthereumTransactionProcessor(BlobBaseFeeCalculator.Instance, SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); - long blockNumber = eip3541Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; + ulong blockNumber = eip3541Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; (Block block, Transaction transaction) = PrepareTx(blockNumber, 100000, createContract); transaction.GasPrice = 20.GWei; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3651Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3651Tests.cs index daf3f19e82f0..bac330a26bfb 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3651Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3651Tests.cs @@ -14,7 +14,7 @@ namespace Nethermind.Evm.Test ///
public class Eip3651Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.ShanghaiBlockTimestamp; [Test] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs index 5f4f24452a1a..3ac0fdc25f29 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip3855Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.ShanghaiBlockTimestamp; private TestAllTracerWithOutput testBase(int repeat, bool isShanghai) @@ -35,7 +35,7 @@ public void Test_Eip3855_should_pass(int repeat, bool isShanghai) { TestAllTracerWithOutput receipt = testBase(repeat, isShanghai); Assert.That(receipt.StatusCode, Is.EqualTo(StatusCode.Success)); - Assert.That(receipt.GasSpent, Is.EqualTo(repeat * GasCostOf.Base + GasCostOf.Transaction)); + Assert.That(receipt.GasSpent, Is.EqualTo((ulong)repeat * GasCostOf.Base + GasCostOf.Transaction)); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3860Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3860Tests.cs index 2e6c8c2f5cff..d70ca78eca3a 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3860Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3860Tests.cs @@ -9,16 +9,15 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; namespace Nethermind.Evm.Test { public class Eip3860Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.ShanghaiBlockTimestamp; - private readonly long _transactionCallCost = GasCostOf.Transaction + 100 + 7 * GasCostOf.VeryLow; + private readonly ulong _transactionCallCost = GasCostOf.Transaction + 100 + 7 * GasCostOf.VeryLow; [TestCase("0x61013860006000f0", false, 32039)] //length 312 [TestCase("0x61013860006000f0", true, 32059)] //extra 20 cost @@ -67,7 +66,7 @@ public void Test_EIP_3860_InitCode_Create_Exceeds_Limit(string createCode) Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.ReportedActionErrors.Count, Is.EqualTo(1)); Assert.That(tracer.ReportedActionErrors[0], Is.EqualTo(EvmExceptionType.OutOfGas)); - Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo((UInt256)0)); + Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo(0)); Assert.That(tracer.GasSpent, Is.EqualTo(_transactionCallCost + contractCreationGasLimit)); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip4844Tests.cs index 02bce97ef3f3..1eb70f26acd4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip4844Tests.cs @@ -12,7 +12,7 @@ namespace Nethermind.Evm.Test; [TestFixture] public class Eip4844Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.CancunBlockTimestamp; [TestCase(0, 0, Description = "Should return 0 when no hashes")] @@ -34,7 +34,7 @@ public void Test_blobhash_index_in_range(int index, int blobhashesCount) byte[] expectedOutput = blobhashesCount > index ? hashes[index] : new byte[32]; // Cost of transaction call + PUSH1 x4 + MSTORE (entry cost + 1 memory cell used) - const long gasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 5 + GasCostOf.Memory; + const ulong gasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 5 + GasCostOf.Memory; byte[] code = Prepare.EvmCode .PushData(new UInt256((ulong)index)) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip6780Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip6780Tests.cs index 474a3b1dd1de..6268f420473f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip6780Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip6780Tests.cs @@ -33,13 +33,13 @@ namespace Nethermind.Evm.Test [TestFixture] public class Eip6780Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.CancunBlockTimestamp; private byte[] _selfDestructCode; private Address _contractAddress; private byte[] _initCode; - private readonly long _gasLimit = 1000000; + private readonly ulong _gasLimit = 1000000; private readonly EthereumEcdsa _ecdsa = new(1); [SetUp] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7623Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7623Tests.cs index 11d3d56db9b3..9c644a8f6df8 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7623Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7623Tests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm.Test; [TestFixture] public class Eip7623Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.PragueBlockTimestamp; [Test] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7708Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7708Tests.cs index bb3fa2ab3ddc..61b3fe6d87a4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7708Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7708Tests.cs @@ -52,7 +52,7 @@ public async Task SimpleTransfer_EmitsLogs(ulong transferValue, int expectedLogC { BasicTestBlockchain chain = await CreateChain(); - UInt256 nonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); + ulong nonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); Transaction tx = Build.A.Transaction .WithTo(TestItem.AddressB) @@ -73,7 +73,7 @@ public async Task Subcall_WithValueTransfer_EmitsTransferLogs(ulong innerValue) { BasicTestBlockchain chain = await CreateChain(); - UInt256 senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); + ulong senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); // Contract that calls another address with value Address targetAddress = TestItem.AddressC; @@ -119,7 +119,7 @@ public async Task SelfDestruct_ToDifferentAccount_EmitsTransferLog(ulong contrac { BasicTestBlockchain chain = await CreateChain(); - UInt256 senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); + ulong senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); // Contract that self-destructs to a different address (inheritor) Address inheritor = TestItem.AddressC; @@ -166,7 +166,7 @@ public async Task SelfDestruct_ToSelf_NoOp_EmitsNoLog(ulong contractBalance) // is a complete no-op — no destruction, no ETH movement, no log. BasicTestBlockchain chain = await CreateChain(); - UInt256 senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); + ulong senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); // Calculate contract address first - we need it for the selfdestruct target Address contractAddress = ContractAddress.From(TestItem.AddressA, senderNonce); @@ -211,7 +211,7 @@ public async Task SelfDestruct_ThenReceivesEth_EmitsLogs() { BasicTestBlockchain chain = await CreateChain(); - UInt256 senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); + ulong senderNonce = chain.StateReader.GetNonce(chain.BlockTree.Head!.Header, TestItem.AddressA); // Contract A: self-destructs to inheritor only when called with zero value. // When called with value, it just accepts the ETH without self-destructing again. diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7778Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7778Tests.cs index 35941aec1d09..9ae55a765247 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7778Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7778Tests.cs @@ -106,9 +106,9 @@ public void Receipt_uses_post_refund_gas_when_eip7778_enabled() [Test] public void GasConsumed_struct_tracks_block_gas_separately() { - long spentGas = 21000; - long operationGas = 20000; - long blockGas = 25000; + ulong spentGas = 21000UL; + ulong operationGas = 20000UL; + ulong blockGas = 25000UL; GasConsumed gasConsumed = new(spentGas, operationGas, blockGas); @@ -121,33 +121,33 @@ public void GasConsumed_struct_tracks_block_gas_separately() [Test] public void GasConsumed_effective_block_gas_uses_spent_gas_when_block_gas_is_zero() { - long spentGas = 21000; - long operationGas = 20000; + ulong spentGas = 21000UL; + ulong operationGas = 20000UL; GasConsumed gasConsumed = new(spentGas, operationGas); - Assert.That(gasConsumed.BlockGas, Is.EqualTo(0)); + Assert.That(gasConsumed.BlockGas, Is.EqualTo(0UL)); Assert.That(gasConsumed.EffectiveBlockGas, Is.EqualTo(spentGas)); } [Test] - public void GasConsumed_implicit_conversion_from_long() + public void GasConsumed_implicit_conversion_from_ulong() { - long gas = 21000; + ulong gas = 21000UL; GasConsumed gasConsumed = gas; Assert.That(gasConsumed.SpentGas, Is.EqualTo(gas)); Assert.That(gasConsumed.OperationGas, Is.EqualTo(gas)); - Assert.That(gasConsumed.BlockGas, Is.EqualTo(0)); + Assert.That(gasConsumed.BlockGas, Is.EqualTo(0UL)); } [Test] - public void GasConsumed_implicit_conversion_to_long() + public void GasConsumed_implicit_conversion_to_ulong() { - GasConsumed gasConsumed = new(21000, 20000, 25000); - long gas = gasConsumed; + GasConsumed gasConsumed = new(21000UL, 20000UL, 25000UL); + ulong gas = gasConsumed; - Assert.That(gas, Is.EqualTo(21000)); + Assert.That(gas, Is.EqualTo(21000UL)); } [Test] @@ -477,8 +477,8 @@ public void Transaction_allowance_uses_post_refund_receipt_gas_when_eip7778_enab Assert.That(result1, Is.EqualTo(TransactionResult.Ok)); - long blockGasAfterTx1 = block.Header.GasUsed; - long receiptGasAfterTx1 = tracer.TxReceipts[0].GasUsedTotal; + ulong blockGasAfterTx1 = block.Header.GasUsed; + ulong receiptGasAfterTx1 = tracer.TxReceipts[0].GasUsedTotal; Assert.That(blockGasAfterTx1, Is.GreaterThan(receiptGasAfterTx1), "First transaction should create a refund gap between block gas and receipt gas"); block.Header.GasLimit = blockGasAfterTx1 + GasCostOf.Transaction - 1; @@ -534,7 +534,7 @@ public void Multiple_transactions_cumulative_gas_uses_post_refund_values() _processor.Execute(tx1, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); tracer.EndTxTrace(); - long blockGasAfterTx1 = block.Header.GasUsed; + ulong blockGasAfterTx1 = block.Header.GasUsed; TxReceipt receipt1 = tracer.TxReceipts[0]; // Prepare and execute second transaction (no refund) @@ -640,7 +640,7 @@ public void Restore_after_multiple_transactions_maintains_correct_gas_tracking() // Take snapshot after first tx int snapshotAfterTx1 = tracer.TakeSnapshot(); - long blockGasAfterTx1 = block.Header.GasUsed; + ulong blockGasAfterTx1 = block.Header.GasUsed; TxReceipt receipt1 = tracer.TxReceipts[0]; // Execute second transaction @@ -696,7 +696,7 @@ public void Double_restore_works_correctly() // Snapshot 1 (after tx1) int snapshot1 = tracer.TakeSnapshot(); - long gasAfterTx1 = block.Header.GasUsed; + ulong gasAfterTx1 = block.Header.GasUsed; // Execute tx2 (call to Recipient which has code deployed) Transaction tx2 = Build.A.Transaction diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7843Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7843Tests.cs index 9a911b042608..4c27aa334918 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7843Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7843Tests.cs @@ -12,13 +12,13 @@ namespace Nethermind.Evm.Test; [TestFixture] public class Eip7843Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.AmsterdamBlockTimestamp; [Test] public void SLOTNUMTest() { - const long GasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 4 + GasCostOf.Memory; + const ulong GasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 4 + GasCostOf.Memory; const ulong SlotNumber = 1000; byte[] code = Prepare.EvmCode diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs index 3ed5dee52692..65c009c9f96d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs @@ -40,13 +40,13 @@ namespace Nethermind.Evm.Test; [TestFixture(true)] public class Eip7928Tests(bool parallel) : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.AmsterdamBlockTimestamp; private static readonly EthereumEcdsa _ecdsa = new(0); private static readonly UInt256 _accountBalance = 10.Ether; private static readonly UInt256 _testAccountBalance = 1.Ether; - private static readonly long _gasLimit = 150000; + private static readonly ulong _gasLimit = 150000; private static readonly Address _testAddress = ContractAddress.From(TestItem.AddressA, 0); private static readonly Address _callTargetAddress = TestItem.AddressC; private static readonly Address _delegationTargetAddress = TestItem.AddressD; @@ -87,14 +87,14 @@ private static IEnumerable SelfdestructSendToSenderTestSource() return (tracedState, processor); } - private static Transaction BuildContractTx(byte[] code, long executionGas, UInt256 value, BlockHeader header) + private static Transaction BuildContractTx(byte[] code, ulong executionGas, UInt256 value, BlockHeader header) { Transaction templateTx = Build.A.Transaction .WithCode(code) .WithGasLimit(0) .WithValue(value) .TestObject; - long intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, header.GasLimit).MinimalGas; + ulong intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, header.GasLimit).MinimalGas; return Build.A.Transaction .WithCode(code) @@ -170,7 +170,7 @@ private Transaction BuildSetCodeCallTx(Address to, params AuthorizationTuple[] a .TestObject; } - private void AddAccountToState(Address address, UInt256 nonce = default, byte[]? code = null, UInt256 balance = default) + private void AddAccountToState(Address address, ulong nonce = default, byte[]? code = null, UInt256 balance = default) { TestState.CreateAccount(address, balance, nonce); if (code is not null) @@ -355,7 +355,7 @@ private AuthorizationTuple SignAuthorization(PrivateKey signer, Address codeAddr return ecdsa.Sign(signer, SpecProvider.ChainId, codeAddress, nonce); } - private static Transaction BuildCallTx(Address to, UInt256 value = default, UInt256 nonce = default) => + private static Transaction BuildCallTx(Address to, UInt256 value = default, ulong nonce = default) => Build.A.Transaction .To(to) .WithNonce(nonce) @@ -430,7 +430,7 @@ public async Task Constructs_BAL_when_processing_code( .WithGasLimit(0) .WithValue(value) .TestObject; - long gasLimit = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas + _gasLimit; + ulong gasLimit = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas + _gasLimit; Transaction createTx = Build.A.Transaction .WithCode(code) @@ -442,7 +442,7 @@ public async Task Constructs_BAL_when_processing_code( CallOutputTracer callOutputTracer = new(); TransactionResult res = processor.Execute(createTx, callOutputTracer); BlockAccessListAtIndex bal = tracedState.GetGeneratingBlockAccessList()!; - UInt256 gasUsed = new((ulong)callOutputTracer.GasSpent); + UInt256 gasUsed = new(callOutputTracer.GasSpent); UInt256 newBalance = _accountBalance - gasUsed; // With EIP-8037's higher CostPerStateByte, some CREATE/SELFDESTRUCT cases now run out @@ -481,7 +481,7 @@ public async Task Constructs_BAL_when_processing_code_exception( IEnumerable expected, byte[] code, byte[]? extraCode, - long executionGas, + ulong executionGas, EvmExceptionType expectedException) { InitWorldState(TestState, extraCode); @@ -494,8 +494,8 @@ public async Task Constructs_BAL_when_processing_code_exception( .WithGasLimit(0) .WithValue(_testAccountBalance) .TestObject; - long intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas; - long gasLimit = intrinsicGas + executionGas; + ulong intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas; + ulong gasLimit = intrinsicGas + executionGas; Transaction createTx = Build.A.Transaction .WithCode(code) @@ -507,7 +507,7 @@ public async Task Constructs_BAL_when_processing_code_exception( CallOutputTracer callOutputTracer = new(); TransactionResult res = processor.Execute(createTx, callOutputTracer); BlockAccessListAtIndex bal = tracedState.GetGeneratingBlockAccessList()!; - UInt256 gasUsed = new((ulong)callOutputTracer.GasSpent); + UInt256 gasUsed = new(callOutputTracer.GasSpent); ReadOnlyAccountChanges accountChangesA = Build.An.AccountChanges .WithAddress(TestItem.AddressA) @@ -942,7 +942,7 @@ public void Eip7928_create2_selfdestruct_then_recreate_same_block_records_fresh_ InitWorldState(TestState, factoryCode); Transaction firstTx = BuildCallTx(_callTargetAddress, value: (UInt256)firstCreateBalance); - Transaction secondTx = BuildCallTx(_callTargetAddress, nonce: UInt256.One); + Transaction secondTx = BuildCallTx(_callTargetAddress, nonce: 1); // Two tx slices need to merge into a single BlockAccessListAtIndex view for the // per-tx assertion shape; ExecuteCallTxs materialises that combined slice. @@ -989,7 +989,7 @@ public void Eip7928_selfdestruct_to_sender_coalesces_sender_changes(IReleaseSpec CallOutputTracer tracer = new(); TransactionResult res = processor.Execute(tx, tracer); BlockAccessListAtIndex bal = tracedState.GetGeneratingBlockAccessList()!; - UInt256 gasUsed = new((ulong)tracer.GasSpent); + UInt256 gasUsed = (UInt256)tracer.GasSpent; AccountChangesAtIndex? senderChanges = bal.GetAccountChanges(TestItem.AddressA); AccountChangesAtIndex? victimChanges = bal.GetAccountChanges(_callTargetAddress); @@ -1136,13 +1136,13 @@ public void Call_into_7702_delegated_eoa_oog_at_delegation_cold_access_does_not_ .WithCode(code) .WithGasLimit(0) .TestObject; - long intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas; + ulong intrinsicGas = IntrinsicGasCalculator.Calculate(templateTx, Amsterdam.Instance, block.Header.GasLimit).MinimalGas; // Enough gas to push CALL operands and reach the cold-access charge for the EOA, but // 1 gas short of the cold-access charge for its delegation target. CALL pushes 7 stack // operands (3 each of GasCostOf.VeryLow), pays GasCostOf.Call, then ConsumeAccountAccessGas // for codeSource (cold), then for delegated (cold) — we cap at codeSource cold + 1 short. - long pushOperandsCost = 7 * GasCostOf.VeryLow; - long executionGas = pushOperandsCost + GasCostOf.Call + GasCostOf.ColdAccountAccess + GasCostOf.WarmStateRead - 1; + ulong pushOperandsCost = 7 * GasCostOf.VeryLow; + ulong executionGas = pushOperandsCost + GasCostOf.Call + GasCostOf.ColdAccountAccess + GasCostOf.WarmStateRead - 1; Transaction tx = Build.A.Transaction .WithCode(code) @@ -1167,9 +1167,9 @@ public void Call_into_7702_delegated_eoa_oog_at_delegation_cold_access_does_not_ } } - [TestCase(120_000_000L, 30_000_000L, true, TestName = "EIP2935_system_call_records_storage_change_when_state_gas_affordable")] - [TestCase(120_000_000L, 30_000L, false, TestName = "EIP2935_system_call_records_no_storage_access_when_state_gas_not_affordable")] - public void Eip2935_system_call_bal_respects_eip8037_state_gas(long blockGasLimit, long systemCallGasLimit, bool shouldStoreParentHash) + [TestCase(120_000_000ul, 30_000_000ul, true, TestName = "EIP2935_system_call_records_storage_change_when_state_gas_affordable")] + [TestCase(120_000_000ul, 30_000ul, false, TestName = "EIP2935_system_call_records_no_storage_access_when_state_gas_not_affordable")] + public void Eip2935_system_call_bal_respects_eip8037_state_gas(ulong blockGasLimit, ulong systemCallGasLimit, bool shouldStoreParentHash) { InitWorldState(TestState); @@ -1190,7 +1190,7 @@ public void Eip2935_system_call_bal_respects_eip8037_state_gas(long blockGasLimi GasPrice = header.BaseFeePerGas, SenderAddress = Address.SystemUser, To = Eip2935Constants.BlockHashHistoryAddress, - Value = UInt256.Zero, + Value = 0ul, }; systemCall.Hash = systemCall.CalculateHash(); @@ -1977,7 +1977,7 @@ public void Tx_exceeding_block_gas_limit_rejected_in_parallel_mode() TestState.CreateAccount(TestItem.AddressA, 10.Ether); TestState.Commit(SpecProvider.GenesisSpec); - long blockGasLimit = 100_000; + ulong blockGasLimit = 100_000ul; BlockHeader header = Build.A.BlockHeader .WithGasLimit(blockGasLimit) .WithNumber(1) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7939Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7939Tests.cs index cf7dc6870929..8b525b599431 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7939Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7939Tests.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm.Test; public class Eip7939Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.OsakaBlockTimestamp; public static IEnumerable> Tests @@ -38,7 +38,7 @@ public static IEnumerable> Tests [TestCaseSource(nameof(Tests))] public int CLZTest(UInt256 value) { - const long gasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 5 + GasCostOf.Memory; + const ulong gasCostOfCallingWrapper = GasCostOf.Transaction + GasCostOf.VeryLow * 5 + GasCostOf.Memory; byte[] code = Prepare.EvmCode .PushData(value) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7954Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7954Tests.cs index f9537d97b64c..a90f9fac3ab5 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7954Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7954Tests.cs @@ -15,7 +15,7 @@ namespace Nethermind.Evm.Test; public class Eip7954Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.AmsterdamBlockTimestamp; [Test] diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7976Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7976Tests.cs index 8a7b21da1781..be52cee33e2d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7976Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7976Tests.cs @@ -21,22 +21,22 @@ public class Eip7976Tests // Standard: 21000 + zero*4 + nonzero*16 (+ 32000 + InitCodeWord for contract creation) private static IEnumerable IntrinsicGasCases() { - yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 1 }, 21_016L, 21_064L) + yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 1 }, 21_016UL, 21_064UL) .SetName("EIP-7976: single nonzero byte"); - yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 0 }, 21_004L, 21_064L) + yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 0 }, 21_004UL, 21_064UL) .SetName("EIP-7976: single zero byte"); - yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 0, 0, 1, 1 }, 21_040L, 21_256L) + yield return new TestCaseData(Eip7976Spec, Address.Zero, new byte[] { 0, 0, 1, 1 }, 21_040UL, 21_256UL) .SetName("EIP-7976: mixed data"); - yield return new TestCaseData(Eip7976Spec, Address.Zero, Array.Empty(), 21_000L, 21_000L) + yield return new TestCaseData(Eip7976Spec, Address.Zero, Array.Empty(), 21_000UL, 21_000UL) .SetName("EIP-7976: empty data"); - yield return new TestCaseData(Eip7976Spec, null, new byte[] { 1 }, 53_018L, 21_064L) + yield return new TestCaseData(Eip7976Spec, null, new byte[] { 1 }, 53_018UL, 21_064UL) .SetName("EIP-7976: contract creation standard exceeds floor"); - yield return new TestCaseData(Prague.Instance, Address.Zero, new byte[] { 0 }, 21_004L, 21_010L) + yield return new TestCaseData(Prague.Instance, Address.Zero, new byte[] { 0 }, 21_004UL, 21_010UL) .SetName("EIP-7623 fallback: single zero byte"); } [TestCaseSource(nameof(IntrinsicGasCases))] - public void Intrinsic_gas_calculation(IReleaseSpec spec, Address? to, byte[] data, long expectedStandard, long expectedFloor) + public void Intrinsic_gas_calculation(IReleaseSpec spec, Address? to, byte[] data, ulong expectedStandard, ulong expectedFloor) { Transaction transaction = new() { Data = data, To = to }; EthereumIntrinsicGas cost = IntrinsicGasCalculator.Calculate(transaction, spec); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7981Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7981Tests.cs index b73ffbaf4a08..af66830b184e 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7981Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7981Tests.cs @@ -19,31 +19,32 @@ namespace Nethermind.Evm.Test; public class Eip7981Tests { private static readonly IReleaseSpec Spec = new OverridableReleaseSpec(Amsterdam.Instance) { IsEip7976Enabled = true, IsEip7981Enabled = true }; - private static long FloorPerToken => Spec.GasCosts.TotalCostFloorPerToken; + private static ulong FloorPerToken => Spec.GasCosts.TotalCostFloorPerToken; private static IEnumerable AccessListOnlyCases() { // 20 bytes × 4 = 80 tokens yield return new TestCaseData( - new AccessList.Builder().AddAddress(Address.Zero).Build(), 80L + new AccessList.Builder().AddAddress(Address.Zero).Build(), 80UL ).SetName("Single zero address: 80 tokens"); yield return new TestCaseData( - new AccessList.Builder().AddAddress(new Address("0xAB000000000000000000000000000000000000CD")).Build(), 80L + new AccessList.Builder().AddAddress(new Address("0xAB000000000000000000000000000000000000CD")).Build(), 80UL ).SetName("Address with non-zero bytes: 80 tokens"); // Address (80) + storage key (32 * 4 = 128) = 208 tokens yield return new TestCaseData( - new AccessList.Builder().AddAddress(Address.Zero).AddStorage(UInt256.Zero).Build(), 208L + new AccessList.Builder().AddAddress(Address.Zero).AddStorage(UInt256.Zero).Build(), 208UL ).SetName("Address + zero storage key: 208 tokens"); + // Address + non-zero storage key: 208 tokens yield return new TestCaseData( - new AccessList.Builder().AddAddress(Address.Zero).AddStorage(UInt256.One).Build(), 208L + new AccessList.Builder().AddAddress(Address.Zero).AddStorage(UInt256.One).Build(), 208UL ).SetName("Address + non-zero storage key: 208 tokens"); // Two addresses: 2 * 80 = 160 tokens yield return new TestCaseData( - new AccessList.Builder().AddAddress(Address.Zero).AddAddress(new Address("0x0000000000000000000000000000000000000001")).Build(), 160L + new AccessList.Builder().AddAddress(Address.Zero).AddAddress(new Address("0x0000000000000000000000000000000000000001")).Build(), 160UL ).SetName("Two addresses: 160 tokens"); // 1 address (80) + 3 keys (3 × 128 = 384) = 464 tokens @@ -53,27 +54,27 @@ private static IEnumerable AccessListOnlyCases() .AddStorage(UInt256.Zero) .AddStorage(UInt256.One) .AddStorage(new UInt256(255)) - .Build(), 464L + .Build(), 464UL ).SetName("Address + 3 storage keys: 464 tokens"); // Empty access list: no addresses, no keys → 0 tokens yield return new TestCaseData( - new AccessList.Builder().Build(), 0L + new AccessList.Builder().Build(), 0UL ).SetName("Empty access list: 0 tokens"); } [TestCaseSource(nameof(AccessListOnlyCases))] - public void Access_list_token_pricing(AccessList accessList, long expectedTokens) + public void Access_list_token_pricing(AccessList accessList, ulong expectedTokens) { Transaction transaction = new() { To = Address.Zero, AccessList = accessList }; EthereumIntrinsicGas cost = IntrinsicGasCalculator.Calculate(transaction, Spec); (int addressCount, int storageKeyCount) = accessList.Count; - long expectedStandard = GasCostOf.Transaction - + addressCount * GasCostOf.AccessAccountListEntry - + storageKeyCount * GasCostOf.AccessStorageListEntry + ulong expectedStandard = GasCostOf.Transaction + + (ulong)addressCount * GasCostOf.AccessAccountListEntry + + (ulong)storageKeyCount * GasCostOf.AccessStorageListEntry + FloorPerToken * expectedTokens; - long expectedFloor = GasCostOf.Transaction + FloorPerToken * expectedTokens; + ulong expectedFloor = GasCostOf.Transaction + FloorPerToken * expectedTokens; Assert.That(cost, Is.EqualTo(new EthereumIntrinsicGas(Standard: expectedStandard, FloorGas: expectedFloor))); } @@ -104,30 +105,30 @@ private static IEnumerable CalldataWithAccessListCases() // 1 zero byte + 1 address: standard wins // Standard = 21000 + 4 + 2400 + 80*16 = 24684 // Floor = 21000 + (4 + 80)*16 = 22344 - yield return new TestCaseData(new byte[] { 0 }, 1, 0, 24684L, 22344L) + yield return new TestCaseData(new byte[] { 0 }, 1, 0, 24684UL, 22344UL) .SetName("1 zero byte + 1 address: standard wins"); // 40 zero bytes + 1 address: exact tie (floor == standard) // Standard = 21000 + 40*4 + 2400 + 1280 = 24840 // Floor = 21000 + (160 + 80)*16 = 24840 - yield return new TestCaseData(new byte[40], 1, 0, 24840L, 24840L) + yield return new TestCaseData(new byte[40], 1, 0, 24840UL, 24840UL) .SetName("40 zero bytes + 1 address: exact tie"); // 41 zero bytes + 1 address: floor wins by 60 (smallest count) // Standard = 21000 + 41*4 + 2400 + 1280 = 24844 // Floor = 21000 + (164 + 80)*16 = 24904 - yield return new TestCaseData(new byte[41], 1, 0, 24844L, 24904L) + yield return new TestCaseData(new byte[41], 1, 0, 24844UL, 24904UL) .SetName("41 zero bytes + 1 address: floor wins by 60"); // 100 zero bytes + 1 address + 1 key: floor dominates // Standard = 21000 + 400 + 2400 + 1900 + (80+128)*16 = 29028 // Floor = 21000 + (400 + 80 + 128)*16 = 30728 - yield return new TestCaseData(new byte[100], 1, 1, 29028L, 30728L) + yield return new TestCaseData(new byte[100], 1, 1, 29028UL, 30728UL) .SetName("100 zero bytes + 1 address + 1 key: floor dominates"); } [TestCaseSource(nameof(CalldataWithAccessListCases))] - public void Calldata_with_access_list_floor_pricing(byte[] data, int addressCount, int storageKeyCount, long expectedStandard, long expectedFloor) + public void Calldata_with_access_list_floor_pricing(byte[] data, int addressCount, int storageKeyCount, ulong expectedStandard, ulong expectedFloor) { AccessList.Builder builder = new(); for (int i = 0; i < addressCount; i++) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs index deece35a8c7c..51bdedc986b5 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs @@ -16,7 +16,7 @@ namespace Nethermind.Evm.Test; ///
public class Eip8024Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.OsakaBlockTimestamp; protected override ISpecProvider SpecProvider => new TestSpecProvider(new Osaka { IsEip8024Enabled = true }); @@ -124,7 +124,7 @@ public void InvalidOperation_Fails(byte[] code) private static IEnumerable GasCostTestCases() { - static long Gas(int pushCount) => GasCostOf.Transaction + GasCostOf.VeryLow * pushCount + GasCostOf.VeryLow; + static ulong Gas(int pushCount) => GasCostOf.Transaction + GasCostOf.VeryLow * (ulong)pushCount + GasCostOf.VeryLow; yield return new TestCaseData(PushNValues(20).Op(Instruction.DUPN).Data(0x80).Op(Instruction.STOP).Done, Gas(20)).SetName("DupN_GasCost"); yield return new TestCaseData(PushNValues(20).Op(Instruction.SWAPN).Data(0x80).Op(Instruction.STOP).Done, Gas(20)).SetName("SwapN_GasCost"); @@ -132,7 +132,7 @@ private static IEnumerable GasCostTestCases() } [TestCaseSource(nameof(GasCostTestCases))] - public void Opcode_CostsVeryLowGas(byte[] code, long expectedGas) + public void Opcode_CostsVeryLowGas(byte[] code, ulong expectedGas) { TestAllTracerWithOutput result = Execute(Activation, 100000, code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -162,7 +162,7 @@ public void EipTestVector_JumpOverInvalidDupn_Succeeds() public class Eip8024DisabledTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.OsakaBlockTimestamp; protected override ISpecProvider SpecProvider => new TestSpecProvider(new Osaka() { IsEip8024Enabled = false }); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs index 23074d114ed8..e607076c3512 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs @@ -12,12 +12,12 @@ namespace Nethermind.Evm.Test; [TestFixture] public class Eip8037BlockGasInclusionCheckTests { - private const long CostPerStateByte = 1530; - private const long GasNewAccount = 120; // EIP-8037 GAS_NEW_ACCOUNT - private const long IntrinsicNewAccountState = GasNewAccount * CostPerStateByte; - private const long BaseIntrinsicRegular = 21_000; - private const long CreateIntrinsicRegular = 53_000; - private const long SStoreStateGas = 64 * CostPerStateByte; // GasCostOf.SSetState + private const ulong CostPerStateByte = 1530; + private const ulong GasNewAccount = 120; // EIP-8037 GAS_NEW_ACCOUNT + private const ulong IntrinsicNewAccountState = GasNewAccount * CostPerStateByte; + private const ulong BaseIntrinsicRegular = 21_000; + private const ulong CreateIntrinsicRegular = 53_000; + private const ulong SStoreStateGas = 64 * CostPerStateByte; // GasCostOf.SSetState [TestCase(0L, Eip8037BlockGasInclusionCheck.Outcome.Ok, TestName = "Boundary_state_exact_fit_accepts")] [TestCase(1L, Eip8037BlockGasInclusionCheck.Outcome.StateDimensionExceeded, TestName = "Boundary_state_exceeded_by_one_rejects_on_state_dimension")] @@ -26,14 +26,14 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp // tx1: 50 cold SSTOREs in regular cap budget. Reproduces the spec test // setup: tx1_state = num_sstores * sstore_state_gas; tx1_gas = cap + tx1_state. const int numSstores = 50; - long tx1State = numSstores * SStoreStateGas; - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + tx1State + 100_000; + ulong tx1State = numSstores * SStoreStateGas; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + tx1State + 100_000; - long cumR_afterTx1 = BaseIntrinsicRegular + 5_000; - long cumS_afterTx1 = tx1State; + ulong cumR_afterTx1 = BaseIntrinsicRegular + 5_000; + ulong cumS_afterTx1 = tx1State; - long stateAvailable = blockGasLimit - cumS_afterTx1; - long tx2Gas = BaseIntrinsicRegular + stateAvailable + delta; + ulong stateAvailable = blockGasLimit - cumS_afterTx1; + ulong tx2Gas = (ulong)((long)(BaseIntrinsicRegular + stateAvailable) + delta); Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, cumR_afterTx1, cumS_afterTx1, tx2Gas, BaseIntrinsicRegular, intrinsicState: 0); @@ -45,19 +45,19 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp [Test] public void Creation_tx_regular_check_subtracts_intrinsic_state_accepts() { - long intrinsicState = IntrinsicNewAccountState; - long intrinsicRegular = CreateIntrinsicRegular; - long intrinsicTotal = intrinsicRegular + intrinsicState; + ulong intrinsicState = IntrinsicNewAccountState; + ulong intrinsicRegular = CreateIntrinsicRegular; + ulong intrinsicTotal = intrinsicRegular + intrinsicState; // Filler consumed full cap. Remaining regular = intrinsic_regular + 1. - long remainingRegular = intrinsicRegular + 1; - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + remainingRegular; - long cumR_afterFiller = blockGasLimit - remainingRegular; - long cumS_afterFiller = 0; + ulong remainingRegular = intrinsicRegular + 1; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + remainingRegular; + ulong cumR_afterFiller = blockGasLimit - remainingRegular; + ulong cumS_afterFiller = 0; // Creation tx: tx.gas = intrinsic_total. Raw tx.gas > remaining_regular // but tx.gas - intrinsic_state = intrinsic_regular <= remaining_regular. - long createTxGas = intrinsicTotal; + ulong createTxGas = intrinsicTotal; Assert.That(createTxGas, Is.GreaterThan(remainingRegular), "old formula must reject -> proves new formula behaves differently"); @@ -74,12 +74,12 @@ public void Creation_tx_regular_check_subtracts_intrinsic_state_accepts() [Test] public void Single_tx_state_check_exceeds_block_limit_rejects() { - long intrinsicRegular = BaseIntrinsicRegular; - long intrinsicState = 0; // plain CALL, not creation + ulong intrinsicRegular = BaseIntrinsicRegular; + ulong intrinsicState = 0; // plain CALL, not creation - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100; // tx.gas - intrinsic.regular > block_gas_limit - long txGas = blockGasLimit + intrinsicRegular + 1; + ulong txGas = blockGasLimit + intrinsicRegular + 1; Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, 0, 0, txGas, intrinsicRegular, intrinsicState); @@ -91,23 +91,23 @@ public void Single_tx_state_check_exceeds_block_limit_rejects() [Test] public void Creation_tx_state_check_exceeded_rejects_on_state_dimension() { - long createIntrinsicState = IntrinsicNewAccountState; - long createIntrinsicRegular = CreateIntrinsicRegular; + ulong createIntrinsicState = IntrinsicNewAccountState; + ulong createIntrinsicRegular = CreateIntrinsicRegular; const int numSstores = 50; - long tx1State = numSstores * SStoreStateGas; - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + tx1State + 100_000; + ulong tx1State = numSstores * SStoreStateGas; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + tx1State + 100_000; - long cumR_afterTx1 = BaseIntrinsicRegular + 5_000; - long cumS_afterTx1 = tx1State; - long stateAvailable = blockGasLimit - cumS_afterTx1; + ulong cumR_afterTx1 = BaseIntrinsicRegular + 5_000; + ulong cumS_afterTx1 = tx1State; + ulong stateAvailable = blockGasLimit - cumS_afterTx1; // tx2 (creation): state contribution = state_available + 1 -> reject - long createTxGas = createIntrinsicRegular + stateAvailable + 1; + ulong createTxGas = createIntrinsicRegular + stateAvailable + 1; // Regular dimension check must pass so rejection is pinned to state. - long regularAvailable = blockGasLimit - cumR_afterTx1; - long worstCaseRegular = System.Math.Min(Eip7825Constants.DefaultTxGasLimitCap, createTxGas - createIntrinsicState); + ulong regularAvailable = blockGasLimit - cumR_afterTx1; + ulong worstCaseRegular = Math.Min(Eip7825Constants.DefaultTxGasLimitCap, createTxGas - createIntrinsicState); Assert.That(worstCaseRegular, Is.LessThanOrEqualTo(regularAvailable), "regular check must pass so rejection is pinned to state dimension"); @@ -121,15 +121,15 @@ public void Creation_tx_state_check_exceeded_rejects_on_state_dimension() [Test] public void Regular_check_caps_worst_case_at_tx_max_gas_limit() { - long blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100; // tiny headroom - long intrinsicRegular = BaseIntrinsicRegular; - long intrinsicState = 0; + ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + 100; // tiny headroom + ulong intrinsicRegular = BaseIntrinsicRegular; + ulong intrinsicState = 0; // Pick tx.gas so that (tx.gas - intrinsic.state) >> TX_MAX_GAS_LIMIT but the cap // brings worst-case regular back down to TX_MAX_GAS_LIMIT, which fits exactly. - long txGas = Eip7825Constants.DefaultTxGasLimitCap * 10; - long cumR = 0; - long cumS = 0; + ulong txGas = Eip7825Constants.DefaultTxGasLimitCap * 10; + ulong cumR = 0; + ulong cumS = 0; Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, cumR, cumS, txGas, intrinsicRegular, intrinsicState); @@ -173,21 +173,21 @@ public void Calculate_block_regular_gas_keeps_valid_transcripts_non_negative() Random random = new(8037); for (int i = 0; i < 2_000; i++) { - long intrinsicRegular = random.Next(21_000, 500_000); - long initialRegular = random.Next(0, 5_000_000); - long spentRegular = random.Next(0, (int)Math.Min(initialRegular, int.MaxValue)) + (initialRegular > int.MaxValue ? random.Next(0, 2) : 0); + ulong intrinsicRegular = (ulong)random.Next(21_000, 500_000); + ulong initialRegular = (ulong)random.Next(0, 5_000_000); + ulong spentRegular = (ulong)random.Next(0, (int)Math.Min(initialRegular, int.MaxValue)) + (initialRegular > int.MaxValue ? (ulong)random.Next(0, 2) : 0ul); if (spentRegular > initialRegular) { spentRegular = initialRegular; } - long stateGasSpill = random.Next(0, (int)Math.Min(spentRegular, int.MaxValue)); - long stateGasSpillReclassified = random.Next(0, (int)Math.Min(stateGasSpill, int.MaxValue)); - long remainingRegular = initialRegular - spentRegular; - long floorGas = random.Next(21_000, 200_000); + ulong stateGasSpill = (ulong)random.Next(0, (int)Math.Min(spentRegular, int.MaxValue)); + ulong stateGasSpillReclassified = (ulong)random.Next(0, (int)Math.Min(stateGasSpill, int.MaxValue)); + ulong remainingRegular = initialRegular - spentRegular; + ulong floorGas = (ulong)random.Next(21_000, 200_000); - long executionRegularGasUsed = initialRegular - remainingRegular - stateGasSpill + stateGasSpillReclassified; - long blockRegularGas = Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( + ulong executionRegularGasUsed = initialRegular - remainingRegular - stateGasSpill + stateGasSpillReclassified; + ulong blockRegularGas = Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( intrinsicRegular, initialRegular, remainingRegular, @@ -195,7 +195,7 @@ public void Calculate_block_regular_gas_keeps_valid_transcripts_non_negative() stateGasSpillReclassified, floorGas); - Assert.That(executionRegularGasUsed, Is.GreaterThanOrEqualTo(0L)); + Assert.That(executionRegularGasUsed, Is.GreaterThanOrEqualTo(0ul)); Assert.That(blockRegularGas, Is.EqualTo(Math.Max(intrinsicRegular + executionRegularGasUsed, floorGas))); } } @@ -204,14 +204,14 @@ public void Calculate_block_regular_gas_keeps_valid_transcripts_non_negative() [TestCase(0L, 0L, TestName = "Calculate_block_regular_gas_allows_negative_execution_intermediate")] public void Calculate_block_regular_gas_clamps_to_floor(long initialRegular, long remainingRegular) { - long blockRegularGas = Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( + ulong blockRegularGas = Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( intrinsicRegularGas: 21_000, - initialRegularGas: initialRegular, - remainingRegularGas: remainingRegular, + initialRegularGas: (ulong)initialRegular, + remainingRegularGas: (ulong)remainingRegular, stateGasSpill: 200, stateGasSpillReclassified: 0, floorGas: 53_000); - Assert.That(blockRegularGas, Is.EqualTo(53_000)); + Assert.That(blockRegularGas, Is.EqualTo(53_000ul)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037RegressionTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037RegressionTests.cs index 6ad35c3744bc..3d01fd79c08f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037RegressionTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037RegressionTests.cs @@ -28,7 +28,7 @@ public enum SelfDestructBeneficiaryKind Nonexistent } - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.AmsterdamBlockTimestamp; private static Prepare BuildCreateFactory(byte[] initCode, UInt256 value, bool create2, byte[]? salt = null) => @@ -66,7 +66,7 @@ public void Eip8037_rejects_tx_when_calldata_floor_exceeds_tx_max_regular_gas() Assert.That(result.TransactionExecuted, Is.False); Assert.That(result.Error, Is.EqualTo(TransactionResult.ErrorType.GasLimitBelowIntrinsicGas)); - Assert.That(TestState.GetNonce(Sender), Is.EqualTo(UInt256.Zero)); + Assert.That(TestState.GetNonce(Sender), Is.Zero); } /// @@ -111,7 +111,7 @@ public void Eip8037_nested_create_code_deposit_must_not_borrow_parent_regular_ga // Child: 1540 gas -> 9 for init code -> 1531 remaining for code deposit // Factory post-CREATE: 12 gas (PUSH, MSTORE, PUSH, PUSH, RETURN) // Total: 21000 + 21 + 192602 + 1564 = 215187 - long gasLimit = 215187; + ulong gasLimit = 215187; TestAllTracerWithOutput tracer = Execute(Activation, gasLimit, factoryCode, blockGasLimit: DynamicStatePricingBlockGasLimit); @@ -169,7 +169,7 @@ public void Eip8037_code_deposit_failure_must_keep_initcode_state_gas_in_state_d .Op(Instruction.RETURN) .Done; - long gasLimit = 1_000_000; + ulong gasLimit = 1_000_000ul; (Block block, Transaction transaction) = PrepareTx(Activation, gasLimit, initCode, value: 1, blockGasLimit: DynamicStatePricingBlockGasLimit); transaction.To = null; @@ -211,7 +211,7 @@ public void Eip8037_oversized_initcode_create_must_keep_create_state_out_of_bloc .Done; byte[] oversizedInitCode = new byte[(int)Spec.MaxInitCodeSize + 1]; - long gasLimit = Eip7825Constants.DefaultTxGasLimitCap + GasCostOf.CreateState; + ulong gasLimit = Eip7825Constants.DefaultTxGasLimitCap + GasCostOf.CreateState; (Block block, Transaction transaction) = PrepareTx(Activation, gasLimit, createFromCalldataCode, oversizedInitCode, UInt256.Zero); block.Header.GasLimit = DynamicStatePricingBlockGasLimit; @@ -280,8 +280,8 @@ public void Eip8037_authorization_refund_excludes_existing_authority_from_block_ TestAllTracerWithOutput tracer = CreateTracer(); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); - long expectedAuthorizationStateGas = GasCostOf.PerAuthBaseState; - long expectedPaidGas = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular + GasCostOf.PerAuthBaseState; + ulong expectedAuthorizationStateGas = GasCostOf.PerAuthBaseState; + ulong expectedPaidGas = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular + GasCostOf.PerAuthBaseState; Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.GasConsumedResult.SpentGas, Is.EqualTo(expectedPaidGas)); @@ -381,7 +381,7 @@ public void Eip8037_top_level_halt_must_refund_reverted_create_state_gas() TestAllTracerWithOutput tracer = CreateTracer(); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); - long refundedStateGas = 3 * GasCostOf.CreateState; + ulong refundedStateGas = 3ul * GasCostOf.CreateState; Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Failure)); Assert.That(tracer.GasConsumedResult.SpentGas, Is.EqualTo(gasLimit - refundedStateGas)); @@ -519,7 +519,7 @@ public void Eip8037_create_in_static_context_must_not_charge_state_gas_or_increm Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.Zero); - Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo(UInt256.Zero)); + Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo(0ul)); Assert.That(TestState.AccountExists(createdAddress), Is.False); } @@ -549,7 +549,7 @@ public void Eip8037_static_create_followed_by_parent_sstore_must_not_leak_create Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(GasCostOf.SSetState)); Assert.That(TestState.Get(new StorageCell(Recipient, 0)).ToArray(), Is.EqualTo(new byte[] { 0 })); Assert.That(TestState.Get(new StorageCell(Recipient, 1)).ToArray(), Is.EqualTo(new byte[] { 1 })); - Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo(UInt256.Zero)); + Assert.That(TestState.GetNonce(TestItem.AddressC), Is.EqualTo(0ul)); Assert.That(TestState.AccountExists(createdAddress), Is.False); } @@ -590,7 +590,7 @@ public void Eip8037_delegatecall_sstore_restoration_refund_credits_local_reservo Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(GasCostOf.CreateState + GasCostOf.SSetState)); - Assert.That(TestState.GetNonce(Recipient), Is.EqualTo(UInt256.One)); + Assert.That(TestState.GetNonce(Recipient), Is.EqualTo(1ul)); AssertStorage(new StorageCell(Recipient, 0), UInt256.Zero); AssertStorage(new StorageCell(Recipient, 1), UInt256.Zero); AssertStorage(new StorageCell(Recipient, 2), UInt256.One); @@ -759,7 +759,7 @@ public void Eip8037_exceptional_halt_must_restore_child_inline_state_refund() .Op(Instruction.INVALID) .Done; - long gasLimit = Eip7825Constants.DefaultTxGasLimitCap + GasCostOf.SSetState; + ulong gasLimit = Eip7825Constants.DefaultTxGasLimitCap + GasCostOf.SSetState; TestAllTracerWithOutput tracer = Execute(Activation, gasLimit, code, blockGasLimit: DynamicStatePricingBlockGasLimit); Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Failure)); @@ -848,8 +848,8 @@ public void Eip8037_block_validation_must_not_use_header_max_gas_used_as_remaini block.Header.GasUsed = Math.Max(tracer.CumulativeRegularGasUsed, tracer.GasConsumedResult.BlockStateGas); - long legacyRemaining = block.Header.GasLimit - block.Header.GasUsed; - long secondTxGasLimit = legacyRemaining + 1; + ulong legacyRemaining = block.Header.GasLimit - block.Header.GasUsed; + ulong secondTxGasLimit = legacyRemaining + 1ul; SenderRecipientAndMiner secondParticipants = new() { @@ -915,7 +915,7 @@ public void Eip8037_block_validation_must_allow_tx_gas_limit_above_remaining_reg value: zeroValue, blockGasLimit: blockGasLimit); - long secondTxGasLimit = blockGasLimit - GasCostOf.Transaction + 1; + ulong secondTxGasLimit = blockGasLimit - GasCostOf.Transaction + 1ul; (_, Transaction secondTx) = PrepareTx( Activation, secondTxGasLimit, @@ -970,7 +970,7 @@ public void Eip8037_selfdestruct_to_new_beneficiary_charges_state_gas_only_for_b TestAllTracerWithOutput tracer = CreateTracer(); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); - long expectedStateGas = fundContract ? GasCostOf.NewAccountState : 0; + ulong expectedStateGas = fundContract ? GasCostOf.NewAccountState : 0ul; Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(expectedStateGas)); @@ -1009,7 +1009,7 @@ public void Eip8037_selfdestruct_to_new_beneficiary_state_gas_does_not_depend_on public void Eip8037_same_tx_created_selfdestruct_to_new_beneficiary_keeps_created_account_state_gas( bool create2, int createdBalance, - long expectedStateGas) + ulong expectedStateGas) { Address beneficiary = TestItem.AddressC; byte[] childInitCode = Prepare.EvmCode @@ -1052,7 +1052,7 @@ public void Eip8037_selfdestruct_to_same_tx_created_beneficiary_must_not_charge_ TestAllTracerWithOutput tracer = Execute(Activation, 1_000_000, factoryCode, blockGasLimit: DynamicStatePricingBlockGasLimit); - long expectedStateGas = 2 * GasCostOf.CreateState + GasCostOf.CodeDepositState; + ulong expectedStateGas = 2ul * GasCostOf.CreateState + GasCostOf.CodeDepositState; Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(expectedStateGas)); @@ -1106,7 +1106,7 @@ public void Eip8037_same_tx_selfdestruct_must_not_refund_code_deposit_state_gas( TestAllTracerWithOutput tracer = Execute(Activation, 600_000, factoryCode, blockGasLimit: DynamicStatePricingBlockGasLimit); Assert.That(tracer.StatusCode, Is.EqualTo(StatusCode.Success)); - Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(GasCostOf.CreateState + selfDestructRuntime.Length * GasCostOf.CodeDepositState), + Assert.That(tracer.GasConsumedResult.BlockStateGas, Is.EqualTo(GasCostOf.CreateState + (ulong)selfDestructRuntime.Length * GasCostOf.CodeDepositState), "CREATE account state and code-deposit state gas should not be refunded after same-tx SELFDESTRUCT."); Assert.That(TestState.AccountExists(createdAddress), Is.False); } @@ -1161,7 +1161,7 @@ public void Eip8037_top_level_create_selfdestruct_must_keep_intrinsic_create_sta public void Eip8037_create_tx_selfdestruct_initcode_keeps_create_state_gas( ulong txValue, SelfDestructBeneficiaryKind beneficiaryKind, - long expectedStateGas) + ulong expectedStateGas) { Address contractAddress = ContractAddress.From(Sender, 0); Address beneficiary = beneficiaryKind switch @@ -1205,9 +1205,9 @@ public void Eip8037_create_tx_selfdestruct_initcode_keeps_create_state_gas( Assert.That(block.Header.GasUsed, Is.EqualTo(Math.Max(tracer.GasConsumedResult.EffectiveBlockGas, expectedStateGas))); } - [TestCase(16_777_216L, TestName = "Eip8037_subcall_set_clear_revert_pays_no_state_gas_spill")] - [TestCase(16_875_136L, TestName = "Eip8037_subcall_set_clear_revert_pays_no_state_gas_reservoir")] - public void Eip8037_subcall_set_clear_revert_pays_no_state_gas(long gasLimit) + [TestCase(16_777_216ul, TestName = "Eip8037_subcall_set_clear_revert_pays_no_state_gas_spill")] + [TestCase(16_875_136ul, TestName = "Eip8037_subcall_set_clear_revert_pays_no_state_gas_reservoir")] + public void Eip8037_subcall_set_clear_revert_pays_no_state_gas(ulong gasLimit) { byte[] childCode = Bytes.FromHexString("6001600055600060005560006000fd"); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs index c5d7edc66bde..2d4a40e415d1 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs @@ -19,7 +19,7 @@ namespace Nethermind.Evm.Test; public class Eip8037Tests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.AmsterdamBlockTimestamp; private static IEnumerable ConstantsTestCases() @@ -36,21 +36,21 @@ private static IEnumerable ConstantsTestCases() [TestCaseSource(nameof(ConstantsTestCases))] public long Constants_are_calculated_correctly(long actual) => actual; - [TestCase(1, ExpectedResult = 6L)] - [TestCase(32, ExpectedResult = 6L)] - [TestCase(33, ExpectedResult = 12L)] - public long Code_deposit_regular_cost(int codeLength) + [TestCase(1, ExpectedResult = 6ul)] + [TestCase(32, ExpectedResult = 6ul)] + [TestCase(33, ExpectedResult = 12ul)] + public ulong Code_deposit_regular_cost(int codeLength) { - CodeDepositHandler.CalculateCost(Amsterdam.Instance, codeLength, out long regularCost, out _); + CodeDepositHandler.CalculateCost(Amsterdam.Instance, codeLength, out ulong regularCost, out _); return regularCost; } - [TestCase(1, ExpectedResult = 1530L)] - [TestCase(32, ExpectedResult = 48960L)] - [TestCase(33, ExpectedResult = 50490L)] - public long Code_deposit_state_cost(int codeLength) + [TestCase(1, ExpectedResult = 1530ul)] + [TestCase(32, ExpectedResult = 48960ul)] + [TestCase(33, ExpectedResult = 50490ul)] + public ulong Code_deposit_state_cost(int codeLength) { - CodeDepositHandler.CalculateCost(Amsterdam.Instance, codeLength, out _, out long stateCost); + CodeDepositHandler.CalculateCost(Amsterdam.Instance, codeLength, out _, out ulong stateCost); return stateCost; } @@ -79,7 +79,7 @@ public void System_transaction_gas_keeps_regular_budget_and_state_reservoir() 0L ))); - for (int i = 0; i < Eip8037Constants.SystemMaxSstoresPerCall; i++) + for (ulong i = 0ul; i < Eip8037Constants.SystemMaxSstoresPerCall; i++) { Assert.That(EthereumGasPolicy.ConsumeStateGas(ref availableGas, GasCostOf.SSetState), Is.True); } @@ -107,7 +107,7 @@ public void Regular_transaction_gas_uses_tx_cap_even_when_intrinsic_state_matche }; EthereumGasPolicy availableGas = EthereumGasPolicy.CreateAvailableFromIntrinsic(Eip8037Constants.SystemCallGasLimit, in intrinsicGas, Amsterdam.Instance); - long expectedReservoir = Eip8037Constants.SystemCallGasLimit - Eip8037Constants.SystemCallStateReservoir - Eip7825Constants.DefaultTxGasLimitCap; + ulong expectedReservoir = Eip8037Constants.SystemCallGasLimit - Eip8037Constants.SystemCallStateReservoir - Eip7825Constants.DefaultTxGasLimitCap; Assert.That( ( @@ -149,7 +149,7 @@ public void Generic_code_deposit_cost_uses_fixed_state_pricing() { EthereumGasPolicy gas = default; - bool success = CodeDepositHandler.CalculateCost(Amsterdam.Instance, 33, in gas, out long regularCost, out long stateCost); + bool success = CodeDepositHandler.CalculateCost(Amsterdam.Instance, 33, in gas, out ulong regularCost, out ulong stateCost); Assert.That((success, regularCost, stateCost), Is.EqualTo((true, 12L, GasCostOf.CodeDepositState * 33))); @@ -183,11 +183,11 @@ public void Amsterdam_access_list_floor_pricing_is_added_to_regular_and_floor_in IntrinsicGas splitIntrinsicGas = EthereumGasPolicy.CalculateIntrinsicGas(tx, Amsterdam.Instance); EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, Amsterdam.Instance); - long accessListBaseCost = GasCostOf.AccessAccountListEntry + 3 * GasCostOf.AccessStorageListEntry; - long accessListFloorTokens = (20L + 3 * 32L) * Amsterdam.Instance.GasCosts.TxDataNonZeroMultiplier; - long accessListFloorCost = accessListFloorTokens * Amsterdam.Instance.GasCosts.TotalCostFloorPerToken; - long expectedRegular = GasCostOf.Transaction + accessListBaseCost + accessListFloorCost; - long expectedFloorGas = GasCostOf.Transaction + accessListFloorCost; + ulong accessListBaseCost = GasCostOf.AccessAccountListEntry + 3ul * GasCostOf.AccessStorageListEntry; + ulong accessListFloorTokens = (20ul + 3ul * 32ul) * Amsterdam.Instance.GasCosts.TxDataNonZeroMultiplier; + ulong accessListFloorCost = accessListFloorTokens * Amsterdam.Instance.GasCosts.TotalCostFloorPerToken; + ulong expectedRegular = GasCostOf.Transaction + accessListBaseCost + accessListFloorCost; + ulong expectedFloorGas = GasCostOf.Transaction + accessListFloorCost; Assert.That(splitIntrinsicGas.Standard.Value, Is.EqualTo(expectedRegular)); Assert.That(splitIntrinsicGas.Standard.StateReservoir, Is.Zero); @@ -208,7 +208,7 @@ public void Prague_access_list_floor_pricing_is_not_applied() .TestObject; IntrinsicGas intrinsicGas = EthereumGasPolicy.CalculateIntrinsicGas(tx, Prague.Instance); - long expectedRegular = GasCostOf.Transaction + GasCostOf.AccessAccountListEntry + GasCostOf.AccessStorageListEntry; + ulong expectedRegular = GasCostOf.Transaction + GasCostOf.AccessAccountListEntry + GasCostOf.AccessStorageListEntry; Assert.That(intrinsicGas.Standard.Value, Is.EqualTo(expectedRegular)); Assert.That(intrinsicGas.FloorGas.Value, Is.EqualTo(GasCostOf.Transaction)); @@ -272,14 +272,14 @@ public void State_refund_is_clamped_to_intrinsic_state_floor() [Test] public void Code_insert_state_refund_is_available_to_later_state_gas() { - const long intrinsicAuthState = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; + ulong intrinsicAuthState = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; EthereumGasPolicy gas = new() { Value = 2 * GasCostOf.SSetState - GasCostOf.NewAccountState, StateGasUsed = intrinsicAuthState, }; - long regularRefund = EthereumGasPolicy.ApplyCodeInsertRefunds(ref gas, 1, Amsterdam.Instance, intrinsicAuthState); + ulong regularRefund = EthereumGasPolicy.ApplyCodeInsertRefunds(ref gas, 1, Amsterdam.Instance, intrinsicAuthState); Assert.That(EthereumGasPolicy.ConsumeStateGas(ref gas, GasCostOf.SSetState), Is.True); Assert.That(EthereumGasPolicy.ConsumeStateGas(ref gas, GasCostOf.SSetState), Is.True); @@ -299,8 +299,8 @@ public void Call_depth_exceeded_create_does_not_credit_state_gas_refund() caller: Sender, codeSource: Recipient, callDepth: VirtualMachineStatics.MaxCallDepth, - transferValue: UInt256.Zero, - value: UInt256.Zero, + transferValue: 0ul, + value: 0ul, inputData: ReadOnlyMemory.Empty); EthereumGasPolicy gas = new() { @@ -509,14 +509,14 @@ public void Top_level_halt_block_state_gas_snapshot_captures_spill_only_not_rese "after consuming 5_000 with 1_000 reservoir: reservoir=0, used=5_000 (= 1_000 reservoir-portion + 4_000 spill), spill=4_000"); // CORRECT pattern: snapshot SPILL only (not full StateGasUsed) BEFORE reset. - long preHaltSpill = gas.StateGasSpill; + ulong preHaltSpill = gas.StateGasSpill; Assert.That(preHaltSpill, Is.EqualTo(4_000L), "spill-only snapshot"); EthereumGasPolicy.ResetForHalt(ref gas, initialStateReservoir: 1_000, initialStateGasUsed: 0); // Block-level contribution = post-reset StateGasUsed (intrinsic floor) + pre-halt spill. // The reservoir-portion (1_000) is correctly excluded — that's the refunded portion. - long blockLevelContribution = gas.StateGasUsed + preHaltSpill; + ulong blockLevelContribution = gas.StateGasUsed + preHaltSpill; Assert.That(blockLevelContribution, Is.EqualTo(4_000L), "block-level sum_state contribution = floor (0) + spill (4_000); reservoir-portion (1_000) is refunded"); } @@ -526,21 +526,21 @@ public void Top_level_halt_block_state_gas_overcounts_if_full_state_gas_used_is_ { // Regression-guard: snapshotting full StateGasUsed instead of just spill over-counts // block-level sum_state by the reservoir-portion. - const long reservoirAtTxStart = 100_000; - const long stateGasCharged = GasCostOf.SSetState; + ulong reservoirAtTxStart = 100_000ul; + ulong stateGasCharged = GasCostOf.SSetState; EthereumGasPolicy gas = new() { Value = 1_000_000, StateReservoir = reservoirAtTxStart, StateGasUsed = 0 }; Assert.That(EthereumGasPolicy.ConsumeStateGas(ref gas, stateGasCharged), Is.True); Assert.That(gas.StateGasSpill, Is.EqualTo(0L), "reservoir covers full charge; no spill"); Assert.That(gas.StateGasUsed, Is.EqualTo(stateGasCharged), "full charge recorded in StateGasUsed"); - long wrongSnapshot = gas.StateGasUsed; - long correctSnapshot = gas.StateGasSpill; // = 0 — what the canonical contribution is + ulong wrongSnapshot = gas.StateGasUsed; + ulong correctSnapshot = gas.StateGasSpill; // = 0 — what the canonical contribution is EthereumGasPolicy.ResetForHalt(ref gas, initialStateReservoir: reservoirAtTxStart, initialStateGasUsed: 0); - long blockLevelCorrect = gas.StateGasUsed + correctSnapshot; - long blockLevelWrong = gas.StateGasUsed + wrongSnapshot; + ulong blockLevelCorrect = gas.StateGasUsed + correctSnapshot; + ulong blockLevelWrong = gas.StateGasUsed + wrongSnapshot; Assert.That(blockLevelWrong - blockLevelCorrect, Is.EqualTo(GasCostOf.SSetState), "snapshotting StateGasUsed (instead of StateGasSpill) overcounts block-level sum_state by exactly the reservoir-portion (= 1 SSetState in this case)"); } @@ -553,19 +553,19 @@ public void Top_level_halt_block_state_gas_per_tx_pattern_with_spill() // contribution per halt = floor + spill. Across N halts in a block, sum is // N * (floor + spill). Reading the post-reset StateGasUsed alone (= floor) without // adding spill would undercount by N * spill. - const long perTxGasLimit = 1_000_000; - const long intrinsicStateGas = 0; - const long reservoirAtTxStart = 100_000; - const long stateGasCharged = 104_174; // reservoir(100k) consumed + 4_174 spill + ulong perTxGasLimit = 1_000_000ul; + ulong intrinsicStateGas = 0ul; + ulong reservoirAtTxStart = 100_000ul; + ulong stateGasCharged = 104_174ul; // reservoir(100k) consumed + 4_174 spill EthereumGasPolicy gas = new() { Value = perTxGasLimit, StateReservoir = reservoirAtTxStart, StateGasUsed = intrinsicStateGas }; Assert.That(EthereumGasPolicy.ConsumeStateGas(ref gas, stateGasCharged), Is.True); Assert.That(gas.StateGasSpill, Is.EqualTo(4_174L), "4_174 spill from reservoir overflow"); - long preHaltSpill = gas.StateGasSpill; + ulong preHaltSpill = gas.StateGasSpill; EthereumGasPolicy.ResetForHalt(ref gas, initialStateReservoir: reservoirAtTxStart, initialStateGasUsed: intrinsicStateGas); - long blockLevelContribution = gas.StateGasUsed + preHaltSpill; + ulong blockLevelContribution = gas.StateGasUsed + preHaltSpill; Assert.That(blockLevelContribution, Is.EqualTo(intrinsicStateGas + 4_174L), "per-tx block-level contribution = intrinsic floor + spill; reservoir-portion is refunded"); } @@ -638,15 +638,15 @@ public void Top_level_halt_block_regular_dimension_includes_burned_spill() // contribute (initialRegular + N*S) to block_regular and (intrinsicState - N*S) to // block_state. The burned spill belongs in the regular dimension because it was paid // from gas_left, not from the reservoir. - const long txGasLimit = 16_000_000; - const long intrinsicStateGas = GasCostOf.CreateState; - const long innerRevertSpill = 4_174; + ulong txGasLimit = 16_000_000ul; + ulong intrinsicStateGas = GasCostOf.CreateState; + const ulong innerRevertSpill = 4_174ul; - long initialReservoir = Math.Max(0, txGasLimit - intrinsicStateGas - 16_777_216); - long expectedBlockRegularBeforeFix = txGasLimit - intrinsicStateGas - initialReservoir; - long effectiveStateGas = Math.Max(0, intrinsicStateGas - innerRevertSpill); - long blockRegular = txGasLimit - effectiveStateGas - initialReservoir; - long blockState = effectiveStateGas; + ulong initialReservoir = txGasLimit > intrinsicStateGas + 16_777_216ul ? txGasLimit - intrinsicStateGas - 16_777_216ul : 0ul; + ulong expectedBlockRegularBeforeFix = txGasLimit - intrinsicStateGas - initialReservoir; + ulong effectiveStateGas = intrinsicStateGas > innerRevertSpill ? intrinsicStateGas - innerRevertSpill : 0ul; + ulong blockRegular = txGasLimit - effectiveStateGas - initialReservoir; + ulong blockState = effectiveStateGas; Assert.That(blockRegular - expectedBlockRegularBeforeFix, Is.EqualTo(innerRevertSpill), "applying the spillBurned reattribution adds the burned spill to block_regular"); @@ -705,10 +705,10 @@ public void Revert_discards_descendant_spill_once_refund_reaches_ancestor() "refunded descendant spill must not be added by the top-level halt formula"); } - [TestCase(ExpectedResult = 5_000L)] - public long Spent_gas_subtracts_state_reservoir() + [TestCase(ExpectedResult = 5000ul)] + public ulong Spent_gas_subtracts_state_reservoir() { EthereumGasPolicy gas = new() { Value = 3_000, StateReservoir = 2_000, StateGasUsed = 500 }; - return 10_000L - EthereumGasPolicy.GetRemainingGas(in gas) - EthereumGasPolicy.GetStateReservoir(in gas); + return 10_000ul - EthereumGasPolicy.GetRemainingGas(in gas) - EthereumGasPolicy.GetStateReservoir(in gas); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmMemoryTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/EvmMemoryTestsBase.cs index 2d8802489d38..8a59a3f788eb 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmMemoryTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmMemoryTestsBase.cs @@ -74,9 +74,9 @@ public void Calculate_memory_cost_returns_0_for_subsequent_calls() UInt256 dest = UInt256.One; memory.CalculateMemoryCost(in dest, UInt256.One, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(false)); - long cost = memory.CalculateMemoryCost(in dest, UInt256.One, out outOfGas); + ulong cost = memory.CalculateMemoryCost(in dest, UInt256.One, out outOfGas); Assert.That(outOfGas, Is.EqualTo(false)); - Assert.That(cost, Is.EqualTo(0L)); + Assert.That(cost, Is.EqualTo(0UL)); } [Test] @@ -84,8 +84,8 @@ public void Calculate_memory_cost_returns_0_for_0_length() { EvmPooledMemory memory = new(); UInt256 dest = long.MaxValue; - long cost = memory.CalculateMemoryCost(in dest, UInt256.Zero, out bool outOfGas); + ulong cost = memory.CalculateMemoryCost(in dest, UInt256.Zero, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(false)); - Assert.That(cost, Is.EqualTo(0L)); + Assert.That(cost, Is.EqualTo(0UL)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index c3e2017e56b5..8403fa57caf9 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -31,9 +31,9 @@ public class EvmPooledMemoryTests : EvmMemoryTestsBase [TestCase(int.MaxValue, int.MaxValue / 32 + 1)] public void Div32Ceiling(int input, int expectedResult) { - long result = EvmCalculations.Div32Ceiling((ulong)input); + ulong result = EvmCalculations.Div32Ceiling((ulong)input); TestContext.Out.WriteLine($"Memory cost (gas): {result}"); - Assert.That(result, Is.EqualTo(expectedResult)); + Assert.That(result, Is.EqualTo((ulong)expectedResult)); } private const int MaxCodeSize = CodeSizeConstants.MaxCodeSizeEip170; @@ -53,7 +53,7 @@ public void MemoryCost(int destination, int memoryAllocation) { EvmPooledMemory memory = new(); UInt256 dest = (UInt256)destination; - long result = memory.CalculateMemoryCost(in dest, (UInt256)memoryAllocation, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(in dest, (UInt256)memoryAllocation, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(false)); TestContext.Out.WriteLine($"Gas cost of allocating {memoryAllocation} starting from {dest}: {result}"); } @@ -63,9 +63,9 @@ public void CalculateMemoryCost_LocationExceedsULong_ShouldReturnOutOfGas() { EvmPooledMemory memory = new(); UInt256 location = new(0, 1, 0, 0); // value larger than ulong max (u1 != 0) - long result = memory.CalculateMemoryCost(in location, 32, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(in location, 32, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true)); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -73,9 +73,9 @@ public void CalculateMemoryCost_LengthExceedsULong_ShouldReturnOutOfGas() { EvmPooledMemory memory = new(); UInt256 length = new(0, 1, 0, 0); // value larger than ulong max (u1 != 0) - long result = memory.CalculateMemoryCost(0, in length, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(0, in length, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true)); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -83,9 +83,9 @@ public void CalculateMemoryCost_LengthExceedsLongMax_ShouldReturnOutOfGas() { EvmPooledMemory memory = new(); UInt256 length = (UInt256)long.MaxValue + 1; // just over long.MaxValue - long result = memory.CalculateMemoryCost(0, in length, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(0, in length, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true)); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -93,9 +93,9 @@ public void CalculateMemoryCost_LocationPlusLengthOverflows_ShouldReturnOutOfGas { EvmPooledMemory memory = new(); UInt256 location = ulong.MaxValue; - long result = memory.CalculateMemoryCost(in location, 1, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(in location, 1, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true)); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -103,9 +103,9 @@ public void CalculateMemoryCost_TotalSizeExceedsLongMax_ShouldReturnOutOfGas() { EvmPooledMemory memory = new(); UInt256 location = (UInt256)long.MaxValue; - long result = memory.CalculateMemoryCost(in location, 1, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(in location, 1, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true)); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -118,32 +118,32 @@ public void CalculateMemoryCost_TotalSizeExceedsIntMaxAfterWordAlignment_ShouldR // Request exactly at the limit should succeed UInt256 maxAllowedSize = (UInt256)(int.MaxValue - EvmPooledMemory.WordSize + 1); - long result = memory.CalculateMemoryCost(0, in maxAllowedSize, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(0, in maxAllowedSize, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(false), "Size at limit should be allowed"); // Request one byte over the limit should fail UInt256 overLimitSize = maxAllowedSize + 1; result = memory.CalculateMemoryCost(0, in overLimitSize, out outOfGas); Assert.That(outOfGas, Is.EqualTo(true), "Size over limit should return out of gas"); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] public void CalculateMemoryCost_MaxAllowedSize_ShouldReturnExpectedCostForBothLengthOverloads() { decimal maxWords = EvmPooledMemory.MaxMemoryWords; - long expectedCost = decimal.ToInt64( + ulong expectedCost = (ulong)decimal.ToInt64( maxWords * GasCostOf.Memory + decimal.Floor((maxWords * maxWords) / 512m)); EvmPooledMemory ulongMemory = new(); - long ulongResult = ulongMemory.CalculateMemoryCost(0, EvmPooledMemory.MaxMemorySize, out bool ulongOutOfGas); + ulong ulongResult = ulongMemory.CalculateMemoryCost(0, EvmPooledMemory.MaxMemorySize, out bool ulongOutOfGas); Assert.That(ulongOutOfGas, Is.EqualTo(false)); Assert.That(ulongResult, Is.EqualTo(expectedCost)); EvmPooledMemory uint256Memory = new(); UInt256 maxAllowedSize = (UInt256)EvmPooledMemory.MaxMemorySize; - long uint256Result = uint256Memory.CalculateMemoryCost(0, in maxAllowedSize, out bool uint256OutOfGas); + ulong uint256Result = uint256Memory.CalculateMemoryCost(0, in maxAllowedSize, out bool uint256OutOfGas); Assert.That(uint256OutOfGas, Is.EqualTo(false)); Assert.That(uint256Result, Is.EqualTo(expectedCost)); } @@ -155,9 +155,9 @@ public void CalculateMemoryCost_4GBMemoryRequest_ShouldReturnOutOfGas() // instead of causing integer overflow crash in array operations. EvmPooledMemory memory = new(); UInt256 size4GB = 0xffffffffUL; - long result = memory.CalculateMemoryCost(0, in size4GB, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(0, in size4GB, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true), "4GB memory request should return out of gas"); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -167,9 +167,9 @@ public void CalculateMemoryCost_LargeOffsetPlusLength_ShouldReturnOutOfGas() EvmPooledMemory memory = new(); UInt256 location = (UInt256)(int.MaxValue / 2); UInt256 length = (UInt256)(int.MaxValue / 2 + 100); // Sum exceeds limit - long result = memory.CalculateMemoryCost(in location, in length, out bool outOfGas); + ulong result = memory.CalculateMemoryCost(in location, in length, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(true), "Location + length exceeding limit should return out of gas"); - Assert.That(result, Is.EqualTo(0L)); + Assert.That(result, Is.EqualTo(0UL)); } [Test] @@ -326,8 +326,8 @@ public void GetTrace_memory_should_not_overflow() private static readonly EthereumEcdsa ethereumEcdsa = new(BlockchainIds.GenericNonRealNetwork); private static string Run(byte[] input) { - long blocknr = 12965000; - long gas = 34218; + ulong blocknr = 12965000; + ulong gas = 34218; ulong ts = 123456; IWorldState stateProvider = TestWorldStateFactory.CreateForTest(); ISpecProvider specProvider = new TestSpecProvider(London.Instance); @@ -421,7 +421,7 @@ public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] outp { } - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { } @@ -429,7 +429,7 @@ public void ReportOperationError(EvmExceptionType error) { } - public void ReportOperationRemainingGas(long gas) + public void ReportOperationRemainingGas(ulong gas) { } @@ -477,21 +477,21 @@ public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnly public void ReportStorageRead(in StorageCell storageCell) => throw new NotImplementedException(); - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new NotSupportedException(); + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new NotSupportedException(); - public void ReportActionEnd(long gas, ReadOnlyMemory output) => throw new NotSupportedException(); + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) => throw new NotSupportedException(); public void ReportActionError(EvmExceptionType exceptionType) => throw new NotSupportedException(); - public void ReportActionRevert(long gas, ReadOnlyMemory output) => throw new NotSupportedException(); + public void ReportActionRevert(ulong gas, ReadOnlyMemory output) => throw new NotSupportedException(); - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new NotSupportedException(); + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new NotSupportedException(); public void ReportBlockHash(Hash256 blockHash) => throw new NotImplementedException(); public void ReportByteCode(ReadOnlyMemory byteCode) => throw new NotSupportedException(); - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { } @@ -503,7 +503,7 @@ public void ReportRefund(long refund) { } - public void ReportExtraGasPressure(long extraGasPressure) => throw new NotImplementedException(); + public void ReportExtraGasPressure(ulong extraGasPressure) => throw new NotImplementedException(); public void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) => throw new NotImplementedException(); diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmStackTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmStackTests.cs index 6e232692cf28..1f1afeefd97e 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmStackTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmStackTests.cs @@ -319,7 +319,7 @@ private static EvmExceptionType PushUInt256Value(ref EvmStack stack) private static VmState CreateEvmState() => VmState.RentTopLevel( - EthereumGasPolicy.FromLong(10_000), + EthereumGasPolicy.FromULong(10_000UL), ExecutionType.CALL, ExecutionEnvironment.Rent(null, null, null, null, 0, default, default, default), new StackAccessTracker(), diff --git a/src/Nethermind/Nethermind.Evm.Test/GasPriceExtractorTests.cs b/src/Nethermind/Nethermind.Evm.Test/GasPriceExtractorTests.cs index 53e9a653feb1..e031e8a0dbd3 100644 --- a/src/Nethermind/Nethermind.Evm.Test/GasPriceExtractorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/GasPriceExtractorTests.cs @@ -16,7 +16,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class GasPriceExtractorTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.IstanbulBlockNumber; [Test] public void Block_header_rlp_size_assumption_is_correct() diff --git a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs index dc2b65d64693..0e5b97f7c80b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs @@ -29,18 +29,18 @@ public enum GasOptions [TestFixture] public class IntrinsicGasCalculatorTests { - public static IEnumerable<(Transaction Tx, long cost, string Description)> TestCaseSource() + public static IEnumerable<(Transaction Tx, ulong cost, string Description)> TestCaseSource() { - yield return (Build.A.Transaction.SignedAndResolved().TestObject, 21000, "empty"); + yield return (Build.A.Transaction.SignedAndResolved().TestObject, 21000UL, "empty"); } - public static IEnumerable<(List orderQueue, long Cost)> AccessTestCaseSource() + public static IEnumerable<(List orderQueue, ulong Cost)> AccessTestCaseSource() { - yield return (new List { }, 0); - yield return (new List { Address.Zero }, 2400); - yield return (new List { Address.Zero, (UInt256)1 }, 4300); - yield return (new List { Address.Zero, (UInt256)1, TestItem.AddressA, (UInt256)1 }, 8600); - yield return (new List { Address.Zero, (UInt256)1, Address.Zero, (UInt256)1 }, 8600); + yield return (new List { }, 0UL); + yield return (new List { Address.Zero }, 2400UL); + yield return (new List { Address.Zero, (UInt256)1 }, 4300UL); + yield return (new List { Address.Zero, (UInt256)1, TestItem.AddressA, (UInt256)1 }, 8600UL); + yield return (new List { Address.Zero, (UInt256)1, Address.Zero, (UInt256)1 }, 8600UL); } public static IEnumerable<(byte[] Data, int OldCost, int NewCost, int FloorCost)> DataTestCaseSource() @@ -52,14 +52,14 @@ public class IntrinsicGasCalculatorTests yield return ([0, 0, 1, 1], 144, 40, 21100); } [TestCaseSource(nameof(TestCaseSource))] - public void Intrinsic_cost_is_calculated_properly((Transaction Tx, long Cost, string Description) testCase) + public void Intrinsic_cost_is_calculated_properly((Transaction Tx, ulong Cost, string Description) testCase) { EthereumIntrinsicGas gas = IntrinsicGasCalculator.Calculate(testCase.Tx, Berlin.Instance); Assert.That(gas, Is.EqualTo(new EthereumIntrinsicGas(Standard: testCase.Cost, FloorGas: 0))); } [TestCaseSource(nameof(AccessTestCaseSource))] - public void Intrinsic_cost_is_calculated_properly((List orderQueue, long Cost) testCase) + public void Intrinsic_cost_is_calculated_properly((List orderQueue, ulong Cost) testCase) { AccessList.Builder accessListBuilder = new(); foreach (object o in testCase.orderQueue) @@ -115,12 +115,12 @@ void Test(IReleaseSpec spec, GasOptions options) bool isAfterRepricing = options.HasFlag(GasOptions.AfterRepricing); bool floorCostEnabled = options.HasFlag(GasOptions.FloorCostEnabled); - Assert.That(gas.Standard, Is.EqualTo(21000 + (isAfterRepricing ? testCase.NewCost : testCase.OldCost)), $"{spec.Name}: {testCase.Data.ToHexString()}"); - Assert.That(gas.FloorGas, Is.EqualTo(floorCostEnabled ? testCase.FloorCost : 0)); + Assert.That(gas.Standard, Is.EqualTo(21000UL + (ulong)(isAfterRepricing ? testCase.NewCost : testCase.OldCost)), $"{spec.Name}: {testCase.Data.ToHexString()}"); + Assert.That(gas.FloorGas, Is.EqualTo((ulong)(floorCostEnabled ? testCase.FloorCost : 0))); Assert.That(gas, Is.EqualTo(new EthereumIntrinsicGas( - Standard: 21000 + (isAfterRepricing ? testCase.NewCost : testCase.OldCost), - FloorGas: floorCostEnabled ? testCase.FloorCost : 0)), $"{spec.Name}: {testCase.Data.ToHexString()}"); + Standard: 21000UL + (ulong)(isAfterRepricing ? testCase.NewCost : testCase.OldCost), + FloorGas: (ulong)(floorCostEnabled ? testCase.FloorCost : 0))), $"{spec.Name}: {testCase.Data.ToHexString()}"); } Test(Homestead.Instance, GasOptions.None); @@ -139,10 +139,10 @@ void Test(IReleaseSpec spec, GasOptions options) Test(Prague.Instance, GasOptions.AfterRepricing | GasOptions.FloorCostEnabled); } - public static IEnumerable<(AuthorizationTuple[] contractCode, long expectedCost)> AuthorizationListTestCaseSource() + public static IEnumerable<(AuthorizationTuple[] contractCode, ulong expectedCost)> AuthorizationListTestCaseSource() { yield return ( - [], 0); + [], 0UL); yield return ( [new AuthorizationTuple( TestContext.CurrentContext.Random.NextULong(), @@ -196,7 +196,7 @@ [new AuthorizationTuple( GasCostOf.NewAccount * 3); } [TestCaseSource(nameof(AuthorizationListTestCaseSource))] - public void Calculate_TxHasAuthorizationList_ReturnsExpectedCostOfTx((AuthorizationTuple[] AuthorizationList, long ExpectedCost) testCase) + public void Calculate_TxHasAuthorizationList_ReturnsExpectedCostOfTx((AuthorizationTuple[] AuthorizationList, ulong ExpectedCost) testCase) { Transaction tx = Build.A.Transaction.SignedAndResolved() .WithAuthorizationCode(testCase.AuthorizationList) @@ -244,8 +244,8 @@ public void Eip8037_nongeneric_intrinsic_gas_includes_state_gas_for_create() .TestObject; EthereumIntrinsicGas gas = IntrinsicGasCalculator.Calculate(tx, Amsterdam.Instance); - long expectedRegular = GasCostOf.Transaction + GasCostOf.CreateRegular; - long expectedState = GasCostOf.CreateState; + ulong expectedRegular = GasCostOf.Transaction + GasCostOf.CreateRegular; + ulong expectedState = GasCostOf.CreateState; Assert.That(gas.Standard, Is.EqualTo(expectedRegular + expectedState)); Assert.That(gas.MinimalGas, Is.EqualTo(Math.Max(gas.Standard, gas.FloorGas))); } @@ -258,8 +258,8 @@ public void Eip8037_nongeneric_intrinsic_gas_includes_state_gas_for_setcode() .TestObject; EthereumIntrinsicGas gas = IntrinsicGasCalculator.Calculate(tx, Amsterdam.Instance); - long expectedRegular = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular; - long expectedState = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; + ulong expectedRegular = GasCostOf.Transaction + GasCostOf.PerAuthBaseRegular; + ulong expectedState = GasCostOf.NewAccountState + GasCostOf.PerAuthBaseState; Assert.That(gas.Standard, Is.EqualTo(expectedRegular + expectedState)); } @@ -272,7 +272,7 @@ public void Eip8037_nongeneric_minimal_gas_is_at_least_regular_plus_state() .TestObject; EthereumIntrinsicGas gas = IntrinsicGasCalculator.Calculate(tx, Amsterdam.Instance); - long regularPlusState = GasCostOf.Transaction + GasCostOf.CreateRegular + GasCostOf.CreateState; + ulong regularPlusState = GasCostOf.Transaction + GasCostOf.CreateRegular + GasCostOf.CreateState; Assert.That(gas.MinimalGas, Is.GreaterThanOrEqualTo(regularPlusState)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/InvalidOpcodeTests.cs b/src/Nethermind/Nethermind.Evm.Test/InvalidOpcodeTests.cs index 84f69e6f6ea4..dabf3a22f176 100644 --- a/src/Nethermind/Nethermind.Evm.Test/InvalidOpcodeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/InvalidOpcodeTests.cs @@ -148,7 +148,7 @@ protected override ILogManager GetLogManager() return _logManager; } - [TestCase(0)] + [TestCase(0UL)] [TestCase(MainnetSpecProvider.HomesteadBlockNumber)] [TestCase(MainnetSpecProvider.SpuriousDragonBlockNumber)] [TestCase(MainnetSpecProvider.TangerineWhistleBlockNumber)] @@ -163,7 +163,7 @@ protected override ILogManager GetLogManager() [TestCase(MainnetSpecProvider.ParisBlockNumber + 3, MainnetSpecProvider.PragueBlockTimestamp)] [TestCase(MainnetSpecProvider.ParisBlockNumber + 4, MainnetSpecProvider.OsakaBlockTimestamp)] [TestCase(MainnetSpecProvider.ParisBlockNumber + 7, MainnetSpecProvider.AmsterdamBlockTimestamp)] - public void Test(long blockNumber, ulong? timestamp = null) + public void Test(ulong blockNumber, ulong? timestamp = null) { ILogger logger = _logManager.GetClassLogger(); Instruction[] validOpcodes = _validOpcodes[(blockNumber, timestamp)]; diff --git a/src/Nethermind/Nethermind.Evm.Test/Keccak256Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Keccak256Tests.cs index ed521982dabe..463255d7410e 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Keccak256Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Keccak256Tests.cs @@ -14,7 +14,7 @@ public class Keccak256Tests : VirtualMachineTestsBase { private bool _setAuthor; - protected override Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner, Transaction transaction, long blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) + protected override Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner, Transaction transaction, ulong blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) { Block block = base.BuildBlock(activation, senderRecipientAndMiner, transaction, blockGasLimit, excessBlobGas); if (_setAuthor) block.Header.Author = TestItem.AddressC; diff --git a/src/Nethermind/Nethermind.Evm.Test/Push2JumpFusionTests.cs b/src/Nethermind/Nethermind.Evm.Test/Push2JumpFusionTests.cs index 264ad84f09f0..d3af29d85ca7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Push2JumpFusionTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Push2JumpFusionTests.cs @@ -19,7 +19,7 @@ namespace Nethermind.Evm.Test; [Parallelizable(ParallelScope.Self)] public class Push2JumpFusionTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.CancunBlockTimestamp; // The fusion path is gated on `!TTracingInst.IsActive`; using the default diff --git a/src/Nethermind/Nethermind.Evm.Test/SimdTests.cs b/src/Nethermind/Nethermind.Evm.Test/SimdTests.cs index 302c8731ef30..cd58a22e3036 100644 --- a/src/Nethermind/Nethermind.Evm.Test/SimdTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/SimdTests.cs @@ -12,7 +12,7 @@ namespace Nethermind.Evm.Test [Parallelizable(ParallelScope.Self)] public class SimdTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.ConstantinopleFixBlockNumber; [Test] public void And() @@ -95,7 +95,7 @@ private void AssertSimd(TestAllTracerWithOutput receipt, ReadOnlySpan resu AssertGas(receipt, result.IsZero() ? ZeroResultGas : NonZeroResultGas); } - private const long ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SStoreNetMeteredEip1283; - private const long NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; + private const ulong ZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SStoreNetMeteredEip1283; + private const ulong NonZeroResultGas = GasCostOf.Transaction + 4 * GasCostOf.VeryLow + GasCostOf.SSet; } } diff --git a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs index e68735b01dbd..caae3449b13d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs @@ -32,27 +32,6 @@ public void SetUp() [TearDown] public void TearDown() => _stateScope.Dispose(); - // Only values that don't fit in a ulong are rejected (> ulong.MaxValue). - // ulong.MaxValue itself is valid — consistent with Geth's hexutil.Uint64 type. - private static IEnumerable InvalidNonceCases() => - [ - new TestCaseData((UInt256)ulong.MaxValue + 1).SetName("ulong_max_plus_one"), - new TestCaseData(UInt256.MaxValue).SetName("uint256_max"), - ]; - - [TestCaseSource(nameof(InvalidNonceCases))] - public void nonce_override_above_uint64_range_throws(UInt256 nonce) - { - Dictionary overrides = new() - { - { TestItem.AddressA, new AccountOverride { Nonce = nonce } } - }; - - Action act = () => _state.ApplyStateOverridesNoCommit(_codeRepo, overrides, Shanghai.Instance); - - Assert.That(act, Throws.TypeOf().With.Message.Contains(@"maximum supported value")); - } - private static IEnumerable ValidNonceCases() => [ new TestCaseData((UInt256)ulong.MaxValue).SetName("ulong_max"), @@ -61,7 +40,7 @@ private static IEnumerable ValidNonceCases() => ]; [TestCaseSource(nameof(ValidNonceCases))] - public void nonce_override_within_uint64_range_does_not_throw(UInt256 nonce) + public void nonce_override_within_uint64_range_does_not_throw(ulong nonce) { Dictionary overrides = new() { diff --git a/src/Nethermind/Nethermind.Evm.Test/StorageAndSelfDestructTests.cs b/src/Nethermind/Nethermind.Evm.Test/StorageAndSelfDestructTests.cs index bf86a998ca84..fef233d68826 100644 --- a/src/Nethermind/Nethermind.Evm.Test/StorageAndSelfDestructTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/StorageAndSelfDestructTests.cs @@ -19,7 +19,7 @@ namespace Nethermind.Evm.Test [TestFixture] public class StorageAndSelfDestructTests : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.MuirGlacierBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.MuirGlacierBlockNumber; protected override ISpecProvider SpecProvider => MainnetSpecProvider.Instance; @@ -61,7 +61,7 @@ public void Load_self_destruct() .Call(contractAddress, 100000) .Op(Instruction.STOP).Done; - long gasLimit = 1000000; + ulong gasLimit = 1000000; EthereumEcdsa ecdsa = new(1); Transaction initTx = Build.A.Transaction.WithCode(initByteCode).WithGasLimit(gasLimit).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; @@ -141,7 +141,7 @@ public void Destroy_restore_store() .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; - long gasLimit = 1000000; + ulong gasLimit = 1000000; EthereumEcdsa ecdsa = new(1); // deploy create 2 @@ -247,7 +247,7 @@ public void Destroy_restore_store_different_cells() .CallWithValue(deploymentAddress, 100000) .Op(Instruction.STOP).Done; - long gasLimit = 1000000; + ulong gasLimit = 1000000; EthereumEcdsa ecdsa = new(1); // deploy create 2 @@ -365,7 +365,7 @@ public void Destroy_restore_store_different_cells_previously_existing() TestState.Commit(MuirGlacier.Instance); TestState.CommitTree(0); - long gasLimit = 1000000; + ulong gasLimit = 1000000; EthereumEcdsa ecdsa = new(1); // deploy create 2 diff --git a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs index d95c1715e776..e8357526f4a6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs @@ -29,14 +29,14 @@ public class TestAllTracerWithOutput : TxTracer public byte[]? ReturnValue { get; private set; } - public long GasSpent { get; private set; } + public ulong GasSpent { get; private set; } public string? Error { get; private set; } public byte StatusCode { get; private set; } public GasConsumed GasConsumedResult { get; private set; } - public long CumulativeRegularGasUsed { get; private set; } + public ulong CumulativeRegularGasUsed { get; private set; } public long Refund { get; private set; } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/DebugTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/DebugTracerTests.cs index e1a1599fe89a..c01a3602855f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/DebugTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/DebugTracerTests.cs @@ -383,7 +383,7 @@ public void Use_Debug_Tracer_To_Check_Assertion_Live(string bytecodeHex) Thread vmThread = new(() => ExecuteSafe(tracer, bytecode)); vmThread.Start(); - long? gasAvailable_pre_MSTORE = null; + ulong? gasAvailable_pre_MSTORE = null; while (vmThread.IsAlive) { if (tracer.CanReadState) @@ -392,7 +392,7 @@ public void Use_Debug_Tracer_To_Check_Assertion_Live(string bytecodeHex) if (gasAvailable_pre_MSTORE is null) gasAvailable_pre_MSTORE = EthereumGasPolicy.GetRemainingGas(tracer.CurrentState.Gas); else { - long gasAvailable_post_MSTORE = EthereumGasPolicy.GetRemainingGas(tracer.CurrentState.Gas); + ulong gasAvailable_post_MSTORE = EthereumGasPolicy.GetRemainingGas(tracer.CurrentState.Gas); Assert.That(gasAvailable_pre_MSTORE - gasAvailable_post_MSTORE, Is.EqualTo(GasCostOf.VeryLow)); } tracer.MoveNext(); diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index e64dcd18d02b..d5d4613e7cfb 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -140,11 +140,11 @@ public void Handles_well_errors() public void Handles_well_revert() { using TestEnvironment testEnvironment = new(); - long gasLimit = 100_000_000; + ulong gasLimit = 100_000_000ul; Transaction tx = Build.A.Transaction.WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; - long gasLeft = gasLimit - 22000; + ulong gasLeft = gasLimit - 22000ul; testEnvironment.tracer.ReportAction(gasLeft, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); gasLeft = 63 * gasLeft / 64; @@ -154,10 +154,10 @@ public void Handles_well_revert() testEnvironment.tracer.ReportAction(gasLeft, 0, Address.Zero, Address.Zero, Array.Empty(), _executionType, false); - testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 96000000); - testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 98000000); - testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 99000000); - Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(35146L)); + testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 96000000ul); + testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 98000000ul); + testEnvironment.tracer.ReportActionError(EvmExceptionType.Revert, 99000000ul); + Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(35146ul)); Assert.That(err, Is.Null); } @@ -264,7 +264,7 @@ public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeExceptio Transaction tx = Build.A.Transaction.TestObject; Block block = Build.A.Block.WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - tracer.MarkAsSuccess(Address.Zero, 1, [], []); + tracer.MarkAsSuccess(Address.Zero, 1ul, [], []); IReadOnlyStateProvider stateProvider = Substitute.For(); stateProvider.GetBalance(Arg.Any
()).Returns(new UInt256(1)); GasEstimator sut = new( @@ -273,7 +273,7 @@ public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeExceptio MainnetSpecProvider.Instance, new BlocksConfig()); - sut.Estimate(tx, block.Header, tracer, out string? err, errorMargin); + sut.Estimate(tx, block.Header, tracer, out string? err, (ulong)errorMargin); Assert.That(err, Is.Not.Null); } @@ -283,12 +283,12 @@ public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeExceptio [TestCase(Transaction.BaseTxGasCost + 10000, GasEstimator.DefaultErrorMargin, true)] [TestCase(Transaction.BaseTxGasCost + 20000, GasEstimator.DefaultErrorMargin, true)] [TestCase(Transaction.BaseTxGasCost + 123456789, 123, true)] - public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargin(int totalGas, int errorMargin, bool fail) + public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargin(uint totalGas, int errorMargin, bool fail) { Transaction tx = Build.A.Transaction.WithGasLimit(30000).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - tracer.MarkAsSuccess(Address.Zero, totalGas, [], []); + tracer.MarkAsSuccess(Address.Zero, (ulong)totalGas, [], []); IReadOnlyStateProvider stateProvider = Substitute.For(); stateProvider.GetBalance(Arg.Any
()).Returns(new UInt256(1)); GasEstimator sut = new( @@ -297,14 +297,14 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi MainnetSpecProvider.Instance, new BlocksConfig()); - long result = sut.Estimate(tx, block.Header, tracer, out string? err, errorMargin); + ulong result = sut.Estimate(tx, block.Header, tracer, out string? err, (ulong)errorMargin); if (fail) { using (Assert.EnterMultipleScope()) { Assert.That(err, Is.EqualTo("Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap")); - Assert.That(result, Is.EqualTo(0)); + Assert.That(result, Is.EqualTo(0ul)); } } else @@ -312,7 +312,7 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi using (Assert.EnterMultipleScope()) { Assert.That(err, Is.Null); - Assert.That(result, Is.EqualTo(totalGas).Within(totalGas * (errorMargin / 10000d + 1))); + Assert.That((double)result, Is.EqualTo((double)totalGas).Within((double)totalGas * (errorMargin / 10000d + 1))); } } } @@ -320,10 +320,10 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi [Test] public void Estimate_simple_transfer_with_errorMargin_should_be_exact() { - Transaction tx = Build.A.Transaction.WithGasLimit(30000).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(30000ul).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - const int totalGas = Transaction.BaseTxGasCost; + const uint totalGas = Transaction.BaseTxGasCost; tracer.MarkAsSuccess(Address.Zero, totalGas, [], []); IReadOnlyStateProvider stateProvider = Substitute.For(); stateProvider.GetBalance(Arg.Any
()).Returns(new UInt256(1)); @@ -333,22 +333,22 @@ public void Estimate_simple_transfer_with_errorMargin_should_be_exact() MainnetSpecProvider.Instance, new BlocksConfig()); - long result = sut.Estimate(tx, block.Header, tracer, out string? err); + ulong result = sut.Estimate(tx, block.Header, tracer, out string? err); using (Assert.EnterMultipleScope()) { Assert.That(err, Is.Null); - Assert.That(result, Is.EqualTo(totalGas)); + Assert.That(result, Is.EqualTo((ulong)totalGas)); } } [Test] public void Estimate_UseZeroErrorMargin_EstimationResultIsExact() { - Transaction tx = Build.A.Transaction.WithGasLimit(30000).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(30000ul).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - const int totalGas = Transaction.BaseTxGasCost; + const uint totalGas = Transaction.BaseTxGasCost; tracer.MarkAsSuccess(Address.Zero, totalGas, [], []); IReadOnlyStateProvider stateProvider = Substitute.For(); stateProvider.GetBalance(Arg.Any
()).Returns(new UInt256(1)); @@ -358,7 +358,7 @@ public void Estimate_UseZeroErrorMargin_EstimationResultIsExact() MainnetSpecProvider.Instance, new BlocksConfig()); - long result = sut.Estimate(tx, block.Header, tracer, out string? err, 0); + ulong result = sut.Estimate(tx, block.Header, tracer, out string? err, 0ul); using (Assert.EnterMultipleScope()) { @@ -371,19 +371,19 @@ public void Estimate_UseZeroErrorMargin_EstimationResultIsExact() public void Should_return_zero_when_out_of_gas_detected_during_estimation() { TestEnvironment testEnvironment = new(); - Transaction tx = Build.A.Transaction.WithGasLimit(100000).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(100000ul).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(1000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); testEnvironment.tracer.ReportActionError(EvmExceptionType.OutOfGas); - testEnvironment.tracer.MarkAsSuccess(Address.Zero, 500, Array.Empty(), Array.Empty()); + testEnvironment.tracer.MarkAsSuccess(Address.Zero, 500ul, Array.Empty(), Array.Empty()); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when OutOfGas is detected"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when OutOfGas is detected"); Assert.That(err, Is.Not.Null, "Error message should be provided when OutOfGas is detected"); Assert.That(testEnvironment.tracer.OutOfGas, Is.True, "OutOfGas should be set to true"); } @@ -392,17 +392,17 @@ public void Should_return_zero_when_out_of_gas_detected_during_estimation() public void Should_return_zero_when_status_code_is_failure() { TestEnvironment testEnvironment = new(); - Transaction tx = Build.A.Transaction.WithGasLimit(100000).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(100000ul).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(1000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - testEnvironment.tracer.MarkAsFailed(Address.Zero, 500, Array.Empty(), "execution failed"); + testEnvironment.tracer.MarkAsFailed(Address.Zero, 500ul, Array.Empty(), "execution failed"); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when StatusCode is Failure"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when StatusCode is Failure"); Assert.That(err, Is.Not.Null, "Error message should be provided when transaction always fails"); Assert.That(testEnvironment.tracer.StatusCode, Is.EqualTo(StatusCode.Failure)); } @@ -411,19 +411,19 @@ public void Should_return_zero_when_status_code_is_failure() public void Should_return_positive_estimate_when_no_failure_conditions() { TestEnvironment testEnvironment = new(); - Transaction tx = Build.A.Transaction.WithGasLimit(128).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(128ul).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(128, 0, Address.Zero, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(128ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - testEnvironment.tracer.ReportAction(100, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.CALL, false); + testEnvironment.tracer.ReportAction(100ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.CALL, false); testEnvironment.tracer.ReportActionEnd(63, Array.Empty()); testEnvironment.tracer.ReportActionEnd(65, Array.Empty()); - testEnvironment.tracer.MarkAsSuccess(Address.Zero, 63, Array.Empty(), Array.Empty()); + testEnvironment.tracer.MarkAsSuccess(Address.Zero, 63ul, Array.Empty(), Array.Empty()); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(estimate, Is.EqualTo(1), "Should match the Easy_one_level_case result"); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + Assert.That(estimate, Is.EqualTo(1ul), "Should match the Easy_one_level_case result"); Assert.That(err, Is.Null, "No error should occur"); Assert.That(testEnvironment.tracer.OutOfGas, Is.False, "No OutOfGas should be detected"); Assert.That(testEnvironment.tracer.StatusCode, Is.EqualTo(StatusCode.Success), "StatusCode should be Success"); @@ -434,7 +434,7 @@ public void Should_return_zero_with_insufficient_balance_error_when_sender_is_ad { TestEnvironment testEnvironment = new(); Transaction tx = Build.A.Transaction - .WithGasLimit(100000) + .WithGasLimit(100000ul) .WithSenderAddress(Address.Zero) .WithValue(1.Ether) // Value transfer with zero balance .TestObject; @@ -442,11 +442,11 @@ public void Should_return_zero_with_insufficient_balance_error_when_sender_is_ad // Address.Zero has zero balance by default in test environment EstimateGasTracer tracer = new(); - tracer.MarkAsFailed(Address.Zero, 0, Array.Empty(), "insufficient balance"); + tracer.MarkAsFailed(Address.Zero, 0ul, Array.Empty(), "insufficient balance"); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when Address.Zero has insufficient balance for value transfer"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when Address.Zero has insufficient balance for value transfer"); Assert.That(err, Is.EqualTo("insufficient balance"), "Should provide insufficient balance error message"); } @@ -455,20 +455,20 @@ public void Should_return_zero_with_out_of_gas_error_when_address_zero_runs_out_ { TestEnvironment testEnvironment = new(); Transaction tx = Build.A.Transaction - .WithGasLimit(100000) + .WithGasLimit(100000ul) .WithSenderAddress(Address.Zero) .WithValue(1.Ether) .TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - tracer.ReportAction(100000, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); + tracer.ReportAction(100000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); tracer.ReportActionError(EvmExceptionType.OutOfGas); - tracer.MarkAsFailed(Address.Zero, 100000, Array.Empty(), "out of gas"); + tracer.MarkAsFailed(Address.Zero, 100000ul, Array.Empty(), "out of gas"); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when Address.Zero transaction runs out of gas"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when Address.Zero transaction runs out of gas"); Assert.That(err, Is.EqualTo("Gas estimation failed due to out of gas"), "Should provide out of gas error message"); } @@ -477,19 +477,19 @@ public void Should_return_zero_with_execution_failure_when_address_zero_transact { TestEnvironment testEnvironment = new(); Transaction tx = Build.A.Transaction - .WithGasLimit(100000) + .WithGasLimit(100000ul) .WithSenderAddress(Address.Zero) .WithValue(1.Ether) .TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - tracer.ReportAction(100000, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - tracer.MarkAsFailed(Address.Zero, 50000, Array.Empty(), "execution reverted"); + tracer.ReportAction(100000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); + tracer.MarkAsFailed(Address.Zero, 50000ul, Array.Empty(), "execution reverted"); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when Address.Zero transaction always fails"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when Address.Zero transaction always fails"); Assert.That(err, Is.EqualTo("execution reverted"), "Should provide the specific execution failure message"); } @@ -498,20 +498,20 @@ public void Should_succeed_when_address_zero_has_no_value_transfer() { TestEnvironment testEnvironment = new(); Transaction tx = Build.A.Transaction - .WithGasLimit(100000) - .WithGasPrice(0) + .WithGasLimit(100000ul) + .WithGasPrice(0ul) .WithSenderAddress(Address.Zero) .WithValue(0) // No value transfer - should work even with zero balance .TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(100000, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); + testEnvironment.tracer.ReportAction(100000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); testEnvironment.tracer.ReportActionEnd(79000, Array.Empty()); - testEnvironment.tracer.MarkAsSuccess(Address.Zero, 21000, Array.Empty(), Array.Empty()); + testEnvironment.tracer.MarkAsSuccess(Address.Zero, 21000ul, Array.Empty(), Array.Empty()); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(estimate, Is.GreaterThan(0), "Should succeed when Address.Zero has no value transfer"); + Assert.That(estimate, Is.GreaterThan(0ul), "Should succeed when Address.Zero has no value transfer"); Assert.That(err, Is.Null, "No error should occur for Address.Zero with no value transfer"); } @@ -520,20 +520,20 @@ public void Should_return_zero_when_address_zero_exceeds_gas_limits() { TestEnvironment testEnvironment = new(); Transaction tx = Build.A.Transaction - .WithGasLimit(21000) // Very low gas limit + .WithGasLimit(21000ul) // Very low gas limit .WithSenderAddress(Address.Zero) .WithValue(0) .TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(21000).TestObject; + Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(21000ul).TestObject; EstimateGasTracer tracer = new(); // Simulate gas spent exceeding available limits - tracer.ReportAction(21000, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - tracer.MarkAsSuccess(Address.Zero, 25000, Array.Empty(), Array.Empty()); + tracer.ReportAction(21000ul, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); + tracer.MarkAsSuccess(Address.Zero, 25000ul, Array.Empty(), Array.Empty()); - long estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); + ulong estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err); - Assert.That(estimate, Is.EqualTo(0), "Should return 0 when gas spent exceeds limits"); + Assert.That(estimate, Is.EqualTo(0ul), "Should return 0 when gas spent exceeds limits"); Assert.That(err, Is.EqualTo("Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap"), "Should provide gas limit exceeded error message"); } @@ -541,18 +541,18 @@ public void Should_return_zero_when_address_zero_exceeds_gas_limits() public void Should_estimate_gas_successfully_ignoring_precompile_costs() { TestEnvironment testEnvironment = new(); - Transaction tx = Build.A.Transaction.WithGasLimit(30000).WithSenderAddress(TestItem.AddressA).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(30000ul).WithSenderAddress(TestItem.AddressA).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(30000, 0, TestItem.AddressA, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(30000ul, 0, TestItem.AddressA, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - testEnvironment.tracer.ReportAction(28000, 0, TestItem.AddressA, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(28000ul, 0, TestItem.AddressA, Address.Zero, Array.Empty(), ExecutionType.CALL, true); testEnvironment.tracer.ReportActionEnd(26000, Array.Empty()); testEnvironment.tracer.ReportActionEnd(25000, Array.Empty()); - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Should estimate positive gas, ignoring precompile costs"); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + Assert.That(result, Is.GreaterThan(0ul), "Should estimate positive gas, ignoring precompile costs"); Assert.That(err, Is.Null); } @@ -560,23 +560,23 @@ public void Should_estimate_gas_successfully_ignoring_precompile_costs() public void Should_estimate_gas_successfully_for_simple_transaction() { TestEnvironment testEnvironment = new(); - Transaction tx = Build.A.Transaction.WithGasLimit(30000).WithSenderAddress(TestItem.AddressA).TestObject; + Transaction tx = Build.A.Transaction.WithGasLimit(30000ul).WithSenderAddress(TestItem.AddressA).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; - testEnvironment.tracer.ReportAction(30000, 0, TestItem.AddressA, Address.Zero, Array.Empty(), + testEnvironment.tracer.ReportAction(30000ul, 0, TestItem.AddressA, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); testEnvironment.tracer.ReportActionEnd(28000, Array.Empty()); - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Should estimate positive gas for successful transaction"); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + Assert.That(result, Is.GreaterThan(0ul), "Should estimate positive gas for successful transaction"); Assert.That(err, Is.Null); } - [TestCase(50_000, false)] - [TestCase(500_000, false)] - [TestCase(1_000_000, false)] - [TestCase(1_100_000, true)] - public void Should_estimate_gas_for_explicit_gas_check_and_revert(long gasLimit, bool shouldSucceed) + [TestCase(50_000ul, false)] + [TestCase(500_000ul, false)] + [TestCase(1_000_000ul, false)] + [TestCase(1_100_000ul, true)] + public void Should_estimate_gas_for_explicit_gas_check_and_revert(ulong gasLimit, bool shouldSucceed) { TestEnvironment testEnvironment = new(); Address contractAddress = TestItem.AddressB; @@ -593,11 +593,11 @@ public void Should_estimate_gas_for_explicit_gas_check_and_revert(long gasLimit, Block block = Build.A.Block .WithNumber(MainnetSpecProvider.ByzantiumBlockNumber + 1) // Ensure opcode `REVERT` is available .WithTransactions(tx).TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); if (shouldSucceed) { - Assert.That(result, Is.GreaterThan(1_000_000), "Gas estimation should account for the gas threshold in the contract"); + Assert.That(result, Is.GreaterThan(1_000_000ul), "Gas estimation should account for the gas threshold in the contract"); Assert.That(err, Is.Null); } else @@ -610,11 +610,11 @@ public void Should_estimate_gas_for_explicit_gas_check_and_revert(long gasLimit, public void Should_succeed_with_internal_revert() { using TestEnvironment testEnvironment = new(); - long gasLimit = 100_000; + ulong gasLimit = 100_000ul; Transaction tx = Build.A.Transaction.WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; - long gasLeft = gasLimit - 22000; + ulong gasLeft = gasLimit - 22000ul; testEnvironment.tracer.ReportAction(gasLeft, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); @@ -626,14 +626,14 @@ public void Should_succeed_with_internal_revert() testEnvironment.tracer.ReportAction(gasLeft, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.CALL, false); - testEnvironment.tracer.ReportActionRevert(gasLeft - 1000, Array.Empty()); - testEnvironment.tracer.ReportActionEnd(gasLeft - 500, Array.Empty()); + testEnvironment.tracer.ReportActionRevert(gasLeft - 1000ul, Array.Empty()); + testEnvironment.tracer.ReportActionEnd(gasLeft - 500ul, Array.Empty()); testEnvironment.tracer.ReportActionEnd(gasLeft, Array.Empty()); - testEnvironment.tracer.MarkAsSuccess(Address.Zero, 25000, Array.Empty(), Array.Empty()); + testEnvironment.tracer.MarkAsSuccess(Address.Zero, 25000ul, Array.Empty(), Array.Empty()); - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0)); + Assert.That(result, Is.GreaterThan(0ul)); Assert.That(err, Is.Null); Assert.That(testEnvironment.tracer.TopLevelRevert, Is.False); Assert.That(testEnvironment.tracer.OutOfGas, Is.False); @@ -643,20 +643,20 @@ public void Should_succeed_with_internal_revert() public void Should_fail_with_top_level_revert() { using TestEnvironment testEnvironment = new(); - long gasLimit = 100_000; + ulong gasLimit = 100_000ul; Transaction tx = Build.A.Transaction.WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(gasLimit).TestObject; - long gasLeft = gasLimit - 22000; + ulong gasLeft = gasLimit - 22000ul; testEnvironment.tracer.ReportAction(gasLeft, 0, Address.Zero, Address.Zero, Array.Empty(), ExecutionType.TRANSACTION, false); - testEnvironment.tracer.ReportActionRevert(gasLeft - 1000, Array.Empty()); - testEnvironment.tracer.MarkAsFailed(Address.Zero, 25000, Array.Empty(), "execution reverted"); + testEnvironment.tracer.ReportActionRevert(gasLeft - 1000ul, Array.Empty()); + testEnvironment.tracer.MarkAsFailed(Address.Zero, 25000ul, Array.Empty(), "execution reverted"); - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.EqualTo(0)); + Assert.That(result, Is.EqualTo(0ul)); Assert.That(err, Is.EqualTo("execution reverted")); Assert.That(testEnvironment.tracer.TopLevelRevert, Is.True); } @@ -693,7 +693,7 @@ public void Should_estimate_gas_when_inner_call_reverts_but_transaction_succeeds .Done; testEnvironment.InsertContract(callerAddress, callerCode); - long gasLimit = 300_000; + ulong gasLimit = 300_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(callerAddress) @@ -705,9 +705,9 @@ public void Should_estimate_gas_when_inner_call_reverts_but_transaction_succeeds .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed when inner call reverts but transaction succeeds overall"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed when inner call reverts but transaction succeeds overall"); Assert.That(err, Is.Null, "No error should occur - inner reverts should not be treated as top-level failures"); } @@ -754,7 +754,7 @@ public void Should_estimate_gas_for_create2_with_setup_call_pattern() Address factoryAddress = TestItem.AddressB; testEnvironment.InsertContract(factoryAddress, factoryCode); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(factoryAddress) @@ -766,9 +766,9 @@ public void Should_estimate_gas_for_create2_with_setup_call_pattern() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed for CREATE2 + setup call pattern"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed for CREATE2 + setup call pattern"); Assert.That(err, Is.Null, "No error for CREATE2 + setup call"); } @@ -813,7 +813,7 @@ public void Should_estimate_gas_with_multiple_inner_calls_mixed_reverts() .Done; testEnvironment.InsertContract(callerAddress, callerCode); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(callerAddress) @@ -825,9 +825,9 @@ public void Should_estimate_gas_with_multiple_inner_calls_mixed_reverts() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed with mixed inner reverts"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed with mixed inner reverts"); Assert.That(err, Is.Null, "No error when inner calls revert but overall tx succeeds"); } @@ -873,7 +873,7 @@ public void Should_estimate_gas_when_inner_call_runs_out_of_gas_but_caller_handl .Done; testEnvironment.InsertContract(callerAddress, callerCode); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(callerAddress) @@ -885,16 +885,16 @@ public void Should_estimate_gas_when_inner_call_runs_out_of_gas_but_caller_handl .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed when inner call OOGs but caller handles it"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed when inner call OOGs but caller handles it"); Assert.That(err, Is.Null, "No error - inner OOG should not affect top-level estimation"); } - [TestCase(50_000, true)] - [TestCase(500_000, true)] - [TestCase(1_000, false)] - public void Should_estimate_gas_with_gas_sensitive_branching(long gasThreshold, bool shouldSucceed) + [TestCase(50_000ul, true)] + [TestCase(500_000ul, true)] + [TestCase(1_000ul, false)] + public void Should_estimate_gas_with_gas_sensitive_branching(ulong gasThreshold, bool shouldSucceed) { // Contract that checks gasLeft() and branches: if gasLeft >= threshold, SSTORE; else REVERT. // Tests that the binary search correctly handles gas-dependent execution paths. @@ -904,11 +904,11 @@ public void Should_estimate_gas_with_gas_sensitive_branching(long gasThreshold, // Use the existing pattern from Should_estimate_gas_for_explicit_gas_check_and_revert // Bytecode: PUSH3 , GAS, LT, PUSH1 , JUMPI, PUSH1 1, PUSH1 0, SSTORE, STOP, JUMPDEST, PUSH1 0, PUSH1 0, REVERT - long check = gasThreshold; + ulong check = gasThreshold; byte[] contractCode = Bytes.FromHexString($"0x62{check:x6}5a10600f576001600055005b6000806000fd"); testEnvironment.InsertContract(contractAddress, contractCode); - long gasLimit = 1_100_000; + ulong gasLimit = 1_100_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(contractAddress) @@ -920,7 +920,7 @@ public void Should_estimate_gas_with_gas_sensitive_branching(long gasThreshold, .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); if (shouldSucceed) { @@ -972,7 +972,7 @@ public void Should_estimate_gas_for_create_with_constructor_making_calls() .Done; testEnvironment.InsertContract(factoryAddress, factoryCode); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(factoryAddress) @@ -984,9 +984,9 @@ public void Should_estimate_gas_for_create_with_constructor_making_calls() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed for CREATE with constructor that makes calls"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed for CREATE with constructor that makes calls"); Assert.That(err, Is.Null, "No error for constructor-call pattern"); } @@ -1014,13 +1014,13 @@ public void Should_estimate_gas_consistently_across_repeated_calls() .Done; testEnvironment.InsertContract(callerAddress, callerCode); - long gasLimit = 300_000; + ulong gasLimit = 300_000ul; Block block = Build.A.Block .WithNumber(MainnetSpecProvider.ByzantiumBlockNumber + 1) .WithGasLimit(gasLimit) .TestObject; - long? firstResult = null; + ulong? firstResult = null; for (int i = 0; i < 10; i++) { // Each estimation uses a fresh tracer (as BlockchainBridge.EstimateGas does) @@ -1034,9 +1034,9 @@ public void Should_estimate_gas_consistently_across_repeated_calls() .WithSenderAddress(TestItem.AddressA) .TestObject; - long result = freshEnv.estimator.Estimate(tx, block.Header, freshEnv.tracer, out string? err); + ulong result = freshEnv.estimator.Estimate(tx, block.Header, freshEnv.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), $"Iteration {i}: gas estimation should succeed"); + Assert.That(result, Is.GreaterThan(0ul), $"Iteration {i}: gas estimation should succeed"); Assert.That(err, Is.Null, $"Iteration {i}: no error expected"); firstResult ??= result; @@ -1099,7 +1099,7 @@ public void Should_estimate_gas_for_deeply_nested_calls() .Done; testEnvironment.InsertContract(addrA, codeA); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(addrA) @@ -1111,9 +1111,9 @@ public void Should_estimate_gas_for_deeply_nested_calls() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed for deeply nested call chain"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed for deeply nested call chain"); Assert.That(err, Is.Null, "No error for deeply nested calls"); } @@ -1157,7 +1157,7 @@ public void Should_estimate_gas_for_nested_create2_with_inner_revert_in_construc .Done; testEnvironment.InsertContract(factoryAddress, factoryCode); - long gasLimit = 500_000; + ulong gasLimit = 500_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(factoryAddress) @@ -1169,9 +1169,9 @@ public void Should_estimate_gas_for_nested_create2_with_inner_revert_in_construc .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed for CREATE2 with inner revert in constructor"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed for CREATE2 with inner revert in constructor"); Assert.That(err, Is.Null, "No error for GnosisSafe-like CREATE2 pattern"); } @@ -1189,7 +1189,7 @@ public void Should_return_revert_error_when_top_level_call_reverts_with_data() .Done; testEnvironment.InsertContract(contractAddress, contractCode); - long gasLimit = 300_000; + ulong gasLimit = 300_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(contractAddress) @@ -1201,9 +1201,9 @@ public void Should_return_revert_error_when_top_level_call_reverts_with_data() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.EqualTo(0), "Gas estimation should fail when top-level call reverts"); + Assert.That(result, Is.EqualTo(0ul), "Gas estimation should fail when top-level call reverts"); Assert.That(err, Is.Not.Null, "Should report an error when top-level reverts"); // The error contains the revert data (hex-encoded output from the REVERT opcode) Assert.That(testEnvironment.tracer.TopLevelRevert, Is.True, "TopLevelRevert should be set for top-level REVERT"); @@ -1235,7 +1235,7 @@ public void Should_estimate_gas_with_delegatecall_that_reverts_internally() .Done; testEnvironment.InsertContract(proxyAddress, proxyCode); - long gasLimit = 300_000; + ulong gasLimit = 300_000ul; Transaction tx = Build.A.Transaction .WithGasLimit(gasLimit) .WithTo(proxyAddress) @@ -1247,9 +1247,9 @@ public void Should_estimate_gas_with_delegatecall_that_reverts_internally() .WithGasLimit(gasLimit) .TestObject; - long result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); + ulong result = testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err); - Assert.That(result, Is.GreaterThan(0), "Gas estimation should succeed when DELEGATECALL reverts but caller handles it"); + Assert.That(result, Is.GreaterThan(0ul), "Gas estimation should succeed when DELEGATECALL reverts but caller handles it"); Assert.That(err, Is.Null, "No error for caught DELEGATECALL revert"); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs index 7c8e7044b40e..c473bef6fb31 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs @@ -44,7 +44,7 @@ public void On_failure_block_and_tx_fields_are_set() Assert.That(trace.TransactionPosition, Is.EqualTo(0), "tx index"); Assert.That(trace.TransactionHash, Is.EqualTo(tx.Hash), "tx hash"); Assert.That(trace.Action.Gas, Is.EqualTo((long)tx.GasLimit - 21000), "gas"); - Assert.That(trace.Action.Value, Is.EqualTo(tx.Value), "value"); + Assert.That(trace.Action.Value, Is.EqualTo((UInt256)tx.Value), "value"); Assert.That(trace.Action.Input.ToArray(), Is.EqualTo(tx.Data.AsArray()), "input"); Assert.That(trace.Action.TraceAddress.ToArray(), Is.EqualTo(Array.Empty()), "trace address"); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs index 8c0f0c501c05..c0c15bcae123 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs @@ -55,7 +55,7 @@ public UInt256 Balance_is_affected_by_blob_gas_on_execution(UInt256 balance, int _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - long gasLimit = GasCostOf.Transaction; + ulong gasLimit = GasCostOf.Transaction; Transaction blobTx = Build.A.Transaction .WithValue(value) .WithGasPrice(1) @@ -93,7 +93,7 @@ public void Rejects_blob_tx_when_max_fee_per_blob_gas_is_below_current_blob_fee( _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - long gasLimit = GasCostOf.Transaction; + ulong gasLimit = GasCostOf.Transaction; Transaction blobTx = Build.A.Transaction .WithGasPrice(1) .WithMaxFeePerGas(1) @@ -119,7 +119,7 @@ public void Rejects_blob_tx_when_max_fee_per_blob_gas_is_below_current_blob_fee( Assert.That(result.TransactionExecuted, Is.False); Assert.That(result.ErrorDescription, Does.Contain(BlockErrorMessages.InsufficientMaxFeePerBlobGas)); Assert.That(_stateProvider.GetBalance(TestItem.PrivateKeyA.Address), Is.EqualTo(balance)); - Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(UInt256.Zero)); + Assert.That(_stateProvider.GetNonce(TestItem.PrivateKeyA.Address), Is.EqualTo(0UL)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs index 164880f73624..a8640fd6ffc3 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs @@ -43,10 +43,10 @@ public void Setup() [TearDown] public void TearDown() => _worldStateCloser?.Dispose(); - [TestCase(21006, false, TestName = "GasLimit=IntrinsicGas")] - [TestCase(21010, true, TestName = "GasLimit=FloorGas")] + [TestCase(21006UL, false, TestName = "GasLimit=IntrinsicGas")] + [TestCase(21010UL, true, TestName = "GasLimit=FloorGas")] - public void transaction_validation_intrinsic_below_floor(long gasLimit, bool executed) + public void transaction_validation_intrinsic_below_floor(ulong gasLimit, bool executed) { _stateProvider.CreateAccount(TestItem.AddressA, 1.Ether); _stateProvider.Commit(_specProvider.GenesisSpec); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTraceTest.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTraceTest.cs index a22aa80509af..ff3b0009e88a 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTraceTest.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTraceTest.cs @@ -13,17 +13,17 @@ namespace Nethermind.Evm.Test; public class TransactionProcessorTraceTest : VirtualMachineTestsBase { - protected override long BlockNumber => MainnetSpecProvider.GrayGlacierBlockNumber; + protected override ulong BlockNumber => MainnetSpecProvider.GrayGlacierBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.ShanghaiBlockTimestamp; - [TestCase(21000)] - [TestCase(50000)] - public void Trace_should_not_charge_gas(long gasLimit) + [TestCase(21000UL)] + [TestCase(50000UL)] + public void Trace_should_not_charge_gas(ulong gasLimit) { (Block block, Transaction transaction) = PrepareTx(BlockNumber, gasLimit, gasPrice: 0); ParityLikeTxTracer tracer = new(block, transaction, ParityTraceTypes.All); _processor.Trace(transaction, new BlockExecutionContext(block.Header, Spec), tracer); ParityStateChange senderBalance = tracer.BuildResult().StateChanges[TestItem.AddressA].Balance; - Assert.That((senderBalance.Before - senderBalance.After), Is.EqualTo(transaction.Value)); + Assert.That((senderBalance.Before - senderBalance.After), Is.EqualTo((UInt256)transaction.Value)); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTests.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTests.cs index 50e5dc095bf7..de7acafbee76 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTests.cs @@ -441,7 +441,7 @@ public void MCopy() .Done; GethLikeTxTrace traces = Execute(new GethLikeTxMemoryTracer(Build.A.Transaction.TestObject, GethTraceOptions.Default), code, MainnetSpecProvider.CancunActivation).BuildResult(); - Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * ((data.Length + 31) / 32) + GasCostOf.Memory * 0), "gas"); + Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)((data.Length + 31) / 32) + GasCostOf.Memory * 0UL), "gas"); } [Test] @@ -462,7 +462,7 @@ public void MCopy_exclusive_areas() string copied = traces.Entries.Last().Memory[0]; string origin = traces.Entries.Last().Memory[1]; - Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * ((data.Length + 31) / 32) + GasCostOf.Memory * 1), "gas"); + Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)((data.Length + 31) / 32) + GasCostOf.Memory * 1UL), "gas"); Assert.That(origin, Is.EqualTo(copied)); } @@ -485,7 +485,7 @@ public void MCopy_Overwrite_areas_copy_right() string result = traces.Entries.Last().Memory[0]; - Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (SLICE_SIZE + 31) / 32), "gas"); + Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)(SLICE_SIZE + 31) / 32), "gas"); Assert.That(result, Is.EqualTo("0101020304050607080000000000000000000000000000000000000000000000"), "memory state"); } @@ -504,7 +504,7 @@ public void MCopy_twice_same_location() MainnetSpecProvider.CancunActivation) .BuildResult(); - Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * ((data.Length + 31) / 32)), "gas"); + Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)((data.Length + 31) / 32)), "gas"); Assert.That(traces.Entries.Last().Memory.Count, Is.EqualTo(1)); } @@ -539,7 +539,7 @@ public void MCopy_Overwrite_areas_copy_left() string result = traces.Entries.Last().Memory[0]; - Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (SLICE_SIZE + 31) / 32), "gas"); + Assert.That(traces.Entries[^2].GasCost, Is.EqualTo(GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)(SLICE_SIZE + 31) / 32), "gas"); Assert.That(result, Is.EqualTo("0102030405060708080000000000000000000000000000000000000000000000"), "memory state"); } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 881b4d79b911..d648633f212c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -29,7 +29,7 @@ public abstract class VirtualMachineTestsBase protected const string SampleHexData1 = "a01234"; protected const string SampleHexData2 = "b15678"; protected const string HexZero = "00"; - protected const long DefaultBlockGasLimit = 8000000; + protected const ulong DefaultBlockGasLimit = 8000000; // was: long — no negative gas limits exist private IEthereumEcdsa _ethereumEcdsa; protected ITransactionProcessor _processor; @@ -49,7 +49,7 @@ public abstract class VirtualMachineTestsBase protected static PrivateKey MinerKey { get; } = TestItem.PrivateKeyD; protected virtual ForkActivation Activation => (BlockNumber, Timestamp); - protected virtual long BlockNumber { get; private set; } = MainnetSpecProvider.ByzantiumBlockNumber; + protected virtual ulong BlockNumber { get; private set; } = MainnetSpecProvider.ByzantiumBlockNumber; protected virtual ulong Timestamp { get; private set; } = 0UL; protected virtual ISpecProvider SpecProvider => MainnetSpecProvider.Instance; protected IReleaseSpec Spec => SpecProvider.GetSpec(Activation); @@ -81,13 +81,13 @@ public virtual void TearDown() protected GethLikeTxTrace ExecuteAndTrace(params byte[] code) { - (Block block, Transaction transaction) = PrepareTx(Activation, 100000, code); + (Block block, Transaction transaction) = PrepareTx(Activation, 100000UL, code); GethLikeTxMemoryTracer tracer = new(transaction, GethTraceOptions.Default with { EnableMemory = true }); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); return tracer.BuildResult(); } - protected GethLikeTxTrace ExecuteAndTrace(long blockNumber, long gasLimit, params byte[] code) + protected GethLikeTxTrace ExecuteAndTrace(ulong blockNumber, ulong gasLimit, params byte[] code) { (Block block, Transaction transaction) = PrepareTx((blockNumber, Timestamp), gasLimit, code); GethLikeTxMemoryTracer tracer = new(transaction, GethTraceOptions.Default); @@ -95,7 +95,8 @@ protected GethLikeTxTrace ExecuteAndTrace(long blockNumber, long gasLimit, param return tracer.BuildResult(); } - protected GethLikeTxTrace ExecuteAndTrace(long gasLimit, params byte[] code) + // gasLimit is ulong — gas limits are non-negative by definition + protected GethLikeTxTrace ExecuteAndTrace(ulong gasLimit, params byte[] code) { (Block block, Transaction transaction) = PrepareTx(Activation, gasLimit, code); GethLikeTxMemoryTracer tracer = new(transaction, GethTraceOptions.Default); @@ -105,7 +106,7 @@ protected GethLikeTxTrace ExecuteAndTrace(long gasLimit, params byte[] code) protected GethLikeTxTrace ExecuteAndTraceToFile(Action dumpCallback, byte[] code, GethTraceOptions options) { - (Block block, Transaction transaction) = PrepareTx(Activation, 100000, code); + (Block block, Transaction transaction) = PrepareTx(Activation, 100000UL, code); GethLikeTxFileTracer tracer = new(dumpCallback, options); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); return tracer.BuildResult(); @@ -114,13 +115,13 @@ protected GethLikeTxTrace ExecuteAndTraceToFile(Action dum /// /// deprecated. Please use activation instead of blockNumber. /// - protected TestAllTracerWithOutput Execute(long blockNumber, params byte[] code) => Execute((blockNumber, Timestamp), code); + protected TestAllTracerWithOutput Execute(ulong blockNumber, params byte[] code) => Execute((blockNumber, Timestamp), code); - protected TestAllTracerWithOutput Execute(ForkActivation activation, params byte[] code) => Execute(activation, 100000, code); + protected TestAllTracerWithOutput Execute(ForkActivation activation, params byte[] code) => Execute(activation, 100000UL, code); - protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLimit, params byte[] code) => Execute(activation, gasLimit, 0, code); + protected TestAllTracerWithOutput Execute(ForkActivation activation, ulong gasLimit, params byte[] code) => Execute(activation, gasLimit, 0UL, code); - protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLimit, ulong slotNumber, params byte[] code) + protected TestAllTracerWithOutput Execute(ForkActivation activation, ulong gasLimit, ulong slotNumber, params byte[] code) { (Block block, Transaction transaction) = PrepareTx(activation, gasLimit, code, slotNumber: slotNumber); TestAllTracerWithOutput tracer = CreateTracer(); @@ -130,7 +131,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim protected TestAllTracerWithOutput Execute(ForkActivation activation, Transaction tx) { - (Block block, _) = PrepareTx(activation, 100000, null); + (Block block, _) = PrepareTx(activation, 100000UL, null); TestAllTracerWithOutput tracer = CreateTracer(); _processor.Execute(tx, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); return tracer; @@ -145,7 +146,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, Transaction protected T ExecuteBlock(T tracer, byte[] code, ForkActivation? forkActivation = null) where T : IBlockTracer { - (Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, 100000, code); + (Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, 100000UL, code); tracer.StartNewBlockTrace(block); ITxTracer txTracer = tracer.StartNewTxTrace(transaction); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), txTracer); @@ -156,7 +157,7 @@ protected T ExecuteBlock(T tracer, byte[] code, ForkActivation? forkActivatio protected T Execute(T tracer, byte[] code, ForkActivation? forkActivation = null) where T : ITxTracer { - (Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, 100000, code); + (Block block, Transaction transaction) = PrepareTx(forkActivation ?? Activation, 100000UL, code); _processor.Execute(transaction, new BlockExecutionContext(block.Header, SpecProvider.GetSpec(block.Header)), tracer); return tracer; } @@ -164,8 +165,8 @@ protected T Execute(T tracer, byte[] code, ForkActivation? forkActivation = n /// /// deprecated. Please use activation instead of blockNumber. /// - protected TestAllTracerWithOutput Execute(long blockNumber, long gasLimit, byte[] code, - long blockGasLimit = DefaultBlockGasLimit, byte[][] blobVersionedHashes = null) + protected TestAllTracerWithOutput Execute(ulong blockNumber, ulong gasLimit, byte[] code, + ulong blockGasLimit = DefaultBlockGasLimit, byte[][] blobVersionedHashes = null) { (Block block, Transaction transaction) = PrepareTx((blockNumber, Timestamp), gasLimit, code, blockGasLimit: blockGasLimit, blobVersionedHashes: blobVersionedHashes); @@ -174,8 +175,8 @@ protected TestAllTracerWithOutput Execute(long blockNumber, long gasLimit, byte[ return tracer; } - protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLimit, byte[] code, - long blockGasLimit = DefaultBlockGasLimit, byte[][] blobVersionedHashes = null) + protected TestAllTracerWithOutput Execute(ForkActivation activation, ulong gasLimit, byte[] code, + ulong blockGasLimit = DefaultBlockGasLimit, byte[][] blobVersionedHashes = null) { (Block block, Transaction transaction) = PrepareTx(activation, gasLimit, code, blockGasLimit: blockGasLimit, blobVersionedHashes: blobVersionedHashes); @@ -188,23 +189,23 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim /// deprecated. Please use activation instead of blockNumber. /// protected (Block block, Transaction transaction) PrepareTx( - long blockNumber, - long gasLimit, + ulong blockNumber, + ulong gasLimit, byte[]? code = null, SenderRecipientAndMiner? senderRecipientAndMiner = null, int value = 1, - long blockGasLimit = DefaultBlockGasLimit, + ulong blockGasLimit = DefaultBlockGasLimit, byte[][]? blobVersionedHashes = null, ulong excessBlobGas = 0, ulong gasPrice = 1) => PrepareTx((blockNumber, Timestamp), gasLimit, code, senderRecipientAndMiner, value, blockGasLimit, blobVersionedHashes, excessBlobGas, gasPrice: gasPrice); protected (Block block, Transaction transaction) PrepareTx( ForkActivation activation, - long gasLimit, + ulong gasLimit, byte[]? code = null, SenderRecipientAndMiner? senderRecipientAndMiner = null, int value = 1, - long blockGasLimit = DefaultBlockGasLimit, + ulong blockGasLimit = DefaultBlockGasLimit, byte[][]? blobVersionedHashes = null, ulong excessBlobGas = 0, ulong slotNumber = 0, @@ -258,10 +259,10 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim /// /// deprecated. Please use activation instead of blockNumber. /// - protected (Block block, Transaction transaction) PrepareTx(long blockNumber, long gasLimit, byte[] code, + protected (Block block, Transaction transaction) PrepareTx(ulong blockNumber, ulong gasLimit, byte[] code, byte[] input, UInt256 value, SenderRecipientAndMiner senderRecipientAndMiner = null, ulong gasPrice = 1) => PrepareTx((blockNumber, Timestamp), gasLimit, code, input, value, senderRecipientAndMiner); - protected (Block block, Transaction transaction) PrepareTx(ForkActivation activation, long gasLimit, byte[] code, + protected (Block block, Transaction transaction) PrepareTx(ForkActivation activation, ulong gasLimit, byte[] code, byte[] input, UInt256 value, SenderRecipientAndMiner senderRecipientAndMiner = null) { senderRecipientAndMiner ??= SenderRecipientAndMiner.Default; @@ -285,7 +286,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim Transaction transaction = Build.A.Transaction .WithGasLimit(gasLimit) - .WithGasPrice(1) + .WithGasPrice(1UL) .WithNonce(TestState.GetNonce(senderRecipientAndMiner.Sender)) .WithData(input) .WithValue(value) @@ -297,7 +298,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim return (block, transaction); } - protected (Block block, Transaction transaction) PrepareInitTx(ForkActivation activation, long gasLimit, byte[] code, + protected (Block block, Transaction transaction) PrepareInitTx(ForkActivation activation, ulong gasLimit, byte[] code, SenderRecipientAndMiner senderRecipientAndMiner = null) { senderRecipientAndMiner ??= SenderRecipientAndMiner.Default; @@ -307,7 +308,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim Transaction transaction = Build.A.Transaction .WithTo(null) .WithGasLimit(gasLimit) - .WithGasPrice(1) + .WithGasPrice(1UL) .WithCode(code) .SignedAndResolved(_ethereumEcdsa, senderRecipientAndMiner.SenderKey) .TestObject; @@ -319,7 +320,7 @@ protected TestAllTracerWithOutput Execute(ForkActivation activation, long gasLim protected Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner) => BuildBlock(activation, senderRecipientAndMiner, null); protected virtual Block BuildBlock(ForkActivation activation, SenderRecipientAndMiner senderRecipientAndMiner, - Transaction tx, long blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) + Transaction tx, ulong blockGasLimit = DefaultBlockGasLimit, ulong excessBlobGas = 0, ulong slotNumber = 0) { senderRecipientAndMiner ??= SenderRecipientAndMiner.Default; return Build.A.Block.WithNumber(activation.BlockNumber) @@ -335,7 +336,7 @@ protected virtual Block BuildBlock(ForkActivation activation, SenderRecipientAnd .TestObject; } - protected void AssertGas(TestAllTracerWithOutput receipt, long gas) => Assert.That(receipt.GasSpent, Is.EqualTo(gas), "gas"); + protected void AssertGas(TestAllTracerWithOutput receipt, ulong gas) => Assert.That(receipt.GasSpent, Is.EqualTo(gas), "gas"); protected void AssertStorage(UInt256 address, Address value) => Assert.That(TestState.Get(new StorageCell(Recipient, address)).PadLeft(32), Is.EqualTo(value.Bytes.PadLeft(32)), "storage"); diff --git a/src/Nethermind/Nethermind.Evm.Test/VmCodeDepositTests.cs b/src/Nethermind/Nethermind.Evm.Test/VmCodeDepositTests.cs index 88330c38df43..88d76da779bf 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VmCodeDepositTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VmCodeDepositTests.cs @@ -14,9 +14,9 @@ namespace Nethermind.Evm.Test [Parallelizable(ParallelScope.Self)] public class VmCodeDepositTests : VirtualMachineTestsBase { - private long _blockNumber = MainnetSpecProvider.ByzantiumBlockNumber; + private ulong _blockNumber = MainnetSpecProvider.ByzantiumBlockNumber; - protected override long BlockNumber => _blockNumber; + protected override ulong BlockNumber => _blockNumber; [SetUp] public override void Setup() diff --git a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs index 9a812fd3d8f5..3b0c125dd6fc 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs @@ -222,12 +222,12 @@ public void Can_dispose_after_init() private static VmState CreateEvmState(VmState parentVmState = null, bool isContinuation = false) => parentVmState is null - ? VmState.RentTopLevel(EthereumGasPolicy.FromLong(10000), + ? VmState.RentTopLevel(EthereumGasPolicy.FromULong(10000), ExecutionType.CALL, RentExecutionEnvironment(), new StackAccessTracker(), Snapshot.Empty) - : VmState.RentFrame(EthereumGasPolicy.FromLong(10000), + : VmState.RentFrame(EthereumGasPolicy.FromULong(10000), 0, 0, ExecutionType.CALL, diff --git a/src/Nethermind/Nethermind.Evm/AccountOverride.cs b/src/Nethermind/Nethermind.Evm/AccountOverride.cs index 91fe22d9f407..ea2f0ea31a23 100644 --- a/src/Nethermind/Nethermind.Evm/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Evm/AccountOverride.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm; public class AccountOverride { - public UInt256? Nonce { get; set; } + public ulong? Nonce { get; set; } public UInt256? Balance { get; set; } public byte[]? Code { get; set; } public Address? MovePrecompileToAddress { get; set; } diff --git a/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs b/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs index aae08a91cbb1..0b69413803f6 100644 --- a/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs +++ b/src/Nethermind/Nethermind.Evm/BlockExecutionContext.cs @@ -48,8 +48,8 @@ private BlockExecutionContext( { Header = blockHeader; Coinbase = blockHeader.GasBeneficiary ?? Address.Zero; - Number = (ulong)blockHeader.Number; - GasLimit = (ulong)blockHeader.GasLimit; + Number = blockHeader.Number; + GasLimit = blockHeader.GasLimit; BlobBaseFee = blobBaseFee.ToValueHash(); Spec = spec; PrevRandao = prevRandao; diff --git a/src/Nethermind/Nethermind.Evm/BlockOverride.cs b/src/Nethermind/Nethermind.Evm/BlockOverride.cs index e43e39d24ec3..99d537cb9857 100644 --- a/src/Nethermind/Nethermind.Evm/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Evm/BlockOverride.cs @@ -22,15 +22,10 @@ public void ApplyOverrides(BlockHeader result) { if (Time is not null) result.Timestamp = Time.Value; if (GasLimit is not null) - { - if (GasLimit > long.MaxValue) - { - throw new OverflowException($"GasLimit value is too large, max value {long.MaxValue}"); - } - result.GasLimit = (long)GasLimit.Value; - } + result.GasLimit = GasLimit.Value; - if (Number is not null) result.Number = (long)Number.Value; + if (Number is not null) + result.Number = Number.Value; if (FeeRecipient is not null) { // Set Author as well because GasBeneficiary = Author ?? Beneficiary. diff --git a/src/Nethermind/Nethermind.Evm/BlockOverrideExtensions.cs b/src/Nethermind/Nethermind.Evm/BlockOverrideExtensions.cs index b251fd4d038e..8728f31a51a6 100644 --- a/src/Nethermind/Nethermind.Evm/BlockOverrideExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/BlockOverrideExtensions.cs @@ -5,6 +5,6 @@ namespace Nethermind.Evm; public static class BlockOverrideExtensions { - public static ulong GetBlockNumber(this BlockOverride? blockOverride, long lastBlockNumber) - => blockOverride?.Number ?? (ulong)lastBlockNumber + 1; + public static ulong GetBlockNumber(this BlockOverride? blockOverride, ulong lastBlockNumber) + => blockOverride?.Number ?? lastBlockNumber + 1; } diff --git a/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs b/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs index dc1b700b8c31..236887880583 100644 --- a/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs +++ b/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs @@ -12,68 +12,68 @@ public static class CodeDepositHandler { private const byte InvalidStartingCodeByte = 0xEF; - public static long CalculateCost(IReleaseSpec spec, int byteCodeLength) => - CalculateCost(spec, byteCodeLength, out long regularCost, out long stateCost) + public static ulong CalculateCost(IReleaseSpec spec, int byteCodeLength) => + CalculateCost(spec, byteCodeLength, out ulong regularCost, out ulong stateCost) ? regularCost + stateCost - : long.MaxValue; + : ulong.MaxValue; - public static long CalculateCost(IReleaseSpec spec, int byteCodeLength, in TGasPolicy gas) + public static ulong CalculateCost(IReleaseSpec spec, int byteCodeLength, in TGasPolicy gas) where TGasPolicy : struct, IGasPolicy => - CalculateCost(spec, byteCodeLength, in gas, out long regularCost, out long stateCost) + CalculateCost(spec, byteCodeLength, in gas, out ulong regularCost, out ulong stateCost) ? regularCost + stateCost - : long.MaxValue; + : ulong.MaxValue; - public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, out long regularCost, out long stateCost) + public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, out ulong regularCost, out ulong stateCost) { stateCost = 0; if (spec.LimitCodeSize && byteCodeLength > spec.MaxCodeSize) { - regularCost = long.MaxValue; + regularCost = ulong.MaxValue; return false; } if (!spec.IsEip8037Enabled) { - regularCost = GasCostOf.CodeDeposit * byteCodeLength; + regularCost = GasCostOf.CodeDeposit * (ulong)byteCodeLength; return true; } - long words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); + ulong words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); if (outOfGas) { - regularCost = long.MaxValue; - stateCost = long.MaxValue; + regularCost = ulong.MaxValue; + stateCost = ulong.MaxValue; return false; } regularCost = GasCostOf.CodeDepositRegularPerWord * words; - stateCost = GasCostOf.CodeDepositState * byteCodeLength; + stateCost = GasCostOf.CodeDepositState * (ulong)byteCodeLength; return true; } - public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, in TGasPolicy gas, out long regularCost, out long stateCost) + public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, in TGasPolicy gas, out ulong regularCost, out ulong stateCost) where TGasPolicy : struct, IGasPolicy { stateCost = 0; if (spec.LimitCodeSize && byteCodeLength > spec.MaxCodeSize) { - regularCost = long.MaxValue; + regularCost = ulong.MaxValue; return false; } if (!spec.IsEip8037Enabled) { - regularCost = GasCostOf.CodeDeposit * byteCodeLength; + regularCost = GasCostOf.CodeDeposit * (ulong)byteCodeLength; return true; } - long words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); + ulong words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); if (outOfGas) { - regularCost = long.MaxValue; - stateCost = long.MaxValue; + regularCost = ulong.MaxValue; + stateCost = ulong.MaxValue; return false; } diff --git a/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs b/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs index b2faf519fdfe..1a4b8201076a 100644 --- a/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs +++ b/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs @@ -246,32 +246,32 @@ private void ClearForTracing(ulong size) } } - public long CalculateMemoryCost(in UInt256 location, ulong length, out bool outOfGas) + public ulong CalculateMemoryCost(in UInt256 location, ulong length, out bool outOfGas) { if (length == 0) { outOfGas = false; - return 0L; + return 0; } CheckMemoryAccessViolation(in location, length, out ulong newSize, out outOfGas); if (outOfGas) return 0; - return newSize > Size ? ComputeMemoryExpansionCost(newSize) : 0L; + return newSize > Size ? ComputeMemoryExpansionCost(newSize) : 0; } - public long CalculateMemoryCost(in UInt256 location, in UInt256 length, out bool outOfGas) + public ulong CalculateMemoryCost(in UInt256 location, in UInt256 length, out bool outOfGas) { if (length.IsZero) { outOfGas = false; - return 0L; + return 0; } CheckMemoryAccessViolation(in location, in length, out ulong newSize, out outOfGas); if (outOfGas) return 0; - return newSize > Size ? ComputeMemoryExpansionCost(newSize) : 0L; + return newSize > Size ? ComputeMemoryExpansionCost(newSize) : 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -339,7 +339,7 @@ internal void CopyAfterGas(in UInt256 destination, in UInt256 source, ulong leng } [MethodImpl(MethodImplOptions.NoInlining)] - private long ComputeMemoryExpansionCost(ulong newSize) + private ulong ComputeMemoryExpansionCost(ulong newSize) { // CheckMemoryAccessViolation has already capped newSize at MaxMemorySize (< 2^31), so the // ceiling division cannot overflow uint and the squared terms stay below 2^52. Size is @@ -352,9 +352,9 @@ private long ComputeMemoryExpansionCost(ulong newSize) // Full Yellow Paper memory cost is bounded above by ~8.8e12 gas, which fits comfortably // in long -- so the outOfGas propagation that older revisions carried is unreachable. - long cost = (newActiveWords - activeWords) * GasCostOf.Memory + - ((newActiveWords * newActiveWords) >> 9) - - ((activeWords * activeWords) >> 9); + ulong cost = (ulong)(newActiveWords - activeWords) * GasCostOf.Memory + + (ulong)((newActiveWords * newActiveWords) >> 9) - + (ulong)((activeWords * activeWords) >> 9); UpdateSize(newSize, rentIfNeeded: false); diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs index 3412bd2fc0ba..c200a3fdfdfa 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs @@ -14,18 +14,18 @@ public static class Eip8037BlockGasInclusionCheck public enum Outcome { Ok, RegularDimensionExceeded, StateDimensionExceeded } public static Outcome Validate( - long blockGasLimit, - long cumulativeBlockRegular, - long cumulativeBlockState, - long txGas, - long intrinsicRegular, - long intrinsicState) + ulong blockGasLimit, + ulong cumulativeBlockRegular, + ulong cumulativeBlockState, + ulong txGas, + ulong intrinsicRegular, + ulong intrinsicState) { - long regularAvailable = blockGasLimit - cumulativeBlockRegular; - long stateAvailable = blockGasLimit - cumulativeBlockState; + ulong regularAvailable = blockGasLimit - cumulativeBlockRegular; + ulong stateAvailable = blockGasLimit - cumulativeBlockState; // Keep below-intrinsic txs from producing a negative worst-case regular dimension. - long worstCaseRegular = Math.Max(0, txGas - intrinsicState); + ulong worstCaseRegular = txGas > intrinsicState ? txGas - intrinsicState : 0UL; if (worstCaseRegular > Eip7825Constants.DefaultTxGasLimitCap) worstCaseRegular = Eip7825Constants.DefaultTxGasLimitCap; if (worstCaseRegular > regularAvailable) @@ -33,23 +33,23 @@ public static Outcome Validate( // The state dimension has no per-tx equivalent of EIP-7825's DefaultTxGasLimitCap; // state-heavy work may be funded by the state reservoir above that regular-dimension cap. - long worstCaseState = Math.Max(0, txGas - intrinsicRegular); + ulong worstCaseState = txGas > intrinsicRegular ? txGas - intrinsicRegular : 0UL; if (worstCaseState > stateAvailable) return Outcome.StateDimensionExceeded; return Outcome.Ok; } - public static long CalculateBlockRegularGas( - long intrinsicRegularGas, - long initialRegularGas, - long remainingRegularGas, - long stateGasSpill, - long stateGasSpillReclassified, - long floorGas) + public static ulong CalculateBlockRegularGas( + ulong intrinsicRegularGas, + ulong initialRegularGas, + ulong remainingRegularGas, + ulong stateGasSpill, + ulong stateGasSpillReclassified, + ulong floorGas) { - long executionRegularGasUsed = initialRegularGas - remainingRegularGas - stateGasSpill + stateGasSpillReclassified; - long blockRegularGas = intrinsicRegularGas + executionRegularGasUsed; + ulong executionRegularGasUsed = initialRegularGas - remainingRegularGas - stateGasSpill + stateGasSpillReclassified; + ulong blockRegularGas = intrinsicRegularGas + executionRegularGasUsed; return Math.Max(blockRegularGas, floorGas); } } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 7c8212a93f8e..281d5e9b5bf7 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -19,25 +19,25 @@ namespace Nethermind.Evm.GasPolicy; public struct EthereumGasPolicy : IGasPolicy { /// Regular gas budget (legacy gas_left). - public long Value; + public ulong Value; /// State gas reservoir used by EIP-8037 paths. - public long StateReservoir; + public ulong StateReservoir; /// Cumulative state gas used for block accounting. - public long StateGasUsed; + public ulong StateGasUsed; /// State gas that spilled from gas_left (for block regular gas exclusion). - public long StateGasSpill; + public ulong StateGasSpill; /// Tx-cumulative spill from reverted child frames used by top-level halt accounting. - public long StateGasSpillBurned; + public ulong StateGasSpillBurned; /// Spill that should remain in the block regular dimension. - public long StateGasSpillReclassified; + public ulong StateGasSpillReclassified; /// Spill consumed by state refunds and excluded from block regular gas. - public long StateGasSpillRefunded; + public ulong StateGasSpillRefunded; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EthereumGasPolicy FromLong(long value) => new() { Value = value }; + public static EthereumGasPolicy FromULong(ulong value) => new() { Value = value }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EthereumGasPolicy CreateSystemTransactionIntrinsicGas(long blockGasLimit) => + public static EthereumGasPolicy CreateSystemTransactionIntrinsicGas(ulong blockGasLimit) => new() { Value = 0, @@ -45,7 +45,7 @@ public static EthereumGasPolicy CreateSystemTransactionIntrinsicGas(long blockGa }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EthereumGasPolicy CreateSystemTransactionAvailableGas(long gasLimit, in EthereumGasPolicy intrinsicGas, IReleaseSpec spec) + public static EthereumGasPolicy CreateSystemTransactionAvailableGas(ulong gasLimit, in EthereumGasPolicy intrinsicGas, IReleaseSpec spec) { if (spec.IsEip8037Enabled) { @@ -62,50 +62,50 @@ public static EthereumGasPolicy CreateSystemTransactionAvailableGas(long gasLimi } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetRemainingGas(in EthereumGasPolicy gas) => gas.Value; + public static ulong GetRemainingGas(in EthereumGasPolicy gas) => gas.Value; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStorageSetStateCost(in EthereumGasPolicy gas) => GasCostOf.SSetState; + public static ulong GetStorageSetStateCost(in EthereumGasPolicy gas) => GasCostOf.SSetState; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetCreateStateCost(in EthereumGasPolicy gas) => GasCostOf.CreateState; + public static ulong GetCreateStateCost(in EthereumGasPolicy gas) => GasCostOf.CreateState; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetNewAccountStateCost(in EthereumGasPolicy gas) => GasCostOf.NewAccountState; + public static ulong GetNewAccountStateCost(in EthereumGasPolicy gas) => GasCostOf.NewAccountState; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetPerAuthBaseStateCost(in EthereumGasPolicy gas) => GasCostOf.PerAuthBaseState; + public static ulong GetPerAuthBaseStateCost(in EthereumGasPolicy gas) => GasCostOf.PerAuthBaseState; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetCodeDepositStateCost(in EthereumGasPolicy gas, int byteCodeLength) => GasCostOf.CodeDepositState * byteCodeLength; + public static ulong GetCodeDepositStateCost(in EthereumGasPolicy gas, int byteCodeLength) => GasCostOf.CodeDepositState * (ulong)byteCodeLength; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStorageSetReversalRefund(in EthereumGasPolicy gas) => RefundOf.SSetReversedEip8037; + public static ulong GetStorageSetReversalRefund(in EthereumGasPolicy gas) => RefundOf.SSetReversedEip8037; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateReservoir(in EthereumGasPolicy gas) => gas.StateReservoir; + public static ulong GetStateReservoir(in EthereumGasPolicy gas) => gas.StateReservoir; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateGasUsed(in EthereumGasPolicy gas) => gas.StateGasUsed; + public static ulong GetStateGasUsed(in EthereumGasPolicy gas) => gas.StateGasUsed; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateGasSpill(in EthereumGasPolicy gas) => gas.StateGasSpill; + public static ulong GetStateGasSpill(in EthereumGasPolicy gas) => gas.StateGasSpill; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateGasSpillBurned(in EthereumGasPolicy gas) => gas.StateGasSpillBurned; + public static ulong GetStateGasSpillBurned(in EthereumGasPolicy gas) => gas.StateGasSpillBurned; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateGasSpillReclassified(in EthereumGasPolicy gas) => gas.StateGasSpillReclassified; + public static ulong GetStateGasSpillReclassified(in EthereumGasPolicy gas) => gas.StateGasSpillReclassified; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetStateGasSpillRefunded(in EthereumGasPolicy gas) => gas.StateGasSpillRefunded; + public static ulong GetStateGasSpillRefunded(in EthereumGasPolicy gas) => gas.StateGasSpillRefunded; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Consume(ref EthereumGasPolicy gas, long cost) => gas.Value -= cost; + public static void Consume(ref EthereumGasPolicy gas, ulong cost) => gas.Value -= cost; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool ConsumeStateGas(ref EthereumGasPolicy gas, long stateGasCost) + public static bool ConsumeStateGas(ref EthereumGasPolicy gas, ulong stateGasCost) { if (gas.StateReservoir >= stateGasCost) { @@ -114,7 +114,7 @@ public static bool ConsumeStateGas(ref EthereumGasPolicy gas, long stateGasCost) return true; } - long spillAmount = stateGasCost - gas.StateReservoir; + ulong spillAmount = stateGasCost - gas.StateReservoir; if (!UpdateGas(ref gas, spillAmount)) { return false; @@ -126,7 +126,7 @@ public static bool ConsumeStateGas(ref EthereumGasPolicy gas, long stateGasCost) return true; } - public static bool TryConsumeStateAndRegularGas(ref EthereumGasPolicy gas, long stateGasCost, long regularGasCost) => + public static bool TryConsumeStateAndRegularGas(ref EthereumGasPolicy gas, ulong stateGasCost, ulong regularGasCost) => (regularGasCost <= 0 || UpdateGas(ref gas, regularGasCost)) && (stateGasCost <= 0 || ConsumeStateGas(ref gas, stateGasCost)); @@ -137,7 +137,7 @@ public static bool ConsumeSelfDestructGas(ref EthereumGasPolicy gas) /// Consume gas for code deposit. For standard Ethereum, this is equivalent to Consume. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ConsumeCodeDeposit(ref EthereumGasPolicy gas, long cost) + public static void ConsumeCodeDeposit(ref EthereumGasPolicy gas, ulong cost) => Consume(ref gas, cost); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -187,7 +187,7 @@ public static void RevertRefundToHalt(ref EthereumGasPolicy parentGas, in Ethere } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) => + private static ulong GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) => Math.Max(0, childGas.StateGasSpill - childGas.StateGasSpillRefunded); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -256,7 +256,7 @@ public static bool UpdateMemoryCost(ref EthereumGasPolicy gas, in UInt256 position, in UInt256 length, VmState vmState) { - long memoryCost = vmState.Memory.CalculateMemoryCost(in position, length, out bool outOfGas); + ulong memoryCost = vmState.Memory.CalculateMemoryCost(in position, length, out bool outOfGas); if (memoryCost == 0L) return !outOfGas; return UpdateGas(ref gas, memoryCost); @@ -267,15 +267,15 @@ public static bool UpdateMemoryCost(ref EthereumGasPolicy gas, in UInt256 position, ulong length, VmState vmState) { - long memoryCost = vmState.Memory.CalculateMemoryCost(in position, length, out bool outOfGas); - if (memoryCost == 0L) + ulong memoryCost = vmState.Memory.CalculateMemoryCost(in position, length, out bool outOfGas); + if (memoryCost == 0) return !outOfGas; return UpdateGas(ref gas, memoryCost); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool UpdateGas(ref EthereumGasPolicy gas, - long gasCost) + ulong gasCost) { if (GetRemainingGas(in gas) < gasCost) return false; @@ -301,17 +301,17 @@ public static bool ConsumeStorageWrite(ref EthereumGa [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UpdateGasUp(ref EthereumGasPolicy gas, - long refund) => gas.Value += refund; + ulong refund) => gas.Value += refund; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RefundStateGas(ref EthereumGasPolicy gas, long amount, long stateGasFloor) + public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor) => RefundStateGas(ref gas, amount, stateGasFloor, trackSpillRefund: true); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RefundStateGas(ref EthereumGasPolicy gas, long amount, long stateGasFloor, bool trackSpillRefund) + public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - long refundableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); - long appliedRefund = Math.Min(amount, refundableStateGas); + ulong refundableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); + ulong appliedRefund = Math.Min(amount, refundableStateGas); if (trackSpillRefund) { TrackStateGasSpillRefund(ref gas, appliedRefund); @@ -322,10 +322,10 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, long amount, long s } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long DiscardStateGas(ref EthereumGasPolicy gas, long amount, long stateGasFloor, bool trackSpillRefund) + public static ulong DiscardStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - long discardableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); - long appliedRefund = Math.Min(amount, discardableStateGas); + ulong discardableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); + ulong appliedRefund = Math.Min(amount, discardableStateGas); if (trackSpillRefund) { TrackStateGasSpillRefund(ref gas, appliedRefund); @@ -336,7 +336,7 @@ public static long DiscardStateGas(ref EthereumGasPolicy gas, long amount, long } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AddStateGasRefundToReservoir(ref EthereumGasPolicy gas, long amount, bool trackSpillRefund) + public static void AddStateGasRefundToReservoir(ref EthereumGasPolicy gas, ulong amount, bool trackSpillRefund) { if (trackSpillRefund) { @@ -347,9 +347,9 @@ public static void AddStateGasRefundToReservoir(ref EthereumGasPolicy gas, long } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RemoveStateGasRefundFromReservoir(ref EthereumGasPolicy gas, long amount) + public static void RemoveStateGasRefundFromReservoir(ref EthereumGasPolicy gas, ulong amount) { - long fromReservoir = Math.Min(amount, gas.StateReservoir); + ulong fromReservoir = Math.Min(amount, gas.StateReservoir); gas.StateReservoir -= fromReservoir; amount -= fromReservoir; @@ -360,14 +360,14 @@ public static void RemoveStateGasRefundFromReservoir(ref EthereumGasPolicy gas, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void TrackStateGasSpillRefund(ref EthereumGasPolicy gas, long amount) + private static void TrackStateGasSpillRefund(ref EthereumGasPolicy gas, ulong amount) { - long unrefundedSpill = GetUnrefundedStateGasSpill(in gas); + ulong unrefundedSpill = GetUnrefundedStateGasSpill(in gas); gas.StateGasSpillRefunded += Math.Min(amount, unrefundedSpill); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ResetForHalt(ref EthereumGasPolicy gas, long initialStateReservoir, long initialStateGasUsed) + public static void ResetForHalt(ref EthereumGasPolicy gas, ulong initialStateReservoir, ulong initialStateGasUsed) { // Snap state-gas back to its tx-start shape (reservoir=R0, used=intrinsic floor, // spill=0). The post-reset StateGasUsed feeds SpentGas so the user does not keep @@ -381,18 +381,18 @@ public static void ResetForHalt(ref EthereumGasPolicy gas, long initialStateRese } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => + public static ulong GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => spec.IsEip8037Enabled || codeInsertRefunds <= 0 ? 0 - : (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * codeInsertRefunds; + : (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * (ulong)codeInsertRefunds; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, int codeInsertRefunds, IReleaseSpec spec, long stateGasFloor) + public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, int codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) { if (codeInsertRefunds > 0 && spec.IsEip8037Enabled) { - long stateGasRefund = checked(GetNewAccountStateCost(in gas) * codeInsertRefunds); - long refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); + ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * (ulong)codeInsertRefunds); + ulong refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); RefundStateGas(ref gas, stateGasRefund, refundFloor, trackSpillRefund: false); } @@ -413,13 +413,13 @@ public static bool ConsumeCallValueTransfer(ref EthereumGasPolicy gas) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ConsumeLogEmission(ref EthereumGasPolicy gas, long topicCount, long dataSize) { - long cost = GasCostOf.Log + topicCount * GasCostOf.LogTopic + dataSize * GasCostOf.LogData; + ulong cost = GasCostOf.Log + (ulong)topicCount * GasCostOf.LogTopic + (ulong)dataSize * GasCostOf.LogData; return UpdateGas(ref gas, cost); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ConsumeDataCopyGas(ref EthereumGasPolicy gas, bool isExternalCode, long baseCost, long dataCost) - => Consume(ref gas, baseCost + dataCost); + public static void ConsumeDataCopyGas(ref EthereumGasPolicy gas, bool isExternalCode, ulong baseCost, ulong dataCost) + => Consume(ref gas, (ulong)(baseCost + dataCost)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void OnBeforeInstructionTrace(in EthereumGasPolicy gas, int pc, Instruction instruction, int depth) { } @@ -432,9 +432,9 @@ public static EthereumGasPolicy Max(in EthereumGasPolicy a, in EthereumGasPolicy a.Value >= b.Value ? a : b; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EthereumGasPolicy CreateChildFrameGas(ref EthereumGasPolicy parentGas, long childRegularGas) + public static EthereumGasPolicy CreateChildFrameGas(ref EthereumGasPolicy parentGas, ulong childRegularGas) { - long childStateReservoir = parentGas.StateReservoir; + ulong childStateReservoir = parentGas.StateReservoir; parentGas.StateReservoir = 0; return new EthereumGasPolicy @@ -450,43 +450,43 @@ public static EthereumGasPolicy CreateChildFrameGas(ref EthereumGasPolicy parent public static IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec) => CalculateIntrinsicGas(tx, spec, blockGasLimit: 0); - public static IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, long blockGasLimit) + public static IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, ulong blockGasLimit) { - long tokensInCallData = IGasPolicy.CalculateTokensInCallData(tx, spec); - long floorTokensInAccessList = IGasPolicy.CalculateFloorTokensInAccessList(tx, spec); - (long authRegularCost, long authStateCost) = IGasPolicy.AuthorizationListCost(tx, spec); - long accessListCost = IGasPolicy.AccessListCost(tx, spec, floorTokensInAccessList); + ulong tokensInCallData = IGasPolicy.CalculateTokensInCallData(tx, spec); + ulong floorTokensInAccessList = IGasPolicy.CalculateFloorTokensInAccessList(tx, spec); + (ulong authRegularCost, ulong authStateCost) = IGasPolicy.AuthorizationListCost(tx, spec); + ulong accessListCost = IGasPolicy.AccessListCost(tx, spec, floorTokensInAccessList); - long regularGas = GasCostOf.Transaction + ulong regularGas = (ulong)(GasCostOf.Transaction + DataCost(tx, spec, tokensInCallData) + CreateCost(tx, spec) + accessListCost - + authRegularCost; - long floorCost = IGasPolicy.CalculateFloorCost(tx, spec, tokensInCallData, floorTokensInAccessList); - long createStateCost = CreateStateCost(tx, spec); - long totalStateCost = authStateCost + createStateCost; + + authRegularCost); + ulong floorCost = IGasPolicy.CalculateFloorCost(tx, spec, tokensInCallData, floorTokensInAccessList); + ulong createStateCost = CreateStateCost(tx, spec); + ulong totalStateCost = authStateCost + createStateCost; return spec.IsEip8037Enabled ? new IntrinsicGas( new EthereumGasPolicy { Value = regularGas, - StateReservoir = totalStateCost, - StateGasUsed = totalStateCost, + StateReservoir = (ulong)totalStateCost, + StateGasUsed = (ulong)totalStateCost, }, - FromLong(floorCost)) - : new IntrinsicGas(FromLong(regularGas), FromLong(floorCost)); + FromULong(floorCost)) + : new IntrinsicGas(FromULong(regularGas), FromULong(floorCost)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EthereumGasPolicy CreateAvailableFromIntrinsic(long gasLimit, in EthereumGasPolicy intrinsicGas, IReleaseSpec spec) + public static EthereumGasPolicy CreateAvailableFromIntrinsic(ulong gasLimit, in EthereumGasPolicy intrinsicGas, IReleaseSpec spec) { - long executionGas = gasLimit - intrinsicGas.Value - intrinsicGas.StateReservoir; - long reservoir = 0; + ulong executionGas = gasLimit - intrinsicGas.Value - intrinsicGas.StateReservoir; + ulong reservoir = 0; if (spec.IsEip8037Enabled) { // EIP-8037: cap gas_left at TX_MAX_GAS_LIMIT - intrinsic_regular, overflow goes to reservoir - long maxGasLeft = Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value; + ulong maxGasLeft = Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value; reservoir = Math.Max(0, executionGas - maxGasLeft); executionGas -= reservoir; } @@ -501,17 +501,17 @@ public static EthereumGasPolicy CreateAvailableFromIntrinsic(long gasLimit, in E } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long CreateCost(Transaction tx, IReleaseSpec spec) => + private static ulong CreateCost(Transaction tx, IReleaseSpec spec) => tx.IsContractCreation && spec.IsEip2Enabled ? (spec.IsEip8037Enabled ? GasCostOf.CreateRegular : GasCostOf.TxCreate) : 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long CreateStateCost(Transaction tx, IReleaseSpec spec) => + private static ulong CreateStateCost(Transaction tx, IReleaseSpec spec) => tx.IsContractCreation && spec.IsEip8037Enabled ? GasCostOf.CreateState : 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long DataCost(Transaction tx, IReleaseSpec spec, long tokensInCallData) => + private static ulong DataCost(Transaction tx, IReleaseSpec spec, ulong tokensInCallData) => spec.GetBaseDataCost(tx) + tokensInCallData * GasCostOf.TxDataZero; } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs index 76ea2de0f9f1..ec54884a59f7 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs @@ -15,39 +15,39 @@ namespace Nethermind.Evm.GasPolicy; public interface IGasPolicy where TSelf : struct, IGasPolicy { - static abstract TSelf FromLong(long value); + static abstract TSelf FromULong(ulong value); - static virtual TSelf CreateSystemTransactionIntrinsicGas(long blockGasLimit) => TSelf.FromLong(0); + static virtual TSelf CreateSystemTransactionIntrinsicGas(ulong blockGasLimit) => TSelf.FromULong(0); - static virtual TSelf CreateSystemTransactionAvailableGas(long gasLimit, in TSelf intrinsicGas, IReleaseSpec spec) => + static virtual TSelf CreateSystemTransactionAvailableGas(ulong gasLimit, in TSelf intrinsicGas, IReleaseSpec spec) => TSelf.CreateAvailableFromIntrinsic(gasLimit, in intrinsicGas, spec); - static abstract long GetRemainingGas(in TSelf gas); + static abstract ulong GetRemainingGas(in TSelf gas); // EIP-8037 state-cost accessors. Pre-EIP-8037 policies return the constant fallback. - static virtual long GetStorageSetStateCost(in TSelf gas) => GasCostOf.SSetState; - static virtual long GetCreateStateCost(in TSelf gas) => GasCostOf.CreateState; - static virtual long GetNewAccountStateCost(in TSelf gas) => GasCostOf.NewAccountState; - static virtual long GetPerAuthBaseStateCost(in TSelf gas) => GasCostOf.PerAuthBaseState; - static virtual long GetCodeDepositStateCost(in TSelf gas, int byteCodeLength) => GasCostOf.CodeDepositState * byteCodeLength; - static virtual long GetStorageSetReversalRefund(in TSelf gas) => RefundOf.SSetReversedEip8037; + static virtual ulong GetStorageSetStateCost(in TSelf gas) => GasCostOf.SSetState; + static virtual ulong GetCreateStateCost(in TSelf gas) => GasCostOf.CreateState; + static virtual ulong GetNewAccountStateCost(in TSelf gas) => GasCostOf.NewAccountState; + static virtual ulong GetPerAuthBaseStateCost(in TSelf gas) => GasCostOf.PerAuthBaseState; + static virtual ulong GetCodeDepositStateCost(in TSelf gas, int byteCodeLength) => GasCostOf.CodeDepositState * (ulong)byteCodeLength; + static virtual ulong GetStorageSetReversalRefund(in TSelf gas) => RefundOf.SSetReversedEip8037; // EIP-8037 state-accounting accessors. Pre-EIP-8037 policies return 0. - static virtual long GetStateReservoir(in TSelf gas) => 0; - static virtual long GetStateGasUsed(in TSelf gas) => 0; - static virtual long GetStateGasSpill(in TSelf gas) => 0; + static virtual ulong GetStateReservoir(in TSelf gas) => 0; + static virtual ulong GetStateGasUsed(in TSelf gas) => 0; + static virtual ulong GetStateGasSpill(in TSelf gas) => 0; // Tx-wide cumulative spill paid via gas_left in reverted child frames; never undone. // Used by top-level halt to reattribute burned spill from state to regular dimension. - static virtual long GetStateGasSpillBurned(in TSelf gas) => 0; + static virtual ulong GetStateGasSpillBurned(in TSelf gas) => 0; // Spill from reverted children that remains in block regular after in-frame state refund. - static virtual long GetStateGasSpillReclassified(in TSelf gas) => 0; + static virtual ulong GetStateGasSpillReclassified(in TSelf gas) => 0; // Spill whose state side was refunded but regular side stays spent; excluded from // Calculate8037BlockRegularGas subtraction. - static virtual long GetStateGasSpillRefunded(in TSelf gas) => 0; + static virtual ulong GetStateGasSpillRefunded(in TSelf gas) => 0; - static abstract void Consume(ref TSelf gas, long cost); + static abstract void Consume(ref TSelf gas, ulong cost); static abstract bool ConsumeSelfDestructGas(ref TSelf gas); - static abstract void ConsumeCodeDeposit(ref TSelf gas, long cost); + static abstract void ConsumeCodeDeposit(ref TSelf gas, ulong cost); static abstract void Refund(ref TSelf gas, in TSelf childGas); // Revert path: restore the child's state gas into the parent reservoir. @@ -88,45 +88,45 @@ static virtual bool UpdateMemoryCost(ref TSelf gas, in UInt256 position, ulong l return TSelf.UpdateMemoryCost(ref gas, in position, in uint256Length, vmState); } - static abstract bool UpdateGas(ref TSelf gas, long gasCost); + static abstract bool UpdateGas(ref TSelf gas, ulong gasCost); // Pre-EIP-8037 fallback: state gas folded into regular gas. - static virtual bool ConsumeStateGas(ref TSelf gas, long stateGasCost) => TSelf.UpdateGas(ref gas, stateGasCost); + static virtual bool ConsumeStateGas(ref TSelf gas, ulong stateGasCost) => TSelf.UpdateGas(ref gas, stateGasCost); // Regular gas charged first to prevent state-gas spill-then-halt from inflating // the reservoir via the error refund path. - static abstract bool TryConsumeStateAndRegularGas(ref TSelf gas, long stateGasCost, long regularGasCost); + static abstract bool TryConsumeStateAndRegularGas(ref TSelf gas, ulong stateGasCost, ulong regularGasCost); - static abstract void UpdateGasUp(ref TSelf gas, long refund); + static abstract void UpdateGasUp(ref TSelf gas, ulong refund); static abstract bool ConsumeStorageWrite(ref TSelf gas, IReleaseSpec spec) where TEip8037 : struct, IFlag where TIsSlotCreation : struct, IFlag; // Pre-EIP-8037 fallback: refund into regular gas. - static virtual void RefundStateGas(ref TSelf gas, long amount, long stateGasFloor) => TSelf.UpdateGasUp(ref gas, amount); - static virtual void RefundStateGas(ref TSelf gas, long amount, long stateGasFloor, bool trackSpillRefund) => + static virtual void RefundStateGas(ref TSelf gas, ulong amount, ulong stateGasFloor) => TSelf.UpdateGasUp(ref gas, amount); + static virtual void RefundStateGas(ref TSelf gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) => TSelf.RefundStateGas(ref gas, amount, stateGasFloor); // Drop state-gas from block-state accounting without refunding to the gas budget; // reverted state charges stay paid by the tx but don't contribute to committed state gas. - static virtual long DiscardStateGas(ref TSelf gas, long amount, long stateGasFloor, bool trackSpillRefund) => amount; + static virtual ulong DiscardStateGas(ref TSelf gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) => amount; - static virtual void AddStateGasRefundToReservoir(ref TSelf gas, long amount, bool trackSpillRefund) => + static virtual void AddStateGasRefundToReservoir(ref TSelf gas, ulong amount, bool trackSpillRefund) => TSelf.UpdateGasUp(ref gas, amount); - static virtual void RemoveStateGasRefundFromReservoir(ref TSelf gas, long amount) { } + static virtual void RemoveStateGasRefundFromReservoir(ref TSelf gas, ulong amount) { } // EIP-8037 top-level halt: snap state-gas back to (R0, intrinsicStateUsed, 0); the // post-reset StateGasUsed feeds SpentGas so the user doesn't pay for uncommitted state. - static virtual void ResetForHalt(ref TSelf gas, long initialStateReservoir, long initialStateGasUsed) { } + static virtual void ResetForHalt(ref TSelf gas, ulong initialStateReservoir, ulong initialStateGasUsed) { } // EIP-7702 code-insert refund regular-gas portion. Pre-EIP-8037: (NewAccount - PerAuthBaseCost) each. - static virtual long GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => - codeInsertRefunds > 0 ? (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * codeInsertRefunds : 0; + static virtual ulong GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => + codeInsertRefunds > 0 ? (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * (ulong)codeInsertRefunds : 0; // EIP-8037: replenishes tx state reservoir before exec (intrinsic state gas already charged). - static virtual long ApplyCodeInsertRefunds(ref TSelf gas, int codeInsertRefunds, IReleaseSpec spec, long stateGasFloor) => + static virtual ulong ApplyCodeInsertRefunds(ref TSelf gas, int codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) => TSelf.GetCodeInsertRegularRefund(codeInsertRefunds, spec); static abstract bool ConsumeCallValueTransfer(ref TSelf gas); @@ -136,32 +136,32 @@ static virtual long ApplyCodeInsertRefunds(ref TSelf gas, int codeInsertRefunds, static virtual IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec) => TSelf.CalculateIntrinsicGas(tx, spec, blockGasLimit: 0); - static abstract IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, long blockGasLimit); + static abstract IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, ulong blockGasLimit); - static abstract TSelf CreateAvailableFromIntrinsic(long gasLimit, in TSelf intrinsicGas, IReleaseSpec spec); + static abstract TSelf CreateAvailableFromIntrinsic(ulong gasLimit, in TSelf intrinsicGas, IReleaseSpec spec); - static virtual TSelf CreateChildFrameGas(ref TSelf parentGas, long childRegularGas) => TSelf.FromLong(childRegularGas); + static virtual TSelf CreateChildFrameGas(ref TSelf parentGas, ulong childRegularGas) => TSelf.FromULong(childRegularGas); // EXTCODECOPY may need different categorization (state trie access) for some policies. - static abstract void ConsumeDataCopyGas(ref TSelf gas, bool isExternalCode, long baseCost, long dataCost); + static abstract void ConsumeDataCopyGas(ref TSelf gas, bool isExternalCode, ulong baseCost, ulong dataCost); static abstract void OnBeforeInstructionTrace(in TSelf gas, int pc, Instruction instruction, int depth); static abstract void OnAfterInstructionTrace(in TSelf gas); - protected static long CalculateTokensInCallData(Transaction transaction, IReleaseSpec spec) + protected static ulong CalculateTokensInCallData(Transaction transaction, IReleaseSpec spec) { ReadOnlySpan data = transaction.Data.Span; int totalZeros = data.CountZeros(); - return totalZeros + (data.Length - totalZeros) * spec.GasCosts.TxDataNonZeroMultiplier; + return (ulong)(totalZeros + (data.Length - totalZeros)) * spec.GasCosts.TxDataNonZeroMultiplier; } // 0 when floor pricing is not active. - public static long CalculateFloorTokensInAccessList(Transaction transaction, IReleaseSpec spec) => + public static ulong CalculateFloorTokensInAccessList(Transaction transaction, IReleaseSpec spec) => spec.IsEip7981Enabled && transaction.AccessList is { Count: (int addressesCount, int storageKeysCount) } - ? (addressesCount * Address.Size + storageKeysCount * AccessList.StorageKeySize) * spec.GasCosts.TxDataNonZeroMultiplier - : 0L; + ? (ulong)(addressesCount * Address.Size + storageKeysCount * AccessList.StorageKeySize) * spec.GasCosts.TxDataNonZeroMultiplier + : 0; - public static long AccessListCost(Transaction transaction, IReleaseSpec spec, long floorTokensInAccessList) + public static ulong AccessListCost(Transaction transaction, IReleaseSpec spec, ulong floorTokensInAccessList) { AccessList? accessList = transaction.AccessList; if (accessList is null) return 0; @@ -172,8 +172,8 @@ public static long AccessListCost(Transaction transaction, IReleaseSpec spec, lo } (int addressesCount, int storageKeysCount) = accessList.Count; - return addressesCount * GasCostOf.AccessAccountListEntry - + storageKeysCount * GasCostOf.AccessStorageListEntry + return (ulong)addressesCount * GasCostOf.AccessAccountListEntry + + (ulong)storageKeysCount * GasCostOf.AccessStorageListEntry + spec.GasCosts.TotalCostFloorPerToken * floorTokensInAccessList; [DoesNotReturn, StackTraceHidden] @@ -181,7 +181,7 @@ static void ThrowInvalidDataException(IReleaseSpec spec) => throw new InvalidDataException($"Transaction with an access list received within the context of {spec.Name}. EIP-2930 is not enabled."); } - public static (long RegularCost, long StateCost) AuthorizationListCost(Transaction transaction, IReleaseSpec spec) + public static (ulong RegularCost, ulong StateCost) AuthorizationListCost(Transaction transaction, IReleaseSpec spec) { AuthorizationTuple[]? authList = transaction.AuthorizationList; if (authList is null) @@ -194,7 +194,7 @@ public static (long RegularCost, long StateCost) AuthorizationListCost(Transacti ThrowAuthorizationListNotEnabled(spec); } - long authCount = authList.Length; + ulong authCount = (ulong)authList.Length; return spec.IsEip8037Enabled ? ( authCount * GasCostOf.PerAuthBaseRegular, @@ -207,14 +207,14 @@ static void ThrowAuthorizationListNotEnabled(IReleaseSpec releaseSpec) => throw new InvalidDataException($"Transaction with an authorization list received within the context of {releaseSpec.Name}. EIP-7702 is not enabled."); } - private static long CalculateFloorTokensInCallData(Transaction transaction, IReleaseSpec spec) => - transaction.Data.Length * spec.GasCosts.TxDataNonZeroMultiplier; + private static ulong CalculateFloorTokensInCallData(Transaction transaction, IReleaseSpec spec) => + (ulong)transaction.Data.Length * spec.GasCosts.TxDataNonZeroMultiplier; - protected static long CalculateFloorCost(Transaction transaction, IReleaseSpec spec, long tokensInCallData, long floorTokensInAccessList) => spec switch + protected static ulong CalculateFloorCost(Transaction transaction, IReleaseSpec spec, ulong tokensInCallData, ulong floorTokensInAccessList) => spec switch { { IsEip7976Enabled: true } => GasCostOf.Transaction + (CalculateFloorTokensInCallData(transaction, spec) + floorTokensInAccessList) * spec.GasCosts.TotalCostFloorPerToken, { IsEip7623Enabled: true } => GasCostOf.Transaction + tokensInCallData * spec.GasCosts.TotalCostFloorPerToken, - _ => 0L + _ => 0 }; } @@ -227,7 +227,7 @@ public readonly record struct IntrinsicGas(TGasPolicy Standard, TGas /// /// EIP-8037: rejects a transaction whose intrinsic regular or floor gas exceeds . /// - public bool ExceedsCap(long cap, out long regular, out long floor) + public bool ExceedsCap(ulong cap, out ulong regular, out ulong floor) { TGasPolicy standard = Standard; TGasPolicy floorGas = FloorGas; diff --git a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs index 800129a5b999..be8345fb8447 100644 --- a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs @@ -11,7 +11,7 @@ namespace Nethermind.Evm { public interface IBlockhashProvider { - Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec); + Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec); Task Prefetch(BlockHeader currentBlock, CancellationToken token); } } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmCalculations.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmCalculations.cs index c4010c42dff1..011fc9b89ff2 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmCalculations.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmCalculations.cs @@ -14,7 +14,7 @@ namespace Nethermind.Evm; public static class EvmCalculations { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Div32Ceiling(in UInt256 length, out bool outOfGas) + public static ulong Div32Ceiling(in UInt256 length, out bool outOfGas) { if (!length.IsUint64) { @@ -26,7 +26,7 @@ public static long Div32Ceiling(in UInt256 length, out bool outOfGas) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Div32Ceiling(ulong result, out bool outOfGas) + public static ulong Div32Ceiling(ulong result, out bool outOfGas) { ulong rem = result & 31; result >>= 5; @@ -42,24 +42,45 @@ public static long Div32Ceiling(ulong result, out bool outOfGas) } outOfGas = false; - return (long)result; + return result; } - public static long Div32Ceiling(in UInt256 length) + [DoesNotReturn, StackTraceHidden] + private static void ThrowOutOfGasException() { - long result = Div32Ceiling(in length, out bool outOfGas); + Metrics.EvmExceptions++; + throw new OutOfGasException(); + } + + public static ulong Div32Ceiling(long length) + { + if (length < 0) + { + ThrowOutOfGasException(); + } + + return Div32Ceiling((ulong)length); + } + + public static ulong Div32Ceiling(ulong length) + { + ulong result = Div32Ceiling(length, out bool outOfGas); if (outOfGas) { ThrowOutOfGasException(); } return result; + } - [DoesNotReturn, StackTraceHidden] - static void ThrowOutOfGasException() + public static ulong Div32Ceiling(in UInt256 length) + { + ulong result = Div32Ceiling(in length, out bool outOfGas); + if (outOfGas) { - Metrics.EvmExceptions++; - throw new OutOfGasException(); + ThrowOutOfGasException(); } + + return result; } } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs index dd86d76813a6..8ca97385722e 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs @@ -20,7 +20,7 @@ public interface IOpBitwise /// /// The gas cost for executing the bitwise operation. /// - static virtual long GasCost => GasCostOf.VeryLow; + static virtual ulong GasCost => GasCostOf.VeryLow; /// /// Executes the bitwise operation. /// @@ -47,7 +47,7 @@ public static EvmExceptionType InstructionBitwise(Virtua where TOpBitwise : struct, IOpBitwise { // Deduct the operation's gas cost. - TGasPolicy.Consume(ref gas, TOpBitwise.GasCost); + TGasPolicy.Consume(ref gas, (ulong)TOpBitwise.GasCost); // Pop the first operand from the stack by reference to minimize copying. ref byte bytesRef = ref stack.PopBytesByRef(); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs index aeda45279178..d861d3d69d85 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Diagnostics; using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; @@ -115,6 +114,7 @@ public static EvmExceptionType InstructionCall !state.AccountExists(target), - true => transferValue != 0 && state.IsDeadAccount(target), + true => !transferValue.IsZero && state.IsDeadAccount(target), }; bool newAccountOutOfGas = chargesNewAccount && !TGasPolicy.ConsumeNewAccountCreation(ref gas); @@ -203,22 +203,21 @@ public static EvmExceptionType InstructionCall= 0, "GetRemainingGas must be non-negative; (ulong)cap below would otherwise wrap."); - long cap = gasAvailable - gasAvailable / 64; - gasLimitUl = gasLimit.IsUint64 && gasLimit.u0 <= (ulong)cap - ? (long)gasLimit.u0 + // EIP-150: cap fits in ulong, so min(gasLimit, cap) fits without 256-bit math. + ulong cap = gasAvailable - gasAvailable / 64; + gasLimitUl = gasLimit.IsUint64 && gasLimit.u0 <= cap + ? gasLimit.u0 : cap; } else { - if (!gasLimit.IsUint64 || gasLimit.u0 >= long.MaxValue) goto OutOfGas; - gasLimitUl = (long)gasLimit.u0; + if (!gasLimit.IsUint64) goto OutOfGas; + gasLimitUl = gasLimit.u0; } if (!TGasPolicy.UpdateGas(ref gas, gasLimitUl)) goto OutOfGas; @@ -265,7 +264,7 @@ public static EvmExceptionType InstructionCall( if (!stack.PopUInt256(out UInt256 a, out UInt256 b, out UInt256 result)) goto StackUnderflow; - TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: false, GasCostOf.VeryLow, GasCostOf.Memory * EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); + TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: false, GasCostOf.VeryLow, GasCostOf.Memory * (ulong)EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); if (outOfGas) goto OutOfGas; if (!result.IsZero) @@ -164,7 +164,7 @@ public static EvmExceptionType InstructionExtCodeCopy( goto StackUnderflow; // Deduct gas cost: cost for external code access plus memory expansion cost. - TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: true, spec.GasCosts.ExtCodeCost, GasCostOf.Memory * EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); + TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: true, spec.GasCosts.ExtCodeCost, GasCostOf.Memory * (ulong)EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); if (outOfGas) goto OutOfGas; // Charge gas for account access (considering hot/cold storage costs). @@ -235,7 +235,7 @@ public static EvmExceptionType InstructionExtCodeSize( { IReleaseSpec spec = vm.Spec; // Deduct the gas cost for external code access. - TGasPolicy.Consume(ref gas, spec.GasCosts.ExtCodeCost); + TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.ExtCodeCost); // Pop the account address from the stack. Address address = stack.PopAddress(); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Create.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Create.cs index 56e2c79c924b..5acb9410646b 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Create.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Create.cs @@ -115,14 +115,14 @@ public static EvmExceptionType InstructionCreate= maxNonce) + ulong accountNonce = state.GetNonce(env.ExecutingAccount); + if (accountNonce >= ulong.MaxValue) { RefundCreateStateGas(ref gas); vm.ReturnDataBuffer = Array.Empty(); @@ -165,7 +164,7 @@ public static EvmExceptionType InstructionCreate(Vi goto StackUnderflow; // Deduct gas: base cost plus additional cost per 32-byte word. - TGasPolicy.Consume(ref gas, GasCostOf.Sha3 + GasCostOf.Sha3Word * EvmCalculations.Div32Ceiling(in b, out bool outOfGas)); + TGasPolicy.Consume(ref gas, (ulong)(GasCostOf.Sha3 + GasCostOf.Sha3Word * (ulong)EvmCalculations.Div32Ceiling(in b, out bool outOfGas))); if (outOfGas) goto OutOfGas; VmState vmState = vm.VmState; diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs index 11c3a7cdee74..f3c1c2113860 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs @@ -26,7 +26,7 @@ public interface IOpBlkAddress /// /// The gas cost for the operation. /// - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as address. /// @@ -45,7 +45,7 @@ public interface IOpEnv32Bytes /// /// The gas cost for the operation. /// - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as ref to big endian word. /// @@ -64,7 +64,7 @@ public interface IOpEnvAddress /// /// The gas cost for the operation. /// - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as address. /// @@ -79,7 +79,7 @@ public interface IOpEnvAddress public interface IOpEnvUInt256 where TGasPolicy : struct, IGasPolicy { - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as a UInt256. /// @@ -95,7 +95,7 @@ public interface IOpEnvUInt256 public interface IOpBlkUInt256 where TGasPolicy : struct, IGasPolicy { - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as a UInt256. /// @@ -111,7 +111,7 @@ public interface IOpBlkUInt256 public interface IOpEnvUInt32 where TGasPolicy : struct, IGasPolicy { - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as a UInt32. /// @@ -126,7 +126,7 @@ public interface IOpEnvUInt32 public interface IOpEnvUInt64 where TGasPolicy : struct, IGasPolicy { - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as a UInt64. /// @@ -141,7 +141,7 @@ public interface IOpEnvUInt64 public interface IOpBlkUInt64 where TGasPolicy : struct, IGasPolicy { - virtual static long GasCost => GasCostOf.Base; + virtual static ulong GasCost => GasCostOf.Base; /// /// Executes the operation and returns the result as a UInt64. /// @@ -545,7 +545,7 @@ public static EvmExceptionType InstructionBalance(Virt { IReleaseSpec spec = vm.Spec; // Deduct gas cost for balance operation as per specification. - TGasPolicy.Consume(ref gas, spec.GasCosts.BalanceCost); + TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.BalanceCost); Address address = stack.PopAddress(); if (address is null) goto StackUnderflow; @@ -605,7 +605,7 @@ public static EvmExceptionType InstructionExtCodeHash( where TTracingInst : struct, IFlag { IReleaseSpec spec = vm.Spec; - TGasPolicy.Consume(ref gas, spec.GasCosts.ExtCodeHashCost); + TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.ExtCodeHashCost); Address address = stack.PopAddress(); if (address is null) goto StackUnderflow; @@ -743,14 +743,11 @@ public static EvmExceptionType InstructionBlockHash(Vi // Pop the block number from the stack. if (!stack.PopUInt256(out UInt256 a)) goto StackUnderflow; - // Convert the block number to a long. Clamp the value to long.MaxValue if it exceeds it. - long number = a > long.MaxValue ? long.MaxValue : (long)a.u0; - // Retrieve the block hash for the given block number. BlockHeader header = vm.BlockExecutionContext.Header; - Hash256? blockHash = number >= header.Number ? - null : // Current block or higher is null, don't bother looking up - vm.BlockHashProvider.GetBlockhash(header, number, vm.Spec); + Hash256? blockHash = !a.IsUint64 || a.u0 > long.MaxValue || a.u0 >= header.Number + ? null // Current block, future block, or unrepresentable block number + : vm.BlockHashProvider.GetBlockhash(header, a.u0, vm.Spec); // Push the block hash bytes if available; otherwise, push a 32-byte zero value. EvmExceptionType pushResult = stack.PushBytes(blockHash is not null ? blockHash.Bytes : BytesZero32); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math1Param.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math1Param.cs index 7ba335e94fd6..e3ec822ef1e8 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math1Param.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math1Param.cs @@ -25,7 +25,7 @@ public interface IOpMath1Param /// /// The gas cost for executing the operation. /// - virtual static long GasCost => GasCostOf.VeryLow; + virtual static ulong GasCost => GasCostOf.VeryLow; /// /// Executes the operation on the provided 256‐bit operand. @@ -100,7 +100,7 @@ public struct OpIsZero : IOpMath1Param /// public struct OpCLZ : IOpMath1Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static EvmWord Operation(EvmWord value) => value == default ? Vector256.Create((byte)0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs index c13c8fd2669e..fa2b989df588 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs @@ -23,7 +23,7 @@ public interface IOpMath2Param /// /// The gas cost for executing this math operation. /// - virtual static long GasCost => GasCostOf.VeryLow; + virtual static ulong GasCost => GasCostOf.VeryLow; /// /// Executes the math operation on two 256-bit operands. /// @@ -97,7 +97,7 @@ public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) /// public struct OpMul : IOpMath2Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) => UInt256.Multiply(in a, in b, out result); } @@ -108,7 +108,7 @@ public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) /// public struct OpDiv : IOpMath2Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) { if (b.IsZero) @@ -132,7 +132,7 @@ public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) /// public struct OpSDiv : IOpMath2Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) { if (b.IsZero) @@ -163,7 +163,7 @@ in As(ref AsRef(in b)), /// public struct OpMod : IOpMath2Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) { if (b.IsZeroOrOne) @@ -185,7 +185,7 @@ public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) /// public struct OpSMod : IOpMath2Param { - public static long GasCost => GasCostOf.Low; + public static ulong GasCost => GasCostOf.Low; public static void Operation(in UInt256 a, in UInt256 b, out UInt256 result) { if (b.IsZeroOrOne) @@ -283,7 +283,7 @@ public static EvmExceptionType InstructionExp(VirtualM int expSize = 32 - leadingZeros; // Deduct gas proportional to the number of 32-byte words needed to represent the exponent. - TGasPolicy.Consume(ref gas, vm.Spec.GasCosts.ExpByteCost * expSize); + TGasPolicy.Consume(ref gas, vm.Spec.GasCosts.ExpByteCost * (ulong)expSize); if (a.IsZero) { diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math3Param.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math3Param.cs index 451e536bb60a..904fdedb1a76 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math3Param.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math3Param.cs @@ -14,7 +14,7 @@ public static partial class EvmInstructions { public interface IOpMath3Param { - virtual static long GasCost => GasCostOf.Mid; + virtual static ulong GasCost => GasCostOf.Mid; abstract static void Operation(in UInt256 a, in UInt256 b, in UInt256 c, out UInt256 result); } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Shifts.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Shifts.cs index b224e8bdbf1a..02df8b0dd20f 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Shifts.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Shifts.cs @@ -22,7 +22,7 @@ public interface IOpShift /// /// The gas cost for executing a shift operation. /// - virtual static long GasCost => GasCostOf.VeryLow; + virtual static ulong GasCost => GasCostOf.VeryLow; /// /// Performs the shift operation. diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index 6e6eb797b159..43d609389941 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -297,7 +297,7 @@ public static EvmExceptionType InstructionMCopy(Virtua if (!stack.PopUInt256(out UInt256 a, out UInt256 b, out UInt256 c)) goto StackUnderflow; // Calculate additional gas cost based on the length (using a division rounding-up method) and deduct the total cost. - TGasPolicy.Consume(ref gas, GasCostOf.VeryLow + GasCostOf.VeryLow * EvmCalculations.Div32Ceiling(c, out bool outOfGas)); + TGasPolicy.Consume(ref gas, GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)(EvmCalculations.Div32Ceiling(c, out bool outOfGas))); if (outOfGas) goto OutOfGas; if (c.IsZero) @@ -365,7 +365,7 @@ internal static EvmExceptionType InstructionSStoreUnmetered /// Non-generic intrinsic gas result for backward compatibility. /// -public readonly record struct EthereumIntrinsicGas(long Standard, long FloorGas) +public readonly record struct EthereumIntrinsicGas(ulong Standard, ulong FloorGas) { - public long MinimalGas { get; } = Math.Max(Standard, FloorGas); - public static explicit operator long(EthereumIntrinsicGas gas) => gas.MinimalGas; + public ulong MinimalGas { get; } = Math.Max(Standard, FloorGas); + public static explicit operator ulong(EthereumIntrinsicGas gas) => gas.MinimalGas; public static implicit operator EthereumIntrinsicGas(IntrinsicGas gas) => new(gas.Standard.Value + gas.Standard.StateReservoir, gas.FloorGas.Value); } @@ -24,17 +24,17 @@ public static class IntrinsicGasCalculator /// /// Calculates intrinsic gas with TGasPolicy type, allowing MultiGas breakdown for Arbitrum. /// - private static IntrinsicGas Calculate(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit = 0) + private static IntrinsicGas Calculate(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit = 0) where TGasPolicy : struct, IGasPolicy => TGasPolicy.CalculateIntrinsicGas(transaction, releaseSpec, blockGasLimit); /// /// Non-generic backward-compatible Calculate method. /// - public static EthereumIntrinsicGas Calculate(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit = 0) => + public static EthereumIntrinsicGas Calculate(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit = 0) => Calculate(transaction, releaseSpec, blockGasLimit); - public static long AccessListCost(Transaction transaction, IReleaseSpec releaseSpec) => + public static ulong AccessListCost(Transaction transaction, IReleaseSpec releaseSpec) => IGasPolicy.AccessListCost(transaction, releaseSpec, IGasPolicy.CalculateFloorTokensInAccessList(transaction, releaseSpec)); } diff --git a/src/Nethermind/Nethermind.Evm/RefundHelper.cs b/src/Nethermind/Nethermind.Evm/RefundHelper.cs index ee4d7c7294f3..e8618e4d6d04 100644 --- a/src/Nethermind/Nethermind.Evm/RefundHelper.cs +++ b/src/Nethermind/Nethermind.Evm/RefundHelper.cs @@ -9,13 +9,13 @@ namespace Nethermind.Evm { public static class RefundHelper { - public const long MaxRefundQuotient = 2L; + public const ulong MaxRefundQuotient = 2L; - public const long MaxRefundQuotientEIP3529 = 5L; + public const ulong MaxRefundQuotientEIP3529 = 5L; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CalculateClaimableRefund(long spentGas, long totalRefund, IReleaseSpec spec) + public static ulong CalculateClaimableRefund(ulong spentGas, ulong totalRefund, IReleaseSpec spec) { - long maxRefundQuotient = spec.IsEip3529Enabled ? MaxRefundQuotientEIP3529 : MaxRefundQuotient; + ulong maxRefundQuotient = (ulong)(spec.IsEip3529Enabled ? MaxRefundQuotientEIP3529 : MaxRefundQuotient); return Math.Min(spentGas / maxRefundQuotient, totalRefund); } } diff --git a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs index dab82328228b..f1e8f8ca915c 100644 --- a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs @@ -17,9 +17,9 @@ public int MaxProductionBlobCount(int? blockProductionBlobLimit) => ? Math.Min(blockProductionBlobLimit.Value, (int)spec.MaxBlobCount) : (int)spec.MaxBlobCount; - public long GetBaseDataCost(Transaction tx) => + public ulong GetBaseDataCost(Transaction tx) => tx.IsContractCreation && spec.IsEip3860Enabled - ? EvmCalculations.Div32Ceiling((UInt256)tx.Data.Length) * GasCostOf.InitCodeWord + ? (ulong)EvmCalculations.Div32Ceiling((UInt256)tx.Data.Length) * GasCostOf.InitCodeWord : 0; } } diff --git a/src/Nethermind/Nethermind.Evm/State/IWorldState.cs b/src/Nethermind/Nethermind.Evm/State/IWorldState.cs index 3a8362843d8e..e73720054a40 100644 --- a/src/Nethermind/Nethermind.Evm/State/IWorldState.cs +++ b/src/Nethermind/Nethermind.Evm/State/IWorldState.cs @@ -97,8 +97,8 @@ public interface IWorldState : IJournal, IReadOnlyStateProvider void DeleteAccount(Address address); - void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default); - void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default); + void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default); + void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default); // used by Arbitrum void CreateEmptyAccountIfDeleted(Address address); @@ -121,13 +121,13 @@ public interface IWorldState : IJournal, IReadOnlyStateProvider void SubtractFromBalance(Address address, in UInt256 balanceChange, IReleaseSpec spec, out UInt256 oldBalance); - void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce); + void IncrementNonce(Address address, ulong delta, out ulong oldNonce); - void DecrementNonce(Address address, UInt256 delta); + void DecrementNonce(Address address, ulong delta); - void DecrementNonce(Address address) => DecrementNonce(address, UInt256.One); + void DecrementNonce(Address address) => DecrementNonce(address, 1); - void SetNonce(Address address, in UInt256 nonce); + void SetNonce(Address address, in ulong nonce); /* snapshots */ void Commit(IReleaseSpec releaseSpec, IWorldStateTracer tracer, bool isGenesis = false, bool commitRoots = true); @@ -136,7 +136,7 @@ public interface IWorldState : IJournal, IReadOnlyStateProvider /// Persist the underlying changes to the storage at the specified block number. This also recalculate state root. /// /// - void CommitTree(long blockNumber); + void CommitTree(ulong blockNumber); ArrayPoolList? GetAccountChanges(); @@ -151,6 +151,6 @@ bool IsNonZeroAccount(Address address, out bool accountExists) { accountExists = AccountExists(address); return accountExists - && (IsContract(address) || !GetNonce(address).IsZero || !IsStorageEmpty(address)); + && (IsContract(address) || !(GetNonce(address) == 0) || !IsStorageEmpty(address)); } } diff --git a/src/Nethermind/Nethermind.Evm/State/IWorldStateScopeProvider.cs b/src/Nethermind/Nethermind.Evm/State/IWorldStateScopeProvider.cs index b98580de1df8..593b8e5822e5 100644 --- a/src/Nethermind/Nethermind.Evm/State/IWorldStateScopeProvider.cs +++ b/src/Nethermind/Nethermind.Evm/State/IWorldStateScopeProvider.cs @@ -65,7 +65,7 @@ public interface IScope : IDisposable /// That said, will always call /// first. /// - void Commit(long blockNumber); + void Commit(ulong blockNumber); } public interface ICodeDb diff --git a/src/Nethermind/Nethermind.Evm/State/WorldStateExtensions.cs b/src/Nethermind/Nethermind.Evm/State/WorldStateExtensions.cs index 712a21401bfa..6b30ecfddb5b 100644 --- a/src/Nethermind/Nethermind.Evm/State/WorldStateExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/State/WorldStateExtensions.cs @@ -31,9 +31,9 @@ public static bool AddToBalanceAndCreateIfNotExists(this IWorldState worldState, public static void SubtractFromBalance(this IWorldState worldState, Address address, in UInt256 balanceChange, IReleaseSpec spec) => worldState.SubtractFromBalance(address, balanceChange, spec, out _); - public static void IncrementNonce(this IWorldState worldState, Address address, UInt256 delta) + public static void IncrementNonce(this IWorldState worldState, Address address, ulong delta) => worldState.IncrementNonce(address, delta, out _); public static void IncrementNonce(this IWorldState worldState, Address address) - => worldState.IncrementNonce(address, UInt256.One, out _); + => worldState.IncrementNonce(address, 1, out _); } diff --git a/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs index 3c43c2e0f3f2..2bc66e1b9954 100644 --- a/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs @@ -33,7 +33,7 @@ public static void ApplyStateOverridesNoCommit( if (!state.TryGetAccount(address, out AccountStruct account)) { - state.CreateAccount(address, accountOverride.Balance ?? UInt256.Zero, accountOverride.Nonce ?? UInt256.Zero); + state.CreateAccount(address, accountOverride.Balance ?? UInt256.Zero, accountOverride.Nonce ?? 0); } else { @@ -52,7 +52,7 @@ public static void ApplyStateOverrides( IOverridableCodeInfoRepository overridableCodeInfoRepository, Dictionary? overrides, IReleaseSpec spec, - long blockNumber) + ulong blockNumber) { state.ApplyStateOverridesNoCommit(overridableCodeInfoRepository, overrides, spec); @@ -121,8 +121,8 @@ private static void UpdateNonce( { if (accountOverride.Nonce is not null) { - UInt256 nonce = account.Nonce; - UInt256 newNonce = accountOverride.Nonce.Value; + ulong nonce = account.Nonce; + ulong newNonce = accountOverride.Nonce.Value; if (nonce > newNonce) { stateProvider.DecrementNonce(address, nonce - newNonce); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index 35690c1537a8..0f8973b0cc1c 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -190,7 +190,7 @@ public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] outp } } - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingInstructions) @@ -208,7 +208,7 @@ public void ReportOperationError(EvmExceptionType error) } } - public void ReportOperationRemainingGas(long gas) + public void ReportOperationRemainingGas(ulong gas) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingInstructions) @@ -361,7 +361,7 @@ public void ReportSelfDestruct(Address address, UInt256 balance, Address refundA } } - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingActions) @@ -370,7 +370,7 @@ public void ReportAction(long gas, UInt256 value, Address from, Address to, Read } } - public void ReportActionEnd(long gas, ReadOnlyMemory output) + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingActions) @@ -388,7 +388,7 @@ public void ReportActionError(EvmExceptionType evmExceptionType) } } - public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) + public void ReportActionRevert(ulong gasLeft, ReadOnlyMemory output) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingActions) @@ -397,7 +397,7 @@ public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) } } - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingActions) @@ -424,7 +424,7 @@ public void ReportByteCode(ReadOnlyMemory byteCode) } } - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingInstructions) @@ -442,7 +442,7 @@ public void ReportRefund(long refund) } } - public void ReportExtraGasPressure(long extraGasPressure) + public void ReportExtraGasPressure(ulong extraGasPressure) { token.ThrowIfCancellationRequested(); if (innerTracer.IsTracingRefunds) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs index c59c0cc9b25b..2b013c2fd7ee 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs @@ -152,7 +152,7 @@ public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] outp } } - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { for (int index = 0; index < _txTracers.Count; index++) { @@ -176,7 +176,7 @@ public void ReportOperationError(EvmExceptionType error) } } - public void ReportOperationRemainingGas(long gas) + public void ReportOperationRemainingGas(ulong gas) { for (int index = 0; index < _txTracers.Count; index++) { @@ -380,7 +380,7 @@ public void ReportSelfDestruct(Address address, UInt256 balance, Address refundA } } - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { for (int index = 0; index < _txTracers.Count; index++) { @@ -392,7 +392,7 @@ public void ReportAction(long gas, UInt256 value, Address from, Address to, Read } } - public void ReportActionEnd(long gas, ReadOnlyMemory output) + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) { for (int index = 0; index < _txTracers.Count; index++) { @@ -416,7 +416,7 @@ public void ReportActionError(EvmExceptionType evmExceptionType) } } - public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) + public void ReportActionRevert(ulong gasLeft, ReadOnlyMemory output) { for (int index = 0; index < _txTracers.Count; index++) { @@ -428,7 +428,7 @@ public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) } } - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { for (int index = 0; index < _txTracers.Count; index++) { @@ -464,7 +464,7 @@ public void ReportByteCode(ReadOnlyMemory byteCode) } } - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { for (int index = 0; index < _txTracers.Count; index++) { @@ -488,7 +488,7 @@ public void ReportRefund(long refund) } } - public void ReportExtraGasPressure(long extraGasPressure) + public void ReportExtraGasPressure(ulong extraGasPressure) { for (int index = 0; index < _txTracers.Count; index++) { diff --git a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs index 1e0b91496bd2..e32e1583c8a2 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs @@ -191,13 +191,13 @@ public void MarkAsSuccess(Address recipient, in GasConsumed gasSpent, byte[] out public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] output, string error, Hash256? stateRoot = null) => InnerTracer.MarkAsFailed(recipient, gasSpent, output, error, stateRoot); - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => InnerTracer.StartOperation(pc, opcode, gas, env); public void ReportOperationError(EvmExceptionType error) => InnerTracer.ReportOperationError(error); - public void ReportOperationRemainingGas(long gas) + public void ReportOperationRemainingGas(ulong gas) => InnerTracer.ReportOperationRemainingGas(gas); public void ReportLog(LogEntry log) @@ -233,19 +233,19 @@ public void LoadOperationTransientStorage(Address address, UInt256 storageIndex, public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) => InnerTracer.ReportSelfDestruct(address, balance, refundAddress); - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => InnerTracer.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - public void ReportActionEnd(long gas, ReadOnlyMemory output) + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) => InnerTracer.ReportActionEnd(gas, output); public void ReportActionError(EvmExceptionType evmExceptionType) => InnerTracer.ReportActionError(evmExceptionType); - public void ReportActionRevert(long gas, ReadOnlyMemory output) + public void ReportActionRevert(ulong gas, ReadOnlyMemory output) => InnerTracer.ReportActionRevert(gas, output); - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => InnerTracer.ReportActionEnd(gas, deploymentAddress, deployedCode); public void ReportBlockHash(Hash256 blockHash) @@ -254,13 +254,13 @@ public void ReportBlockHash(Hash256 blockHash) public void ReportByteCode(ReadOnlyMemory byteCode) => InnerTracer.ReportByteCode(byteCode); - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) => InnerTracer.ReportGasUpdateForVmTrace(refund, gasAvailable); public void ReportRefund(long refund) => InnerTracer.ReportRefund(refund); - public void ReportExtraGasPressure(long extraGasPressure) + public void ReportExtraGasPressure(ulong extraGasPressure) => InnerTracer.ReportExtraGasPressure(extraGasPressure); public void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 773933475b1c..f3c4290ca25f 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -180,7 +180,7 @@ public interface ITxTracer : IWorldStateTracer, IDisposable /// /// /// Depends on - void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env); + void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env); /// /// @@ -194,7 +194,7 @@ public interface ITxTracer : IWorldStateTracer, IDisposable /// /// /// Depends on - void ReportOperationRemainingGas(long gas); + void ReportOperationRemainingGas(ulong gas); /// @@ -341,7 +341,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); + void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); /// /// @@ -349,7 +349,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportActionEnd(long gas, ReadOnlyMemory output); + void ReportActionEnd(ulong gas, ReadOnlyMemory output); /// /// @@ -357,7 +357,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportActionRevert(long gasLeft, ReadOnlyMemory output); + void ReportActionRevert(ulong gasLeft, ReadOnlyMemory output); /// /// @@ -373,7 +373,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode); + void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode); /// /// @@ -395,7 +395,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportGasUpdateForVmTrace(long refund, long gasAvailable); + void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable); /// /// @@ -409,7 +409,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportExtraGasPressure(long extraGasPressure); + void ReportExtraGasPressure(ulong extraGasPressure); /// /// Reports access to storage cell diff --git a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs index 54b46bb79663..389d0cf82a96 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs @@ -26,13 +26,13 @@ public override void MarkAsSuccess(Address recipient, in GasConsumed gasSpent, b => ThrowInvalidOperationException(); public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] output, string? error, Hash256? stateRoot = null) => ThrowInvalidOperationException(); - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => ThrowInvalidOperationException(); public override void ReportOperationError(EvmExceptionType error) => ThrowInvalidOperationException(); - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) => ThrowInvalidOperationException(); public override void SetOperationMemorySize(ulong newSize) @@ -80,29 +80,29 @@ public override void ReportStorageChange(in StorageCell storageCell, byte[] befo public override void ReportStorageRead(in StorageCell storageCell) => ThrowInvalidOperationException(); - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => ThrowInvalidOperationException(); - public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) => ThrowInvalidOperationException(); public override void ReportActionError(EvmExceptionType exceptionType) => ThrowInvalidOperationException(); - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => ThrowInvalidOperationException(); public override void ReportBlockHash(Hash256 blockHash) => ThrowInvalidOperationException(); public override void ReportByteCode(ReadOnlyMemory byteCode) => ThrowInvalidOperationException(); - public override void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public override void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) => ThrowInvalidOperationException(); public override void ReportRefund(long refund) => ThrowInvalidOperationException(); - public override void ReportExtraGasPressure(long extraGasPressure) + public override void ReportExtraGasPressure(ulong extraGasPressure) => ThrowInvalidOperationException(); public override void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/TxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/TxTracer.cs index d7b2f5cabb13..90ce1a199c74 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/TxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/TxTracer.cs @@ -54,9 +54,9 @@ public virtual void ReportStorageChange(in StorageCell storageCell, byte[] befor public virtual void ReportStorageRead(in StorageCell storageCell) { } public virtual void MarkAsSuccess(Address recipient, in GasConsumed gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) { } public virtual void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] output, string? error, Hash256? stateRoot = null) { } - public virtual void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) { } + public virtual void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { } public virtual void ReportOperationError(EvmExceptionType error) { } - public virtual void ReportOperationRemainingGas(long gas) { } + public virtual void ReportOperationRemainingGas(ulong gas) { } public virtual void ReportLog(LogEntry log) { } public virtual void SetOperationStack(TraceStack stack) { } public virtual void ReportStackPush(in ReadOnlySpan stackItem) { } @@ -68,16 +68,16 @@ public virtual void LoadOperationStorage(Address address, UInt256 storageIndex, public virtual void SetOperationTransientStorage(Address address, UInt256 storageIndex, ReadOnlySpan newValue, ReadOnlySpan currentValue) { } public virtual void LoadOperationTransientStorage(Address address, UInt256 storageIndex, ReadOnlySpan value) { } public virtual void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) { } - public virtual void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { } - public virtual void ReportActionEnd(long gas, ReadOnlyMemory output) { } + public virtual void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { } + public virtual void ReportActionEnd(ulong gas, ReadOnlyMemory output) { } public virtual void ReportActionError(EvmExceptionType evmExceptionType) { } - public virtual void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { } - public virtual void ReportActionRevert(long gas, ReadOnlyMemory output) => ReportActionError(EvmExceptionType.Revert); + public virtual void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { } + public virtual void ReportActionRevert(ulong gas, ReadOnlyMemory output) => ReportActionError(EvmExceptionType.Revert); public virtual void ReportBlockHash(Hash256 blockHash) { } public virtual void ReportByteCode(ReadOnlyMemory byteCode) { } - public virtual void ReportGasUpdateForVmTrace(long refund, long gasAvailable) { } + public virtual void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { } public virtual void ReportRefund(long refund) { } - public virtual void ReportExtraGasPressure(long extraGasPressure) { } + public virtual void ReportExtraGasPressure(ulong extraGasPressure) { } public virtual void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) { } public virtual void ReportFees(UInt256 fees, UInt256 burntFees) { } public virtual void Dispose() { } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/GasConsumed.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/GasConsumed.cs index 1b8a2b726963..bb46e2407d0a 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/GasConsumed.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/GasConsumed.cs @@ -11,19 +11,19 @@ namespace Nethermind.Evm.TransactionProcessing; /// EIP-7778/EIP-8037 regular gas for block accounting (pre-refund). When 0 without state gas, use SpentGas. /// EIP-8037: State gas for block accounting. Block gasUsed = max(sum_regular, sum_state). /// Maximum gas consumed before refunds; if 0, use SpentGas. -public readonly record struct GasConsumed(long SpentGas, long OperationGas, long BlockGas = 0, long BlockStateGas = 0, long MaxUsedGas = 0) +public readonly record struct GasConsumed(ulong SpentGas, ulong OperationGas, ulong BlockGas = 0, ulong BlockStateGas = 0, ulong MaxUsedGas = 0) { /// /// Gets the effective regular gas for block accounting. When EIP-7778 is enabled, /// this returns BlockGas (pre-refund), otherwise returns SpentGas. EIP-8037 can explicitly report zero regular gas when state gas is nonzero. /// - public long EffectiveBlockGas => BlockGas > 0 || BlockStateGas > 0 ? BlockGas : SpentGas; + public ulong EffectiveBlockGas => BlockGas > 0 || BlockStateGas > 0 ? BlockGas : SpentGas; /// /// Gets gas consumed before refunds (and floor adjusted), used by eth_simulate maxUsedGas. /// - public long EffectiveMaxUsedGas => MaxUsedGas > 0 ? MaxUsedGas : SpentGas; + public ulong EffectiveMaxUsedGas => MaxUsedGas > 0 ? MaxUsedGas : SpentGas; - public static implicit operator long(GasConsumed gas) => gas.SpentGas; - public static implicit operator GasConsumed(long spentGas) => new(spentGas, spentGas, 0, 0, spentGas); + public static implicit operator ulong(GasConsumed gas) => gas.SpentGas; + public static implicit operator GasConsumed(ulong spentGas) => new(spentGas, spentGas, 0, 0, spentGas); } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/SystemTransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/SystemTransactionProcessor.cs index 68aef10f1d97..14b8c32ab2a9 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/SystemTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/SystemTransactionProcessor.cs @@ -42,7 +42,7 @@ protected override TransactionResult Execute(Transaction tx, ITxTracer tracer, E if (_isAura && !VirtualMachine.BlockExecutionContext.IsGenesis) { - WorldState.CreateAccountIfNotExists(Address.SystemUser, UInt256.Zero, UInt256.Zero); + WorldState.CreateAccountIfNotExists(Address.SystemUser, UInt256.Zero, 0); } ExecutionOptions coreOpts = opts & ~ExecutionOptions.Warmup; @@ -63,13 +63,13 @@ protected override TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, I protected override IReleaseSpec GetSpec(BlockHeader header) => base.GetSpec(header).ForSystemTransaction(_isAura, header.IsGenesis); - protected override TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec spec, in TGasPolicy intrinsicGas, long minGasRequired, bool validate) => TransactionResult.Ok; + protected override TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec spec, in TGasPolicy intrinsicGas, ulong minGasRequired, bool validate) => TransactionResult.Ok; protected override TransactionResult IncrementNonce(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts) => TransactionResult.Ok; protected override void DecrementNonce(Transaction tx) { } - protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, long spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) { } + protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) { } protected override void PayValue(Transaction tx, IReleaseSpec spec, ExecutionOptions opts) { @@ -79,7 +79,7 @@ protected override void PayValue(Transaction tx, IReleaseSpec spec, ExecutionOpt } } - protected override IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, long blockGasLimit) + protected override IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, ulong blockGasLimit) { if (tx is not SystemCall) { diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 3d4684b9a0f9..439b35422772 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -81,9 +81,9 @@ public abstract class TransactionProcessorBase : ITransactionProcess private readonly ITransactionProcessor.IBlobBaseFeeCalculator _blobBaseFeeCalculator; private readonly ILogManager _logManager; private readonly bool _parallel; - private long _blockCumulativeReceiptGas; - private long _blockCumulativeRegularGas; - private long _blockCumulativeStateGas; + private ulong _blockCumulativeReceiptGas; + private ulong _blockCumulativeRegularGas; + private ulong _blockCumulativeStateGas; protected TransactionProcessorBase( ITransactionProcessor.IBlobBaseFeeCalculator? blobBaseFeeCalculator, @@ -381,15 +381,15 @@ private TransactionResult Apply8037DelegationRefunds( if (spec.IsEip8037Enabled && (delegationRefunds > 0 || delegationAuthBaseRefunds > 0)) { TGasPolicy intrinsicGasStandard = intrinsicGas.Standard; - long stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); - long newAccountStateCost = TGasPolicy.GetNewAccountStateCost(in gasAvailable); - long perAuthBaseStateCost = TGasPolicy.GetPerAuthBaseStateCost(in gasAvailable); + ulong stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); + ulong newAccountStateCost = TGasPolicy.GetNewAccountStateCost(in gasAvailable); + ulong perAuthBaseStateCost = TGasPolicy.GetPerAuthBaseStateCost(in gasAvailable); bool refundWithinBounds = TryCalculate8037DelegationRefund( newAccountStateCost, perAuthBaseStateCost, delegationRefunds, delegationAuthBaseRefunds, - out long stateGasRefund); + out ulong stateGasRefund); Debug.Assert(refundWithinBounds, "Authorization refunds are bounded before delegation processing."); if (!refundWithinBounds) { @@ -397,7 +397,7 @@ private TransactionResult Apply8037DelegationRefunds( return TransactionResult.ErrorType.MalformedTransaction.WithDetail("authorization refund gas overflow"); } - long refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); + ulong refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); TGasPolicy.RefundStateGas(ref gasAvailable, stateGasRefund, refundFloor, trackSpillRefund: false); delegationRefunds = 0; delegationAuthBaseRefunds = 0; @@ -413,8 +413,8 @@ private TransactionResult Validate8037DelegationRefundBounds(Transaction tx, IRe return TransactionResult.Ok; } - long newAccountStateCost = TGasPolicy.GetNewAccountStateCost(in gasAvailable); - long perAuthBaseStateCost = TGasPolicy.GetPerAuthBaseStateCost(in gasAvailable); + ulong newAccountStateCost = TGasPolicy.GetNewAccountStateCost(in gasAvailable); + ulong perAuthBaseStateCost = TGasPolicy.GetPerAuthBaseStateCost(in gasAvailable); int maxRefunds = tx.AuthorizationList.Length; if (!TryCalculate8037DelegationRefund( newAccountStateCost, @@ -431,30 +431,27 @@ private TransactionResult Validate8037DelegationRefundBounds(Transaction tx, IRe } private static bool TryCalculate8037DelegationRefund( - long newAccountStateCost, - long perAuthBaseStateCost, + ulong newAccountStateCost, + ulong perAuthBaseStateCost, int delegationRefunds, int delegationAuthBaseRefunds, - out long stateGasRefund) + out ulong stateGasRefund) { stateGasRefund = 0; - if (newAccountStateCost < 0 || - perAuthBaseStateCost < 0 || - delegationRefunds < 0 || - delegationAuthBaseRefunds < 0) + if (delegationRefunds < 0 || delegationAuthBaseRefunds < 0) { return false; } - if ((delegationRefunds != 0 && newAccountStateCost > long.MaxValue / delegationRefunds) || - (delegationAuthBaseRefunds != 0 && perAuthBaseStateCost > long.MaxValue / delegationAuthBaseRefunds)) + if ((delegationRefunds != 0 && newAccountStateCost > ulong.MaxValue / (ulong)delegationRefunds) || + (delegationAuthBaseRefunds != 0 && perAuthBaseStateCost > ulong.MaxValue / (ulong)delegationAuthBaseRefunds)) { return false; } - long newAccountStateRefund = newAccountStateCost * delegationRefunds; - long authBaseStateRefund = perAuthBaseStateCost * delegationAuthBaseRefunds; - if (newAccountStateRefund > long.MaxValue - authBaseStateRefund) + ulong newAccountStateRefund = newAccountStateCost * (ulong)delegationRefunds; + ulong authBaseStateRefund = perAuthBaseStateCost * (ulong)delegationAuthBaseRefunds; + if (newAccountStateRefund > ulong.MaxValue - authBaseStateRefund) { return false; } @@ -553,7 +550,7 @@ private AuthorizationTupleResult IsValidForExecution( return AuthorizationTupleResult.InvalidAsCodeDeployed; } - UInt256 authNonce = WorldState.GetNonce(authorizationTuple.Authority); + ulong authNonce = WorldState.GetNonce(authorizationTuple.Authority); if (authNonce != authorizationTuple.Nonce) { error = $"Skipping tuple in authorization_list because nonce is set to {authorizationTuple.Nonce}, but authority ({authorizationTuple.Authority}) has {authNonce}."; @@ -643,7 +640,7 @@ protected virtual TransactionResult ValidateStatic( } } - if (spec.IsEip8037Enabled && intrinsicGas.ExceedsCap(Eip7825Constants.DefaultTxGasLimitCap, out long regular, out long floor)) + if (spec.IsEip8037Enabled && intrinsicGas.ExceedsCap(Eip7825Constants.DefaultTxGasLimitCap, out ulong regular, out ulong floor)) { TraceLogInvalidTx(tx, $"TX_INTRINSIC_GAS_EXCEEDS_CAP regular={regular} floor={floor} > {Eip7825Constants.DefaultTxGasLimitCap}"); return TransactionResult.ErrorType.GasLimitBelowIntrinsicGas.WithDetail( @@ -652,14 +649,14 @@ protected virtual TransactionResult ValidateStatic( TGasPolicy standard = intrinsicGas.Standard; TGasPolicy minimal = intrinsicGas.MinimalGas; - long minGasRequired = spec.IsEip8037Enabled + ulong minGasRequired = spec.IsEip8037Enabled ? Math.Max(TGasPolicy.GetRemainingGas(in standard) + TGasPolicy.GetStateReservoir(in standard), TGasPolicy.GetRemainingGas(in minimal)) : TGasPolicy.GetRemainingGas(in minimal); return ValidateGas(tx, header, spec, in standard, minGasRequired, validate); } - protected virtual TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec spec, in TGasPolicy intrinsicGas, long minGasRequired, bool validate) + protected virtual TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec spec, in TGasPolicy intrinsicGas, ulong minGasRequired, bool validate) { if (tx.GasLimit < minGasRequired) { @@ -684,13 +681,13 @@ protected virtual TransactionResult ValidateGas(Transaction tx, BlockHeader head return TransactionResult.Ok; } - long gasUsedForAllowance = _parallel ? 0 : spec switch + ulong gasUsedForAllowance = _parallel ? 0 : spec switch { { IsEip7778Enabled: true } => _blockCumulativeReceiptGas, _ => header.GasUsed, }; - long maxTransactionGasLimit = header.GasLimit - gasUsedForAllowance; + ulong maxTransactionGasLimit = header.GasLimit - gasUsedForAllowance; if (tx.GasLimit > maxTransactionGasLimit) { string limitDescription = _parallel @@ -744,7 +741,7 @@ protected virtual bool RecoverSenderIfNeeded(Transaction tx, IReleaseSpec spec, return deleteCallerAccount; } - protected virtual IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, long blockGasLimit) + protected virtual IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, ulong blockGasLimit) => TGasPolicy.CalculateIntrinsicGas(tx, spec, blockGasLimit); protected virtual UInt256 CalculateEffectiveGasPrice(Transaction tx, bool eip1559Enabled, in UInt256 baseFee, out UInt256 opcodeGasPrice) @@ -770,7 +767,7 @@ protected virtual TransactionResult ValidateSender(Transaction tx, BlockHeader h } protected static bool ShouldValidateGas(Transaction tx, ExecutionOptions opts) - => !opts.HasFlag(ExecutionOptions.SkipValidation) || !tx.MaxFeePerGas.IsZero || !tx.MaxPriorityFeePerGas.IsZero; + => !opts.HasFlag(ExecutionOptions.SkipValidation) || tx.MaxFeePerGas != 0UL || tx.MaxPriorityFeePerGas != 0UL; protected virtual TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts, in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobBaseFee) @@ -789,7 +786,8 @@ protected virtual TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, IT } UInt256 senderBalance = WorldState.GetBalance(tx.SenderAddress!); - if (UInt256.SubtractUnderflow(in senderBalance, in tx.ValueRef, out UInt256 balanceLeft)) + UInt256 txValue = (UInt256)tx.ValueRef; + if (UInt256.SubtractUnderflow(in senderBalance, in txValue, out UInt256 balanceLeft)) { TraceLogInvalidTx(tx, $"INSUFFICIENT_SENDER_BALANCE: ({tx.SenderAddress})_BALANCE = {senderBalance}"); return InsufficientFundsForTransfer(tx, senderBalance); @@ -857,7 +855,7 @@ private static TransactionResult InsufficientFundsForGas(Transaction tx, UInt256 protected virtual TransactionResult IncrementNonce(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts) { bool validate = !opts.HasFlag(ExecutionOptions.SkipValidation); - UInt256 nonce = WorldState.GetNonce(tx.SenderAddress!); + ulong nonce = WorldState.GetNonce(tx.SenderAddress!); if (validate && tx.Nonce != nonce) { TraceLogInvalidTx(tx, $"WRONG_TRANSACTION_NONCE: {tx.Nonce} (expected {nonce})"); @@ -870,7 +868,7 @@ protected virtual TransactionResult IncrementNonce(Transaction tx, BlockHeader h $"nonce too low: address {sender}, tx: {tx.Nonce} state: {nonce}"); } - UInt256 newNonce = validate || nonce < ulong.MaxValue ? nonce + 1 : 0; + ulong newNonce = validate || nonce < ulong.MaxValue ? nonce + 1 : 0; WorldState.SetNonce(tx.SenderAddress, newNonce); return TransactionResult.Ok; @@ -951,10 +949,10 @@ private int ExecuteEvmCall( // EIP-7702 + EIP-8037: capture the tx-start state reservoir after authorization refunds. // The halt path needs this to correctly initialize the reservoir in ResetForHalt. - long postIntrinsicStateReservoir = TGasPolicy.GetStateReservoir(in gasAvailable); + ulong postIntrinsicStateReservoir = TGasPolicy.GetStateReservoir(in gasAvailable); Snapshot snapshot = WorldState.TakeSnapshot(); - long floorGasLong = TGasPolicy.GetRemainingGas(gas.FloorGas); + ulong floorGasLong = TGasPolicy.GetRemainingGas(gas.FloorGas); PayValue(tx, spec, opts); @@ -983,11 +981,11 @@ private int ExecuteEvmCall( else { // Gas for initcode execution is not consumed, only intrinsic creation transaction costs are charged. - long minimalGasLong = TGasPolicy.GetRemainingGas(gas.MinimalGas); + ulong minimalGasLong = TGasPolicy.GetRemainingGas(gas.MinimalGas); gasConsumed = minimalGasLong; // If noValidation we didn't charge for gas, so do not refund; otherwise return unspent gas if (!opts.HasFlag(ExecutionOptions.SkipValidation)) - WorldState.AddToBalance(tx.SenderAddress!, (ulong)(tx.GasLimit - minimalGasLong) * VirtualMachine.TxExecutionContext.GasPrice, spec); + WorldState.AddToBalance(tx.SenderAddress!, (tx.GasLimit - minimalGasLong) * VirtualMachine.TxExecutionContext.GasPrice, spec); goto Complete; } @@ -1047,7 +1045,7 @@ private int ExecuteEvmCall( if (tracingRefunds) { - tracer.ReportRefund(spec.GasCosts.DestroyRefund); + tracer.ReportRefund((long)spec.GasCosts.DestroyRefund); } } } @@ -1097,14 +1095,14 @@ private int ExecuteEvmCall( } [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void RefundRevertedExecutionStateGas(IReleaseSpec spec, long stateGasFloor, ref TGasPolicy gas) + static void RefundRevertedExecutionStateGas(IReleaseSpec spec, ulong stateGasFloor, ref TGasPolicy gas) { if (!spec.IsEip8037Enabled) { return; } - long revertedStateGas = TGasPolicy.GetStateGasUsed(in gas); + ulong revertedStateGas = TGasPolicy.GetStateGasUsed(in gas); if (revertedStateGas > stateGasFloor) { TGasPolicy.RefundStateGas(ref gas, revertedStateGas, stateGasFloor); @@ -1122,17 +1120,17 @@ private GasConsumed CompleteEip8037Halt( ref TGasPolicy gas, in UInt256 gasPrice, in TGasPolicy intrinsicGasStandard, - long floorGas, - long postIntrinsicStateReservoir) + ulong floorGas, + ulong postIntrinsicStateReservoir) { - long intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); - long refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); - long initialStateReservoir = CalculateInitialStateReservoir(tx.GasLimit, in intrinsicGasStandard); - long refundedIntrinsicStateGas = Math.Max(0, postIntrinsicStateReservoir - initialStateReservoir) + refundedTopLevelCreateStateGas; - long postHaltIntrinsicStateGas = Math.Max(0, intrinsicStateGas - refundedIntrinsicStateGas); + ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); + ulong refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); + ulong initialStateReservoir = CalculateInitialStateReservoir(tx.GasLimit, in intrinsicGasStandard); + ulong refundedIntrinsicStateGas = Math.Max(0, postIntrinsicStateReservoir - initialStateReservoir) + refundedTopLevelCreateStateGas; + ulong postHaltIntrinsicStateGas = Math.Max(0, intrinsicStateGas - refundedIntrinsicStateGas); RefundRevertedExecutionStateGas(spec, postHaltIntrinsicStateGas, ref gas); - long refundedCreateStateSpillForHalt = CalculateRefundedCreateStateSpillForHalt(in gas); - long postHaltStateReservoir = Math.Max(postIntrinsicStateReservoir, TGasPolicy.GetStateReservoir(in gas)); + ulong refundedCreateStateSpillForHalt = CalculateRefundedCreateStateSpillForHalt(in gas); + ulong postHaltStateReservoir = Math.Max(postIntrinsicStateReservoir, TGasPolicy.GetStateReservoir(in gas)); TGasPolicy.ResetForHalt(ref gas, postHaltStateReservoir, postHaltIntrinsicStateGas); return RefundOnTopLevelHalt(tx, spec, opts, in gas, in gasPrice, in intrinsicGasStandard, floorGas, refundedCreateStateSpillForHalt); } @@ -1144,16 +1142,16 @@ protected virtual GasConsumed RefundOnFail( in TGasPolicy gas, in UInt256 gasPrice, in TGasPolicy intrinsicGasStandard, - long floorGas = 0) + ulong floorGas = 0) { if (!spec.IsEip8037Enabled) return tx.GasLimit; - long remainingRegularGas = TGasPolicy.GetRemainingGas(in gas); - long stateReservoir = TGasPolicy.GetStateReservoir(in gas); - long spentGas = Math.Max(tx.GasLimit - remainingRegularGas - stateReservoir, floorGas); - long blockGas = Calculate8037BlockRegularGas(in gas, in intrinsicGasStandard, tx.GasLimit, floorGas, remainingRegularGas); - long blockStateGas = TGasPolicy.GetStateGasUsed(in gas); + ulong remainingRegularGas = TGasPolicy.GetRemainingGas(in gas); + ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); + ulong spentGas = Math.Max(tx.GasLimit - remainingRegularGas - stateReservoir, floorGas); + ulong blockGas = Calculate8037BlockRegularGas(in gas, in intrinsicGasStandard, tx.GasLimit, floorGas, remainingRegularGas); + ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, blockGas, blockStateGas); } @@ -1166,21 +1164,21 @@ protected virtual GasConsumed RefundOnContractCollision( in TGasPolicy gas, in UInt256 gasPrice, in TGasPolicy intrinsicGasStandard, - long floorGas) + ulong floorGas) { if (!spec.IsEip8037Enabled) return tx.GasLimit; TGasPolicy gasAfterCollision = gas; - long refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); + ulong refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); if (refundedTopLevelCreateStateGas > 0) { - long stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard) - refundedTopLevelCreateStateGas; + ulong stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard) - refundedTopLevelCreateStateGas; TGasPolicy.RefundStateGas(ref gasAfterCollision, refundedTopLevelCreateStateGas, stateGasFloor, trackSpillRefund: false); } - long blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterCollision); - long spentGas = Math.Max(tx.GasLimit - TGasPolicy.GetStateReservoir(in gasAfterCollision), floorGas); + ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterCollision); + ulong spentGas = Math.Max(tx.GasLimit - TGasPolicy.GetStateReservoir(in gasAfterCollision), floorGas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, spentGas, blockStateGas); } @@ -1192,18 +1190,18 @@ protected virtual GasConsumed RefundOnTopLevelHalt( in TGasPolicy gas, in UInt256 gasPrice, in TGasPolicy intrinsicGasStandard, - long floorGas, - long refundedCreateStateSpillForHalt) + ulong floorGas, + ulong refundedCreateStateSpillForHalt) { if (!spec.IsEip8037Enabled) return tx.GasLimit; - long stateReservoir = TGasPolicy.GetStateReservoir(in gas); - long spentGas = Math.Max(tx.GasLimit - stateReservoir, floorGas); - long intrinsicStateGas = TGasPolicy.GetStateGasUsed(in gas); - long spillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); - long effectiveStateGas = Math.Max(0, intrinsicStateGas - spillBurned) + refundedCreateStateSpillForHalt; - long blockGas = Math.Max(tx.GasLimit - stateReservoir - effectiveStateGas, floorGas); + ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); + ulong spentGas = Math.Max(tx.GasLimit - stateReservoir, floorGas); + ulong intrinsicStateGas = TGasPolicy.GetStateGasUsed(in gas); + ulong spillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); + ulong effectiveStateGas = Math.Max(0, intrinsicStateGas - spillBurned) + refundedCreateStateSpillForHalt; + ulong blockGas = Math.Max(tx.GasLimit - stateReservoir - effectiveStateGas, floorGas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, blockGas, effectiveStateGas); } @@ -1213,19 +1211,19 @@ private GasConsumed RefundFailedEip8037Gas( IReleaseSpec spec, ExecutionOptions opts, in UInt256 gasPrice, - long spentGas, - long blockGas, - long blockStateGas) + ulong spentGas, + ulong blockGas, + ulong blockStateGas) { if (ShouldRefundGas(tx, opts, in gasPrice) && spentGas < tx.GasLimit) - PayRefund(tx, (ulong)(tx.GasLimit - spentGas) * gasPrice, spec); + PayRefund(tx, (tx.GasLimit - spentGas) * gasPrice, spec); return new GasConsumed(spentGas, spentGas, blockGas, blockStateGas, spentGas); } protected virtual bool DeployContract(IReleaseSpec spec, Address codeOwner, in TransactionSubstate substate, in StackAccessTracker accessedItems, ref TGasPolicy unspentGas) { - if (!CodeDepositHandler.CalculateCost(spec, substate.Output.Length, in unspentGas, out long regularDepositCost, out long stateDepositCost)) + if (!CodeDepositHandler.CalculateCost(spec, substate.Output.Length, in unspentGas, out ulong regularDepositCost, out ulong stateDepositCost)) return false; if (CodeDepositHandler.CodeIsInvalid(spec, substate.Output)) @@ -1240,11 +1238,11 @@ private bool TryChargeCodeDeposit( Address codeOwner, in StackAccessTracker accessedItems, ref TGasPolicy unspentGas, - long regularDepositCost, - long stateDepositCost, + ulong regularDepositCost, + ulong stateDepositCost, byte[] code) { - long remainingGas = TGasPolicy.GetRemainingGas(in unspentGas); + ulong remainingGas = TGasPolicy.GetRemainingGas(in unspentGas); bool hasEnoughGas = remainingGas >= regularDepositCost && remainingGas + TGasPolicy.GetStateReservoir(in unspentGas) >= stateDepositCost; if (!hasEnoughGas) @@ -1260,11 +1258,16 @@ private bool TryChargeCodeDeposit( return true; } - protected virtual void PayValue(Transaction tx, IReleaseSpec spec, ExecutionOptions opts) => WorldState.SubtractFromBalance(tx.SenderAddress!, in tx.ValueRef, spec); + protected virtual void PayValue(Transaction tx, IReleaseSpec spec, ExecutionOptions opts) + { + UInt256 value = tx.ValueRef; + + WorldState.SubtractFromBalance(tx.SenderAddress!, in value, spec, out _); + } - protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, long spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) + protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) { - UInt256 fees = premiumPerGas * (ulong)spentGas; + UInt256 fees = premiumPerGas * spentGas; // n.b. destroyed accounts already set to zero balance // EIP-8037: always pay coinbase — deferred finalization will burn the balance @@ -1309,13 +1312,13 @@ protected void TraceLogInvalidTx(Transaction transaction, string reason) } protected virtual GasConsumed Refund(Transaction tx, BlockHeader header, IReleaseSpec spec, ExecutionOptions opts, - in TransactionSubstate substate, in TGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in TGasPolicy floorGas, in TGasPolicy intrinsicGasStandard, long postIntrinsicStateReservoir) + in TransactionSubstate substate, in TGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in TGasPolicy floorGas, in TGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) { TGasPolicy gasAfterExecution = unspentGas; - long stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); + ulong stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); if (substate.ShouldRevert && spec.IsEip8037Enabled) { - long refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); + ulong refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); if (refundedTopLevelCreateStateGas > 0) { stateGasFloor -= refundedTopLevelCreateStateGas; @@ -1323,8 +1326,8 @@ protected virtual GasConsumed Refund(Transaction tx, BlockHeader header, IReleas } } - long codeInsertRegularRefund = TGasPolicy.ApplyCodeInsertRefunds(ref gasAfterExecution, codeInsertRefunds, spec, stateGasFloor); - long floorGasLong = TGasPolicy.GetRemainingGas(floorGas); + ulong codeInsertRegularRefund = TGasPolicy.ApplyCodeInsertRefunds(ref gasAfterExecution, codeInsertRefunds, spec, stateGasFloor); + ulong floorGasLong = TGasPolicy.GetRemainingGas(floorGas); if (substate.IsError && spec.IsEip8037Enabled) { @@ -1334,20 +1337,20 @@ protected virtual GasConsumed Refund(Transaction tx, BlockHeader header, IReleas return CompleteEip8037Halt(tx, spec, opts, ref gasAfterExecution, in gasPrice, in intrinsicGasStandard, floorGasLong, postIntrinsicStateReservoir); } - (long spentGas, long refund) = CalculateSpentGasAndRefund(tx, spec, in substate, in gasAfterExecution, codeInsertRegularRefund); - (long blockGas, long blockStateGas) = CalculateBlockGas(spec, in substate, in gasAfterExecution, in intrinsicGasStandard, spentGas, floorGasLong, tx.GasLimit); + (ulong spentGas, ulong refund) = CalculateSpentGasAndRefund(tx, spec, in substate, in gasAfterExecution, codeInsertRegularRefund); + (ulong blockGas, ulong blockStateGas) = CalculateBlockGas(spec, in substate, in gasAfterExecution, in intrinsicGasStandard, spentGas, floorGasLong, tx.GasLimit); - long operationGas = spentGas - refund; - long spentGasAfterFloor = Math.Max(operationGas, floorGasLong); + ulong operationGas = spentGas - refund; + ulong spentGasAfterFloor = Math.Max(operationGas, floorGasLong); if (ShouldRefundGas(tx, opts, in gasPrice)) - PayRefund(tx, (ulong)(tx.GasLimit - spentGasAfterFloor) * gasPrice, spec); + PayRefund(tx, (tx.GasLimit - spentGasAfterFloor) * gasPrice, spec); return new GasConsumed(spentGasAfterFloor, operationGas, blockGas, blockStateGas, Math.Max(spentGas, floorGasLong)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long CalculateTopLevelCreateIntrinsicStateRefund( + private static ulong CalculateTopLevelCreateIntrinsicStateRefund( Transaction tx, in TGasPolicy intrinsicGasStandard) { @@ -1362,42 +1365,42 @@ private static long CalculateTopLevelCreateIntrinsicStateRefund( } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long CalculateInitialStateReservoir( - long txGasLimit, + private static ulong CalculateInitialStateReservoir( + ulong txGasLimit, in TGasPolicy intrinsicGasStandard) { - long intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); + ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); return Math.Max(0, txGasLimit - intrinsicStateGas - Eip7825Constants.DefaultTxGasLimitCap); } - private (long spentGas, long refund) CalculateSpentGasAndRefund( + private (ulong spentGas, ulong refund) CalculateSpentGasAndRefund( Transaction tx, IReleaseSpec spec, in TransactionSubstate substate, in TGasPolicy gasAfterExecution, - long codeInsertRegularRefund) + ulong codeInsertRegularRefund) { - long spentGas = substate.IsError + ulong spentGas = substate.IsError ? tx.GasLimit : tx.GasLimit - TGasPolicy.GetRemainingGas(in gasAfterExecution) - TGasPolicy.GetStateReservoir(in gasAfterExecution); - long totalToRefund = codeInsertRegularRefund; + ulong totalToRefund = codeInsertRegularRefund; if (!substate.IsError && !substate.ShouldRevert) - totalToRefund += substate.Refund + substate.DestroyList.Count * spec.GasCosts.DestroyRefund; + totalToRefund += substate.Refund + (ulong)substate.DestroyList.Count * spec.GasCosts.DestroyRefund; return (spentGas, CalculateClaimableRefund(spentGas, totalToRefund, spec)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static long CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) + private static ulong CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) { - long returnedSpillNotInReservoir = + ulong returnedSpillNotInReservoir = TGasPolicy.GetStateGasSpill(in gas) - TGasPolicy.GetStateReservoir(in gas) - TGasPolicy.GetStateGasSpillBurned(in gas); - long refundedSpill = TGasPolicy.GetStateGasSpillRefunded(in gas); - long refundedSpillNotInReservoir = Math.Min(returnedSpillNotInReservoir, refundedSpill); - long createStateGas = TGasPolicy.GetCreateStateCost(in gas); + ulong refundedSpill = TGasPolicy.GetStateGasSpillRefunded(in gas); + ulong refundedSpillNotInReservoir = Math.Min(returnedSpillNotInReservoir, refundedSpill); + ulong createStateGas = TGasPolicy.GetCreateStateCost(in gas); if (createStateGas <= 0) { return 0; @@ -1407,20 +1410,20 @@ private static long CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) return Math.Max(0, (refundedSpillNotInReservoir / createStateGas) * createStateGas); } - private static (long blockGas, long blockStateGas) CalculateBlockGas( + private static (ulong blockGas, ulong blockStateGas) CalculateBlockGas( IReleaseSpec spec, in TransactionSubstate substate, in TGasPolicy gasAfterExecution, in TGasPolicy intrinsicGasStandard, - long preRefundGas, - long floorGas, - long txGasLimit) + ulong preRefundGas, + ulong floorGas, + ulong txGasLimit) { if (!spec.IsEip8037Enabled) return (spec.IsEip7778Enabled ? Math.Max(preRefundGas, floorGas) : 0, 0); - long blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterExecution); - long blockGas = Calculate8037BlockRegularGas( + ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterExecution); + ulong blockGas = Calculate8037BlockRegularGas( in gasAfterExecution, in intrinsicGasStandard, txGasLimit, @@ -1430,19 +1433,19 @@ private static (long blockGas, long blockStateGas) CalculateBlockGas( return (blockGas, blockStateGas); } - private static long Calculate8037BlockRegularGas( + private static ulong Calculate8037BlockRegularGas( in TGasPolicy gasAfterExecution, in TGasPolicy intrinsicGasStandard, - long txGasLimit, - long floorGas, - long remainingRegularGas) + ulong txGasLimit, + ulong floorGas, + ulong remainingRegularGas) { - long intrinsicRegularGas = TGasPolicy.GetRemainingGas(in intrinsicGasStandard); - long intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); - long initialReservoir = Math.Max(0, txGasLimit - intrinsicStateGas - Eip7825Constants.DefaultTxGasLimitCap); - long initialRegularGas = txGasLimit - intrinsicRegularGas - intrinsicStateGas - initialReservoir; - long stateGasSpill = TGasPolicy.GetStateGasSpill(in gasAfterExecution); - long stateGasSpillReclassified = TGasPolicy.GetStateGasSpillReclassified(in gasAfterExecution); + ulong intrinsicRegularGas = TGasPolicy.GetRemainingGas(in intrinsicGasStandard); + ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); + ulong initialReservoir = Math.Max(0, txGasLimit - intrinsicStateGas - Eip7825Constants.DefaultTxGasLimitCap); + ulong initialRegularGas = txGasLimit - intrinsicRegularGas - intrinsicStateGas - initialReservoir; + ulong stateGasSpill = TGasPolicy.GetStateGasSpill(in gasAfterExecution); + ulong stateGasSpillReclassified = TGasPolicy.GetStateGasSpillReclassified(in gasAfterExecution); return Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( intrinsicRegularGas, initialRegularGas, @@ -1461,7 +1464,7 @@ protected virtual void PayRefund(Transaction tx, UInt256 refundAmount, IReleaseS private static bool ShouldRefundGas(Transaction tx, ExecutionOptions opts, in UInt256 gasPrice) => !gasPrice.IsZero && ShouldValidateGas(tx, opts); - protected virtual long CalculateClaimableRefund(long spentGas, long totalRefund, IReleaseSpec spec) + protected virtual ulong CalculateClaimableRefund(ulong spentGas, ulong totalRefund, IReleaseSpec spec) => RefundHelper.CalculateClaimableRefund(spentGas, totalRefund, spec); [DoesNotReturn, StackTraceHidden] diff --git a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs index 5d81bf93791e..1611f3bf7dc9 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs @@ -52,7 +52,7 @@ public readonly ref struct TransactionSubstate public EvmExceptionType EvmExceptionType { get; } public ReadOnlyMemory Output { get; } public bool ShouldRevert { get; } - public long Refund { get; } + public ulong Refund { get; } public JournalCollection Logs => _logs; public JournalSet
DestroyList => _destroyList ?? _emptyDestroyList; @@ -69,7 +69,7 @@ public TransactionSubstate(EvmExceptionType exceptionType, bool isTracerConnecte } public TransactionSubstate(ReadOnlyMemory bytes, - long refund, + ulong refund, JournalSet
destroyList, JournalCollection logs, bool shouldRevert, diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 5454ae8bedd7..77551c0c2a87 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -263,7 +263,7 @@ public virtual TransactionSubstate ExecuteTransaction( // Refund the remaining gas from the completed call frame (success path). TGasPolicy.Refund(ref _currentState.Gas, in previousState.Gas); - long gasAvailableForCodeDeposit = TGasPolicy.GetRemainingGas(previousState.Gas); + ulong gasAvailableForCodeDeposit = TGasPolicy.GetRemainingGas(previousState.Gas); // Process contract creation calls differently from regular calls. if (isCreate) @@ -386,14 +386,14 @@ protected ZeroPaddedSpan HandleRegularReturn(scoped in CallResult protected void HandleCreate( in CallResult callResult, VmState previousState, - long gasAvailableForCodeDeposit, + ulong gasAvailableForCodeDeposit, ref bool previousStateSucceeded) { IReleaseSpec spec = BlockExecutionContext.Spec; - if (!CodeDepositHandler.CalculateCost(spec, callResult.Output.Length, in previousState.Gas, out long regularDepositCost, out long stateDepositCost)) + if (!CodeDepositHandler.CalculateCost(spec, callResult.Output.Length, in previousState.Gas, out ulong regularDepositCost, out ulong stateDepositCost)) { - regularDepositCost = long.MaxValue; - stateDepositCost = long.MaxValue; + regularDepositCost = ulong.MaxValue; + stateDepositCost = ulong.MaxValue; } bool invalidCode = CodeDepositHandler.CodeIsInvalid(spec, callResult.Output); @@ -421,18 +421,18 @@ protected TransactionSubstate PrepareTopLevelSubstate(scoped in CallResult callR private void TryChargeAndDepositCode( VmState previousState, - long gasAvailableForCodeDeposit, + ulong gasAvailableForCodeDeposit, ref bool previousStateSucceeded, - long regularDepositCost, - long stateDepositCost, + ulong regularDepositCost, + ulong stateDepositCost, bool invalidCode, ReadOnlyMemory code) { IReleaseSpec spec = BlockExecutionContext.Spec; Address callCodeOwner = previousState.Env.ExecutingAccount; - long childStateReservoir = TGasPolicy.GetStateReservoir(in previousState.Gas); - long stateSpill = Math.Max(0, stateDepositCost - childStateReservoir); + ulong childStateReservoir = TGasPolicy.GetStateReservoir(in previousState.Gas); + ulong stateSpill = Math.Max(0, stateDepositCost - childStateReservoir); bool hasEnoughGas = gasAvailableForCodeDeposit >= regularDepositCost + stateSpill; bool chargedCodeDeposit = false; @@ -627,8 +627,8 @@ private void RefundRevertedTopLevelStateGas() // state_gas_used (originally drawn from gas_left) is still in the user's pocket. // Refund the full state_gas_used — reservoir-portion AND spilled-portion — to the // reservoir. The user is billed only the regular component. - long stateGasFloor = _currentState.InitialStateGasUsed; - long revertedStateGas = TGasPolicy.GetStateGasUsed(in _currentState.Gas); + ulong stateGasFloor = _currentState.InitialStateGasUsed; + ulong revertedStateGas = TGasPolicy.GetStateGasUsed(in _currentState.Gas); if (revertedStateGas > stateGasFloor) { TGasPolicy.RefundStateGas(ref _currentState.Gas, revertedStateGas, stateGasFloor); @@ -636,24 +636,24 @@ private void RefundRevertedTopLevelStateGas() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void CreditStateGasRefund(ref TGasPolicy gas, long amount, bool trackSpillRefund = true) + internal void CreditStateGasRefund(ref TGasPolicy gas, ulong amount, bool trackSpillRefund = true) { - if (!Spec.IsEip8037Enabled || amount <= 0) + if (!Spec.IsEip8037Enabled || amount == 0) { return; } VmState vmState = VmState; - long stateGasFloor = vmState.InitialStateGasUsed; - long refundableStateGas = Math.Max(0, TGasPolicy.GetStateGasUsed(in gas) - stateGasFloor); - long appliedRefund = Math.Min(amount, refundableStateGas); + ulong stateGasFloor = vmState.InitialStateGasUsed; + ulong refundableStateGas = Math.Max(0, TGasPolicy.GetStateGasUsed(in gas) - stateGasFloor); + ulong appliedRefund = Math.Min(amount, refundableStateGas); if (appliedRefund > 0) { TGasPolicy.RefundStateGas(ref gas, appliedRefund, stateGasFloor, trackSpillRefund); } - long pendingRefund = amount - appliedRefund; + ulong pendingRefund = amount - appliedRefund; if (pendingRefund > 0) { // The restored state gas may have been paid by an ancestor frame. It is still @@ -670,8 +670,8 @@ private void IncorporateChildStateGasRefunds(VmState childState) { if (childState.StateGasRefundPending > 0) { - long pendingRefund = childState.StateGasRefundPending; - long unappliedRefund = TGasPolicy.DiscardStateGas( + ulong pendingRefund = childState.StateGasRefundPending; + ulong unappliedRefund = TGasPolicy.DiscardStateGas( ref _currentState.Gas, pendingRefund, _currentState.InitialStateGasUsed, @@ -905,9 +905,9 @@ protected void TraceTransactionActionEnd(VmState currentState, in Ca { IReleaseSpec spec = BlockExecutionContext.Spec; // Calculate the gas cost required for depositing the contract code based on the length of the output. - long regularDepositCost = 0; - long stateDepositCost = 0; - long codeDepositGasCost = CodeDepositHandler.CalculateCost(spec, callResult.Output.Length, in currentState.Gas); + ulong regularDepositCost = 0; + ulong stateDepositCost = 0; + ulong codeDepositGasCost = CodeDepositHandler.CalculateCost(spec, callResult.Output.Length, in currentState.Gas); bool hasEnoughGasForCodeDeposit = true; if (currentState.ExecutionType.IsAnyCreate()) { @@ -929,14 +929,14 @@ protected void TraceTransactionActionEnd(VmState currentState, in Ca else if (callResult.ShouldRevert) { // For creation operations, subtract the code deposit cost from the available gas; otherwise, use full gas. - long gasAvailable = TGasPolicy.GetRemainingGas(currentState.Gas); - long reportedGas = currentState.ExecutionType.IsAnyCreate() ? gasAvailable - codeDepositGasCost : gasAvailable; + ulong gasAvailable = TGasPolicy.GetRemainingGas(currentState.Gas); + ulong reportedGas = currentState.ExecutionType.IsAnyCreate() ? gasAvailable - codeDepositGasCost : gasAvailable; _txTracer.ReportActionRevert(reportedGas, outputBytes); } // Process contract creation flows. else if (currentState.ExecutionType.IsAnyCreate()) { - long gasAvailable = TGasPolicy.GetRemainingGas(currentState.Gas); + ulong gasAvailable = TGasPolicy.GetRemainingGas(currentState.Gas); // If available gas is insufficient to cover the code deposit cost... if (!hasEnoughGasForCodeDeposit) { @@ -1013,7 +1013,7 @@ private CallResult RunPrecompile(VmState state) } if ((ulong)baseGasCost + (ulong)dataGasCost > (ulong)long.MaxValue || - !TGasPolicy.UpdateGas(ref gas, baseGasCost + dataGasCost)) + !TGasPolicy.UpdateGas(ref gas, (ulong)(baseGasCost + dataGasCost))) { return new(default, precompileSuccess: false, shouldRevert: true, EvmExceptionType.OutOfGas); } @@ -1389,7 +1389,7 @@ protected virtual CallResult RunByteCode( static void ThrowOperationCanceledException() => throw new OperationCanceledException("Cancellation Requested"); } - private CallResult GetFailureReturn(long gasAvailable, EvmExceptionType exceptionType) + private CallResult GetFailureReturn(ulong gasAvailable, EvmExceptionType exceptionType) { if (_txTracer.IsTracingInstructions) EndInstructionTraceError(gasAvailable, exceptionType); @@ -1416,7 +1416,7 @@ private void UpdateCurrentState(int pc, in TGasPolicy gas, int stackHead) } [MethodImpl(MethodImplOptions.NoInlining)] - private void StartInstructionTrace(Instruction instruction, long gasAvailable, int programCounter, in EvmStack stackValue) + private void StartInstructionTrace(Instruction instruction, ulong gasAvailable, int programCounter, in EvmStack stackValue) { VmState vmState = VmState; _txTracer.StartOperation(programCounter, instruction, gasAvailable, vmState.Env); @@ -1433,10 +1433,10 @@ private void StartInstructionTrace(Instruction instruction, long gasAvailable, i } [MethodImpl(MethodImplOptions.NoInlining)] - internal void EndInstructionTrace(long gasAvailable) => _txTracer.ReportOperationRemainingGas(gasAvailable); + internal void EndInstructionTrace(ulong gasAvailable) => _txTracer.ReportOperationRemainingGas(gasAvailable); [MethodImpl(MethodImplOptions.NoInlining)] - private void EndInstructionTraceError(long gasAvailable, EvmExceptionType evmExceptionType) + private void EndInstructionTraceError(ulong gasAvailable, EvmExceptionType evmExceptionType) { _txTracer.ReportOperationRemainingGas(gasAvailable); _txTracer.ReportOperationError(evmExceptionType); @@ -1460,7 +1460,7 @@ private void AddTransferLog(VmState currentState) if (currentState.ExecutionType is not (ExecutionType.DELEGATECALL or ExecutionType.CALLCODE)) { // Runtime check acceptable here — called once per frame entry, not per instruction. - if (Spec.IsEip7708Enabled && !currentState.Env.Value.IsZero && currentState.From != currentState.To) + if (Spec.IsEip7708Enabled && currentState.Env.Value != 0UL && currentState.From != currentState.To) AddLog(TransferLog.CreateTransfer(currentState.From, currentState.To, currentState.Env.Value)); } } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.warmup.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.warmup.cs index 9d11fd93b8e4..2d7a9963c4d5 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.warmup.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.warmup.cs @@ -53,7 +53,7 @@ public static void WarmUpEvmInstructions(IWorldState state, ICodeInfoRepository value: 0, inputData: default); - using (VmState vmState = VmState.RentTopLevel(TGasPolicy.FromLong(long.MaxValue), ExecutionType.TRANSACTION, env, new StackAccessTracker(), state.TakeSnapshot())) + using (VmState vmState = VmState.RentTopLevel(TGasPolicy.FromULong(ulong.MaxValue), ExecutionType.TRANSACTION, env, new StackAccessTracker(), state.TakeSnapshot())) { vm.VmState = vmState; vm._worldState = state; @@ -154,7 +154,7 @@ private static void RunOpCodes(VirtualMachine vm, IWor ITxTracer txTracer = new FeesTracer(); vm._txTracer = txTracer; vmState.InitializeStacks(txTracer, vmState.Env.CodeInfo.CodeSpan, out EvmStack stack); - TGasPolicy gas = TGasPolicy.FromLong(long.MaxValue); + TGasPolicy gas = TGasPolicy.FromULong(ulong.MaxValue); int pc = 0; for (int repeat = 0; repeat < WarmUpIterations; repeat++) @@ -178,7 +178,7 @@ private static void RunOpCodes(VirtualMachine vm, IWor state.Reset(resetBlockChanges: true); stack.Head = 0; - gas = TGasPolicy.FromLong(long.MaxValue); + gas = TGasPolicy.FromULong(ulong.MaxValue); pc = 0; } } @@ -186,10 +186,10 @@ private static void RunOpCodes(VirtualMachine vm, IWor private class WarmupBlockhashProvider(ISpecProvider specProvider) : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, long number) + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number) => GetBlockhash(currentBlock, number, specProvider.GetSpec(currentBlock)); - public Hash256 GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) => Keccak.Compute(spec!.IsBlockHashInStateAvailable + public Hash256 GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) => Keccak.Compute(spec!.IsBlockHashInStateAvailable ? (Eip2935Constants.RingBufferSize + number).ToString() : number.ToString()); diff --git a/src/Nethermind/Nethermind.Evm/VmState.cs b/src/Nethermind/Nethermind.Evm/VmState.cs index 8e3f4ba45573..ad61a7fea480 100644 --- a/src/Nethermind/Nethermind.Evm/VmState.cs +++ b/src/Nethermind/Nethermind.Evm/VmState.cs @@ -26,14 +26,14 @@ public class VmState : IDisposable public byte[]? DataStack; public TGasPolicy Gas; - public long InitialStateGasUsed; - public long StateGasRefundPending; + public ulong InitialStateGasUsed; + public ulong StateGasRefundPending; // State-gas refund already made spendable in this frame while its accounting correction // still has to reach the ancestor frame that originally paid the state gas. - public long StateGasRefundAdvanced; + public ulong StateGasRefundAdvanced; internal long OutputDestination { get; private set; } // TODO: move to CallEnv internal long OutputLength { get; private set; } // TODO: move to CallEnv - public long Refund { get; set; } + public ulong Refund { get; set; } public int DataStackHead; public ExecutionType ExecutionType { get; private set; } // TODO: move to CallEnv public int ProgramCounter { get; set; } diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index fdaf8616eadd..423ba40c20df 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -117,7 +117,7 @@ public void get_transaction_returns_receipt_and_transaction_when_found() { int index = 5; Transaction[] transactions = Enumerable.Range(0, 10) - .Select(static i => Build.A.Transaction.WithNonce((UInt256)i).WithHash(TestItem.Keccaks[i]).TestObject) + .Select(static i => Build.A.Transaction.WithNonce((ulong)i).WithHash(TestItem.Keccaks[i]).TestObject) .ToArray(); Block block = Build.A.Block .WithTransactions(transactions.ToArray()) @@ -138,7 +138,7 @@ public void get_transaction_returns_receipt_and_transaction_when_found() Assert.That(_blockchainBridge.TryGetTransaction(transactions[index].Hash!, out TransactionLookupResult? result), Is.True); Assert.Multiple(() => { - Assert.That(result!.Value.Transaction.Nonce, Is.EqualTo((UInt256)index)); + Assert.That(result!.Value.Transaction.Nonce, Is.EqualTo((ulong)index)); Assert.That(result.Value.Transaction.Hash, Is.EqualTo(TestItem.Keccaks[index])); }); Assert.That(result.Value.ExtraData, Is.EqualTo(new TransactionForRpcContext( @@ -221,8 +221,8 @@ public void Call_uses_valid_beneficiary() [TestCase(0)] public void Bridge_head_is_correct(long headNumber) { - Block head = Build.A.Block.WithNumber(headNumber).TestObject; - Block bestSuggested = Build.A.Block.WithNumber(8).TestObject; + Block head = Build.A.Block.WithNumber((ulong)headNumber).TestObject; + Block bestSuggested = Build.A.Block.WithNumber(8UL).TestObject; _blockTree.Head.Returns(head); _blockTree.BestSuggestedBody.Returns(bestSuggested); @@ -571,7 +571,7 @@ private static IEnumerable MinerPremiumNegativeCases() { GasLimit = 56786, SenderAddress = sender, - DecodedMaxFeePerGas = maxFeePerGas, + DecodedMaxFeePerGas = (ulong)maxFeePerGas, Type = TxType.EIP1559 }; yield return new TestCaseData( diff --git a/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs b/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs index 4549471a08ee..2aa00fecb030 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs @@ -70,8 +70,8 @@ public void IsSyncing_ReturnsExpectedResult(long bestHeader, long currentHead, b ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(bestHeader).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(currentHead).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber((ulong)bestHeader).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber((ulong)currentHead).TestObject).TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, new SyncConfig(), new StaticSelector(SyncMode.All), syncProgressResolver, LimboLogs.Instance); SyncingResult syncingResult = ethSyncingInfo.GetFullInfo(); @@ -97,7 +97,7 @@ public void IsSyncing_AncientBarriers(bool resolverDownloadingBodies, PivotNumber = 1000 }; IBlockTree blockTree = Substitute.For(); - blockTree.SyncPivot.Returns((1000, Keccak.Zero)); + blockTree.SyncPivot.Returns((1000UL, Keccak.Zero)); ISyncPointers syncPointers = Substitute.For(); ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(resolverDownloadingBodies); @@ -164,8 +164,8 @@ public void IsSyncing_ReturnsFalseOnFastSyncWithoutPivot(long bestHeader, long c ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(bestHeader).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(currentHead).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber((ulong)bestHeader).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber((ulong)currentHead).TestObject).TestObject); SyncConfig syncConfig = new() { FastSync = true, @@ -182,7 +182,7 @@ public void IsSyncing_ReturnsFalseOnFastSyncWithoutPivot(long bestHeader, long c private SyncingResult CreateSyncingResult(bool isSyncing, long currentBlock, long highestBlock, SyncMode syncMode) { if (!isSyncing) return SyncingResult.NotSyncing; - return new SyncingResult { CurrentBlock = currentBlock, HighestBlock = highestBlock, IsSyncing = true, StartingBlock = 0, SyncMode = syncMode }; + return new SyncingResult { CurrentBlock = (ulong)currentBlock, HighestBlock = (ulong)highestBlock, IsSyncing = true, StartingBlock = 0, SyncMode = syncMode }; } } } diff --git a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs index 7b3bec9f9549..074827b47099 100644 --- a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs @@ -165,7 +165,7 @@ CancellationToken cancellation ) { _config.MaxBatchSize = batchSize; - _syncConfig.AncientReceiptsBarrier = minBarrier; + _syncConfig.AncientReceiptsBarrier = (ulong)minBarrier; Assert.That(_syncConfig.AncientReceiptsBarrierCalc, Is.EqualTo(minBarrier)); int expectedMin = minBarrier <= 1 ? 0 : synced[0] < 0 ? minBarrier : Math.Min(synced[0], minBarrier); @@ -224,7 +224,7 @@ public async Task Should_CompleteImmediately_IfAlreadySynced( { Assert.That(minBlock, Is.LessThanOrEqualTo(minBarrier)); - _syncConfig.AncientReceiptsBarrier = minBarrier; + _syncConfig.AncientReceiptsBarrier = (ulong)minBarrier; LogIndexBuilder builder = GetService(new FailingLogIndexStorage(0, new("Should not set new receipts.")) { MinBlockNumber = minBlock, @@ -252,9 +252,9 @@ private IBlockTree CreateFailingBlockTree(Exception exception) throwingTree.SyncPivot.Returns(realTree.SyncPivot); throwingTree.BestKnownNumber.Returns(realTree.BestKnownNumber); throwingTree - .FindBlock(Arg.Any(), Arg.Any()) + .FindBlock(Arg.Any(), Arg.Any()) .Returns(ci => Interlocked.Increment(ref findCalls) == 1 - ? realTree.FindBlock(ci.ArgAt(0), ci.ArgAt(1)) + ? realTree.FindBlock(ci.ArgAt(0), ci.ArgAt(1)) : throw exception); return throwingTree; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 9bfa84398cab..20ad40d4fe9d 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -191,7 +191,7 @@ private CallOutput RunCall(IStateReader nonceReader, ITransactionProcessor txPro private static bool HasOverrides(Dictionary? stateOverride, UInt256? blobBaseFeeOverride) => stateOverride is { Count: > 0 } || blobBaseFeeOverride is not null; - public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, ISimulateBlockTracerFactory simulateBlockTracerFactory, long gasCapLimit, CancellationToken cancellationToken) + public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, ISimulateBlockTracerFactory simulateBlockTracerFactory, ulong gasCapLimit, CancellationToken cancellationToken) { using SimulateReadOnlyBlocksProcessingScope env = lazySimulateProcessingEnv.Value.Begin(header); env.SimulateRequestState.Validate = payload.Validation; @@ -226,12 +226,12 @@ private CallOutput RunEstimateGas(IStateReader nonceReader, ITransactionProcesso IReleaseSpec spec = specProvider.GetSpec(header.Number + 1, header.Timestamp + blocksConfig.SecondsPerSlot); UInt256 senderBalance = worldState.GetBalance(tx.SenderAddress ?? Address.Zero); UInt256 feeCap = tx.CalculateFeeCap(); - if (feeCap > UInt256.Zero && !UInt256.SubtractUnderflow(senderBalance, tx.Value, out UInt256 availableForGas)) + if (feeCap > UInt256.Zero && !UInt256.SubtractUnderflow(senderBalance, (UInt256)tx.ValueRef, out UInt256 availableForGas)) { if (!BlobGasCalculator.TrySubtractBlobFee(spec, tx, ref availableForGas)) availableForGas = UInt256.Zero; - long allowance = (long)UInt256.Min(availableForGas / feeCap, (UInt256)long.MaxValue); + ulong allowance = (ulong)UInt256.Min(availableForGas / feeCap, (UInt256)ulong.MaxValue); if (tx.GasLimit > allowance) tx.GasLimit = allowance; } @@ -244,7 +244,7 @@ private CallOutput RunEstimateGas(IStateReader nonceReader, ITransactionProcesso string? error = ConstructError(tryCallResult, estimateGasTracer.Error); - long estimate = gasEstimator.Estimate(tx, header, estimateGasTracer, out string? err, errorMargin, cancellationToken); + ulong estimate = gasEstimator.Estimate(tx, header, estimateGasTracer, out string? err, (ulong)errorMargin, cancellationToken); // Allowance errors take precedence over any earlier revert: the revert was an artifact // of the gas cap, so surfacing it instead of the affordability error would be misleading. error = err switch @@ -408,6 +408,8 @@ private TransactionResult CallAndRestore( transaction.SenderAddress ??= Address.Zero; //Ignore nonce on all CallAndRestore calls + // CAST NOTE: GetNonce returns UInt256 (IStateReader interface). Transaction.Nonce is ulong. + // Nonce values beyond ulong.MaxValue are not realistically reachable. transaction.Nonce = nonceReader.GetNonce(blockHeader, transaction.SenderAddress); BlockHeader callHeader = blockHeader.Clone(); @@ -551,14 +553,14 @@ public void RunTreeVisitor(ITreeVisitor treeVisitor, BlockHeader? ba public IEnumerable FindLogs(LogFilter filter, CancellationToken cancellationToken = default) => logFinder.FindLogs(filter, cancellationToken); - public ReadOnlyBlockAccessList? GetBlockAccessList(long blockNumber, Hash256 blockHash) + public ReadOnlyBlockAccessList? GetBlockAccessList(ulong blockNumber, Hash256 blockHash) => balStore.Get(blockNumber, blockHash); - public MemoryManager? GetBlockAccessListRlp(long blockNumber, Hash256 blockHash) + public MemoryManager? GetBlockAccessListRlp(ulong blockNumber, Hash256 blockHash) => balStore.GetRlp(blockNumber, blockHash); // for testing - public void DeleteBlockAccessList(long blockNumber, Hash256 blockHash) + public void DeleteBlockAccessList(ulong blockNumber, Hash256 blockHash) => balStore.Delete(blockNumber, blockHash); private static string? ConstructError(TransactionResult txResult, string? tracerError) diff --git a/src/Nethermind/Nethermind.Facade/CallOutput.cs b/src/Nethermind/Nethermind.Facade/CallOutput.cs index 7f46c85128d1..3b1ab8ee222e 100644 --- a/src/Nethermind/Nethermind.Facade/CallOutput.cs +++ b/src/Nethermind/Nethermind.Facade/CallOutput.cs @@ -11,8 +11,8 @@ public class CallOutput public byte[] OutputData { get; set; } = []; - public long GasSpent { get; set; } - public long OperationGas { get; set; } + public ulong GasSpent { get; set; } + public ulong OperationGas { get; set; } public bool InputError { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs index 690efb0b9ce0..24ba32b96f73 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs @@ -104,8 +104,8 @@ public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider s public Address? Author { get; set; } public UInt256 Difficulty { get; set; } public byte[] ExtraData { get; set; } - public long GasLimit { get; set; } - public long GasUsed { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Hash256? Hash { get; set; } @@ -121,7 +121,7 @@ public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider s public byte[]? Nonce { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public long? Number { get; set; } + public ulong? Number { get; set; } public Hash256 ParentHash { get; set; } public Hash256 ReceiptsRoot { get; set; } public Hash256 Sha3Uncles { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs index 29bf7c52ce32..eed8d955bbc9 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs @@ -70,7 +70,7 @@ public BlockHeaderForRpc(BlockHeader header, ISpecProvider? specProvider = null) public Address? Author { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public long? Number { get; set; } + public ulong? Number { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Hash256? Hash { get; set; } @@ -98,8 +98,8 @@ public BlockHeaderForRpc(BlockHeader header, ISpecProvider? specProvider = null) public UInt256 Difficulty { get; set; } public byte[] ExtraData { get; set; } = []; - public long GasLimit { get; set; } - public long GasUsed { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } public UInt256 Timestamp { get; set; } public Hash256? TransactionsRoot { get; set; } public Hash256? ReceiptsRoot { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Eth/EthSyncingInfo.cs b/src/Nethermind/Nethermind.Facade/Eth/EthSyncingInfo.cs index 8ca2185edd70..c15ebdafdf3d 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/EthSyncingInfo.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/EthSyncingInfo.cs @@ -30,7 +30,7 @@ public class EthSyncingInfo( public SyncingResult GetFullInfo() { - (bool isSyncing, long headNumberOrZero, long bestSuggestedNumber) = _blockTree.IsSyncing(maxDistanceForSynced: MaxDistanceForSynced); + (bool isSyncing, ulong headNumberOrZero, ulong bestSuggestedNumber) = _blockTree.IsSyncing(maxDistanceForSynced: MaxDistanceForSynced); SyncMode syncMode = _syncModeSelector.Current; if (_logger.IsTrace) _logger.Trace($"Start - EthSyncingInfo - BestSuggestedNumber: {bestSuggestedNumber}, HeadNumberOrZero: {headNumberOrZero}, IsSyncing: {isSyncing} {_syncConfig}. LowestInsertedBodyNumber: {_syncPointers.LowestInsertedBodyNumber} LowestInsertedReceiptBlockNumber: {_syncPointers.LowestInsertedReceiptBlockNumber}"); @@ -63,7 +63,7 @@ public SyncingResult GetFullInfo() return SyncingResult.NotSyncing; } - private static SyncingResult ReturnSyncing(long headNumberOrZero, long bestSuggestedNumber, SyncMode syncMode) => new() + private static SyncingResult ReturnSyncing(ulong headNumberOrZero, ulong bestSuggestedNumber, SyncMode syncMode) => new() { CurrentBlock = headNumberOrZero, HighestBlock = bestSuggestedNumber, diff --git a/src/Nethermind/Nethermind.Facade/Eth/IFromTransaction.cs b/src/Nethermind/Nethermind.Facade/Eth/IFromTransaction.cs index 9a7736e16c5a..b249b57755b1 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/IFromTransaction.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/IFromTransaction.cs @@ -17,7 +17,7 @@ public readonly record struct TransactionForRpcContext { public ulong? ChainId { get; } public Hash256? BlockHash { get; } - public long? BlockNumber { get; } + public ulong? BlockNumber { get; } public ulong? BlockTimestamp { get; } public int? TxIndex { get; } public UInt256? BaseFee { get; } @@ -37,7 +37,7 @@ public TransactionForRpcContext(ulong chainId) public TransactionForRpcContext( ulong chainId, Hash256 blockHash, - long blockNumber, + ulong blockNumber, int txIndex, ulong blockTimestamp, UInt256 baseFee, diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AccessListTransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AccessListTransactionForRpc.cs index 31b3fcae6d3d..153796f469b0 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AccessListTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AccessListTransactionForRpc.cs @@ -36,7 +36,7 @@ public AccessListTransactionForRpc(Transaction transaction, in TransactionForRpc V = YParity ?? 0; } - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { Result baseResult = base.ToTransaction(validateUserInput, gasCap, spec); if (baseResult.IsError) return baseResult; diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/BlobTransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/BlobTransactionForRpc.cs index 7c4a1a7ef4c1..47a21e26b832 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/BlobTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/BlobTransactionForRpc.cs @@ -48,7 +48,7 @@ public BlobTransactionForRpc(Transaction transaction, in TransactionForRpcContex } } - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { if (BlobVersionedHashes is null || BlobVersionedHashes.Length == 0) return RpcTransactionErrors.AtLeastOneBlobInBlobTransaction; diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/EIP1559TransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/EIP1559TransactionForRpc.cs index 7f932219ae5d..bdc7eb6cfad5 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/EIP1559TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/EIP1559TransactionForRpc.cs @@ -37,7 +37,7 @@ public EIP1559TransactionForRpc(Transaction transaction, in TransactionForRpcCon : transaction.MaxFeePerGas; } - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { if (validateUserInput) { diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs index 5c88a19f77f4..a35117529a1a 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Text.Json.Serialization; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -20,7 +21,7 @@ public class LegacyTransactionForRpc : TransactionForRpc, ITxTyped, IFromTransac public override TxType? Type => TxType; [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public UInt256? Nonce { get; set; } + public ulong? Nonce { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Address? To { get; set; } @@ -91,7 +92,7 @@ public LegacyTransactionForRpc(Transaction transaction, in TransactionForRpcCont } } - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { if (validateUserInput && To is null && Input is null or { Length: 0 }) return RpcTransactionErrors.ContractCreationWithoutData; @@ -100,7 +101,7 @@ public override Result ToTransaction(bool validateUserInput = false if (baseResult.IsError) return baseResult; Transaction tx = baseResult.Data; - tx.Nonce = Nonce ?? UInt256.Zero; // TODO: Should we pick the last nonce? + tx.Nonce = Nonce ?? 0UL; // TODO: Should we pick the last nonce? tx.To = To; tx.Value = Value ?? UInt256.Zero; tx.Data = Input; @@ -111,10 +112,10 @@ public override Result ToTransaction(bool validateUserInput = false // null Gas → caller didn't specify, default to gasCap (uncapped if gasCap is unset). // explicit Gas (including 0) → use as-is, capped at gasCap. This matches Geth: gas: 0x0 // is a literal request that fails the intrinsic gas check, not a "missing" signal. - long effectiveCap = gasCap is null or 0 ? long.MaxValue : gasCap.Value; + ulong effectiveCap = gasCap is null or 0 ? ulong.MaxValue : gasCap.Value; tx.GasLimit = Gas is null ? effectiveCap - : long.Min(Gas.Value, effectiveCap); + : Math.Min(Gas.Value, effectiveCap); if ((R?.IsZero == false || S?.IsZero == false) && (R is not null || S is not null)) { diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/SetCodeTransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/SetCodeTransactionForRpc.cs index 74e094d7511c..16c618fb688a 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/SetCodeTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/SetCodeTransactionForRpc.cs @@ -22,7 +22,7 @@ public SetCodeTransactionForRpc() { } public SetCodeTransactionForRpc(Transaction transaction, in TransactionForRpcContext extraData) : base(transaction, extraData) => AuthorizationList = AuthorizationListForRpc.FromAuthorizationList(transaction.AuthorizationList); - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { Result baseResult = base.ToTransaction(validateUserInput, gasCap, spec); if (baseResult.IsError) return baseResult; diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/TransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/TransactionForRpc.cs index f43e0f198695..4cd053876fda 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/TransactionForRpc.cs @@ -41,13 +41,13 @@ public abstract class TransactionForRpc public Hash256? BlockHash { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public long? BlockNumber { get; set; } + public ulong? BlockNumber { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public ulong? BlockTimestamp { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public long? Gas { get; set; } + public ulong? Gas { get; set; } // True when type came from a fallback (gasPrice-only or absolute default), not from an // explicit `type` field or a discriminator. Set only during JSON deserialization. @@ -66,7 +66,7 @@ protected TransactionForRpc(Transaction transaction, in TransactionForRpcContext BlockTimestamp = extraData.BlockTimestamp; } - public virtual Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public virtual Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) => new Transaction { Type = ResolveType(spec) }; private TxType ResolveType(IReleaseSpec? spec) diff --git a/src/Nethermind/Nethermind.Facade/Eth/SyncingResult.cs b/src/Nethermind/Nethermind.Facade/Eth/SyncingResult.cs index 1349487fd0ed..a64b3f7af5a1 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/SyncingResult.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/SyncingResult.cs @@ -12,9 +12,9 @@ public struct SyncingResult { public static SyncingResult NotSyncing = new(); public bool IsSyncing { get; set; } - public long StartingBlock { get; set; } - public long CurrentBlock { get; set; } - public long HighestBlock { get; set; } + public ulong StartingBlock { get; set; } + public ulong CurrentBlock { get; set; } + public ulong HighestBlock { get; set; } public SyncMode SyncMode { get; set; } public override readonly string ToString() => $"IsSyncing: {IsSyncing}, StartingBlock: {StartingBlock}, CurrentBlock {CurrentBlock}, HighestBlock {HighestBlock}"; diff --git a/src/Nethermind/Nethermind.Facade/Eth/SyncingResultJsonConverter.cs b/src/Nethermind/Nethermind.Facade/Eth/SyncingResultJsonConverter.cs index b65b7e9fd81d..9ed7559c0e24 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/SyncingResultJsonConverter.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/SyncingResultJsonConverter.cs @@ -35,8 +35,8 @@ public override void Write( private struct Result { - public long StartingBlock { get; set; } - public long CurrentBlock { get; set; } - public long HighestBlock { get; set; } + public ulong StartingBlock { get; set; } + public ulong CurrentBlock { get; set; } + public ulong HighestBlock { get; set; } } } diff --git a/src/Nethermind/Nethermind.Facade/Filters/FilterLog.cs b/src/Nethermind/Nethermind.Facade/Filters/FilterLog.cs index ecf50b5c449e..a7ffbbf0cb1f 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/FilterLog.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/FilterLog.cs @@ -6,11 +6,11 @@ namespace Nethermind.Facade.Filters { - public class FilterLog(long logIndex, long blockNumber, ulong blockTimestamp, Hash256 blockHash, int transactionIndex, Hash256 transactionHash, Address address, byte[] data, Hash256[] topics, bool removed = false) : ILogEntry + public class FilterLog(long logIndex, ulong blockNumber, ulong blockTimestamp, Hash256 blockHash, int transactionIndex, Hash256 transactionHash, Address address, byte[] data, Hash256[] topics, bool removed = false) : ILogEntry { public Address Address { get; } = address; public Hash256 BlockHash { get; } = blockHash; - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; public ulong BlockTimestamp { get; } = blockTimestamp; public byte[] Data { get; } = data; public long LogIndex { get; } = logIndex; diff --git a/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs index 3f898f360640..a43e08d26fbe 100644 --- a/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/ILogIndexBuilder.cs @@ -12,8 +12,8 @@ public interface ILogIndexBuilder : IAsyncDisposable, IStoppableService Task StartAsync(); bool IsRunning { get; } - int MaxTargetBlockNumber { get; } - int MinTargetBlockNumber { get; } + ulong MaxTargetBlockNumber { get; } + ulong MinTargetBlockNumber { get; } DateTimeOffset? LastUpdate { get; } Exception? LastError { get; } diff --git a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs index d2e0795e445b..93ff7f3f7e6e 100644 --- a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using Nethermind.Facade.Filters; using Nethermind.Blockchain.Find; @@ -40,7 +41,9 @@ public override IEnumerable FindLogs(LogFilter filter, BlockHeader fr private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, (int from, int to) indexRange, CancellationToken cancellationToken) { - if (indexRange.from > fromBlock.Number && FindHeaderOrLogError(indexRange.from - 1, cancellationToken) is { } beforeIndex) + // CAST NOTE: indexRange uses int for log-index storage (kept as int for performance). + // Block numbers in the index fit in int (max ~2 billion blocks). + if ((ulong)indexRange.from > fromBlock.Number && FindHeaderOrLogError((ulong)(indexRange.from - 1), cancellationToken) is { } beforeIndex) { foreach (FilterLog log in base.FindLogs(filter, fromBlock, beforeIndex, cancellationToken)) yield return log; @@ -48,7 +51,10 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro cancellationToken.ThrowIfCancellationRequested(); - IEnumerable indexNumbers = _logIndexStorage.EnumerateBlockNumbersFor(filter, indexRange.from, indexRange.to); + // EnumerateBlockNumbersFor returns IEnumerable (log-index contract kept as long for performance). + // Block numbers from the index are non-negative so the cast is safe. + IEnumerable indexNumbers = _logIndexStorage.EnumerateBlockNumbersFor(filter, indexRange.from, indexRange.to) + .Select(static n => (ulong)n); foreach (FilterLog log in FilterLogsInBlocksParallel(filter, indexNumbers, cancellationToken)) { yield return log; @@ -56,7 +62,7 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro cancellationToken.ThrowIfCancellationRequested(); - if (indexRange.to < toBlock.Number && FindHeaderOrLogError(indexRange.to + 1, cancellationToken) is { } afterIndex) + if ((ulong)indexRange.to < toBlock.Number && FindHeaderOrLogError((ulong)(indexRange.to + 1), cancellationToken) is { } afterIndex) { foreach (FilterLog log in base.FindLogs(filter, afterIndex, toBlock, cancellationToken)) yield return log; diff --git a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs index 18bcf8892fe3..c35bfedc951e 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs @@ -85,19 +85,21 @@ public virtual IEnumerable FindLogs(LogFilter filter, BlockHeader fro private static bool ShouldUseBloomDatabase(BlockHeader fromBlock, BlockHeader toBlock) { - long blocksToSearch = toBlock.Number - fromBlock.Number + 1; + ulong blocksToSearch = toBlock.Number - fromBlock.Number + 1; return blocksToSearch > 1; // if we are searching only in 1 block skip bloom index altogether, this can be tweaked } private IEnumerable FilterLogsWithBloomsIndex(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, CancellationToken cancellationToken) { - IEnumerable EnumerateBlockNumbers(LogFilter f, long from, long to) + IEnumerable EnumerateBlockNumbers(LogFilter f, ulong from, ulong to) { + // ContainsRange takes 'in long' — safe cast: block numbers won't exceed long.MaxValue IBloomEnumeration enumeration = _bloomStorage.GetBlooms(from, to); foreach (Bloom bloom in enumeration) { - if (f.Matches(bloom) && enumeration.TryGetBlockNumber(out long blockNumber)) + if (f.Matches(bloom) && enumeration.TryGetBlockNumber(out ulong blockNumber)) { + // TryGetBlockNumber returns long (IBloomEnumeration contract); block numbers are non-negative yield return blockNumber; } } @@ -106,13 +108,13 @@ IEnumerable EnumerateBlockNumbers(LogFilter f, long from, long to) return FilterLogsInBlocksParallel(filter, EnumerateBlockNumbers(filter, fromBlock.Number, toBlock.Number), cancellationToken); } - protected IEnumerable FilterLogsInBlocksParallel(LogFilter filter, IEnumerable blockNumbers, CancellationToken cancellationToken) + protected IEnumerable FilterLogsInBlocksParallel(LogFilter filter, IEnumerable blockNumbers, CancellationToken cancellationToken) { - static IEnumerable ParallelizeWithLock(IEnumerable blocks, bool runParallel, CancellationToken ct) + static IEnumerable ParallelizeWithLock(IEnumerable blocks, bool runParallel, CancellationToken ct) { try { - foreach (long blockNumber in blocks) + foreach (ulong blockNumber in blocks) { yield return blockNumber; ct.ThrowIfCancellationRequested(); @@ -134,7 +136,7 @@ static IEnumerable ParallelizeWithLock(IEnumerable blocks, bool runP int parallelExecutions = Interlocked.Increment(ref ParallelExecutions) - 1; bool canRunParallel = parallelLock == 0; - IEnumerable filterBlocks = ParallelizeWithLock(blockNumbers, canRunParallel, cancellationToken); + IEnumerable filterBlocks = ParallelizeWithLock(blockNumbers, canRunParallel, cancellationToken); if (canRunParallel) { @@ -156,6 +158,7 @@ private bool CanUseBloomDatabase(BlockHeader toBlock, BlockHeader fromBlock) { // method is designed for convenient debugging + // ContainsRange takes 'in long' — block numbers are non-negative so the cast is safe bool containsRange = _bloomStorage.ContainsRange(fromBlock.Number, toBlock.Number); if (!containsRange) { @@ -199,7 +202,7 @@ private IEnumerable FindLogsInBlock(LogFilter filter, BlockHeader blo ? FindLogsInBlock(filter, block.Hash, block.Number, block.Timestamp, cancellationToken) : []; - private IEnumerable FindLogsInBlock(LogFilter filter, Hash256? blockHash, long blockNumber, ulong blockTimestamp, CancellationToken cancellationToken) + private IEnumerable FindLogsInBlock(LogFilter filter, Hash256? blockHash, ulong blockNumber, ulong blockTimestamp, CancellationToken cancellationToken) { if (blockHash is not null) { @@ -271,9 +274,9 @@ private static IEnumerable FilterLogsInBlockLowMemoryAllocation(LogFi return logList ?? (IEnumerable)[]; } - private IEnumerable FilterLogsInBlockHighMemoryAllocation(LogFilter filter, Hash256 blockHash, long blockNumber, ulong blockTimestamp, CancellationToken cancellationToken) + private IEnumerable FilterLogsInBlockHighMemoryAllocation(LogFilter filter, Hash256 blockHash, ulong blockNumber, ulong blockTimestamp, CancellationToken cancellationToken) { - TxReceipt[]? GetReceipts(Hash256 hash, long number) + TxReceipt[]? GetReceipts(Hash256 hash, ulong number) { bool canUseHash = _receiptFinder.CanGetReceiptsByHash(number); if (canUseHash) @@ -338,7 +341,7 @@ void RecoverReceiptsData(Hash256 hash, TxReceipt[] receipts) } } - protected BlockHeader? FindHeaderOrLogError(long blockNumber, CancellationToken token) + protected BlockHeader? FindHeaderOrLogError(ulong blockNumber, CancellationToken token) { token.ThrowIfCancellationRequested(); diff --git a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs index ca92b4f26e72..7410fab5eba7 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs @@ -51,7 +51,7 @@ private struct DirectionStates private readonly CancellationTokenSource _cancellationSource = new(); private CancellationToken CancellationToken => _cancellationSource.Token; - private int MaxReorgDepth => _config.MaxReorgDepth!.Value; + private ulong MaxReorgDepth => (ulong)_config.MaxReorgDepth!.Value; private static readonly TimeSpan NewBlockWaitTimeout = TimeSpan.FromSeconds(5); private readonly ILogIndexStorage _logIndexStorage; @@ -60,8 +60,8 @@ private struct DirectionStates private readonly ILogManager _logManager; private Timer? _progressLoggerTimer; - private readonly TaskCompletionSource _pivotSource = new(RunContinuationsAsynchronously); - private readonly Task _pivotTask; + private readonly TaskCompletionSource _pivotSource = new(RunContinuationsAsynchronously); + private readonly Task _pivotTask; private readonly List _tasks = []; @@ -101,8 +101,10 @@ public LogIndexBuilder(ILogIndexStorage logIndexStorage, ILogIndexConfig config, private void StartProcessing(bool isForward) { - // Do not start backward sync if the target is already reached - if (!isForward && _logIndexStorage.MinBlockNumber <= MinTargetBlockNumber) + // Do not start backward sync if the target is already reached. + // null MinBlockNumber means nothing is indexed yet — do not skip. + // Explicit null-check before ulong widening avoids wrapping a negative int to a huge ulong. + if (!isForward && _logIndexStorage.MinBlockNumber is { } minStored && (ulong)minStored <= MinTargetBlockNumber) { MarkCompleted(false); return; @@ -127,8 +129,10 @@ public async Task StartAsync() _receiptStorage.ReceiptsInserted += OnReceiptsInserted; - TrySetPivot(_logIndexStorage.MaxBlockNumber); - TrySetPivot((int)_blockTree.SyncPivot.BlockNumber); + // Explicit null-pattern before widening: avoids InvalidOperationException on null, + // and prevents a negative int from wrapping to a huge ulong. + TrySetPivot(_logIndexStorage.MaxBlockNumber is { } storedMax ? (ulong)storedMax : null); + TrySetPivot(_blockTree.SyncPivot.BlockNumber); if (!_pivotTask.IsCompleted && _logger.IsInfo) _logger.Info($"{GetLogPrefix()}: waiting for the first block..."); @@ -216,7 +220,7 @@ private void LogProgress() Direction(isForward: true).Progress?.LogProgress(); } - private bool TrySetPivot(int? blockNumber) + private bool TrySetPivot(ulong? blockNumber) { if (blockNumber is not { } number || number is 0) return false; @@ -224,8 +228,10 @@ private bool TrySetPivot(int? blockNumber) if (_pivotSource.Task.IsCompleted) return false; - number = Math.Max(MinTargetBlockNumber, number); - number = Math.Min(MaxTargetBlockNumber, number); + if (number < MinTargetBlockNumber) + number = MinTargetBlockNumber; + if (number > MaxTargetBlockNumber) + number = MaxTargetBlockNumber; if (number is 0) return false; @@ -242,15 +248,22 @@ private bool TrySetPivot(int? blockNumber) private void OnReceiptsInserted(object? sender, ReceiptsEventArgs args) { - int next = (int)args.BlockHeader.Number; + // BlockNumber is now ulong; TrySetPivot already accepts ulong?. + ulong next = args.BlockHeader.Number; if (TrySetPivot(next)) _receiptStorage.ReceiptsInserted -= OnReceiptsInserted; } - public int MaxTargetBlockNumber => (int)Math.Max(_blockTree.BestKnownNumber - MaxReorgDepth, 0); + // CAST NOTE: LogIndexStorage uses int block numbers by design (performance). BestKnownNumber + // is ulong; the subtraction is guarded by Math.Max so the result is always >= 0 and fits in ulong. + public ulong MaxTargetBlockNumber => _blockTree.BestKnownNumber >= MaxReorgDepth + ? _blockTree.BestKnownNumber - MaxReorgDepth + : 0UL; // Block 0 should always be present - public int MinTargetBlockNumber => (int)(_syncConfig.AncientReceiptsBarrierCalc <= 1 ? 0 : _syncConfig.AncientReceiptsBarrierCalc); + public ulong MinTargetBlockNumber => _syncConfig.AncientReceiptsBarrierCalc <= 1 + ? 0UL + : _syncConfig.AncientReceiptsBarrierCalc; public bool IsRunning { get; private set; } public DateTimeOffset? LastUpdate { get; private set; } @@ -324,7 +337,9 @@ private async Task AddReceiptsAsync(LogIndexAggregate aggregate, bool isForward) UpdateProgress(); - if (_logIndexStorage.MinBlockNumber <= MinTargetBlockNumber) + // Cast to int is safe: MinTargetBlockNumber is derived from AncientReceiptsBarrierCalc which + // is a chain config value well within int range. MinBlockNumber is int by LogIndex design. + if (_logIndexStorage.MinBlockNumber <= (int)MinTargetBlockNumber) MarkCompleted(false); } @@ -332,27 +347,29 @@ private async Task DoQueueBlocks(bool isForward) { try { - int pivotNumber = await _pivotTask; + ulong pivotNumber = await _pivotTask; ProcessingQueue queue = Direction(isForward).Queue!; int? next = GetNextBlockNumber(isForward); - if (next is not { } start) + int start; + if (next is not { } startFromStorage) { - if (isForward) - { - start = pivotNumber; - } - else - { - start = pivotNumber - 1; - } + // Cast to int is safe here: LogIndex storage uses int block numbers for performance. + // pivotNumber is bounded by MaxTargetBlockNumber which is derived from BestKnownNumber + // and will not exceed int.MaxValue in practice (~2 billion blocks). + start = isForward ? (int)pivotNumber : (int)pivotNumber - 1; + } + else + { + start = startFromStorage; } BlockReceipts[] buffer = new BlockReceipts[_config.MaxBatchSize]; while (!CancellationToken.IsCancellationRequested) { - if (!isForward && start < MinTargetBlockNumber) + // Cast to int is safe: MinTargetBlockNumber fits in int (see MinTargetBlockNumber property). + if (!isForward && start < (int)MinTargetBlockNumber) { if (_logger.IsTrace) _logger.Trace($"{GetLogPrefix(isForward)}: queued last block"); @@ -362,8 +379,9 @@ private async Task DoQueueBlocks(bool isForward) int batchSize = _config.MaxBatchSize; int end = isForward ? start + batchSize - 1 : start - batchSize + 1; - end = Math.Max(end, MinTargetBlockNumber); - end = Math.Min(end, MaxTargetBlockNumber); + // Cast to int is safe: MinTargetBlockNumber/MaxTargetBlockNumber are bounded within int range for LogIndex. + end = Math.Max(end, (int)MinTargetBlockNumber); + end = Math.Min(end, (int)MaxTargetBlockNumber); // from - inclusive, to - exclusive (int from, int to) = isForward @@ -399,21 +417,39 @@ private async Task DoQueueBlocks(bool isForward) private void UpdateProgress() { if (!_pivotTask.IsCompletedSuccessfully) return; - int pivotNumber = _pivotTask.Result; + ulong pivotNumber = _pivotTask.Result; ref DirectionState forward = ref Direction(isForward: true); if (forward.Progress is { HasEnded: false } forwardProgress) { - forwardProgress.TargetValue = Math.Max(0, _blockTree.BestKnownNumber - MaxReorgDepth - pivotNumber + 1); - forwardProgress.Update(_logIndexStorage.MaxBlockNumber is { } max ? max - pivotNumber + 1 : 0); + ulong bestKnown = _blockTree.BestKnownNumber; + // Guard against underflow: BestKnownNumber - MaxReorgDepth - pivotNumber + 1 + ulong forwardTarget = bestKnown >= MaxReorgDepth + pivotNumber + ? bestKnown - MaxReorgDepth - pivotNumber + 1UL + : 0UL; + forwardProgress.TargetValue = forwardTarget; + // Guard against underflow: storage may not have caught up to pivotNumber yet. + // (ulong)max is safe: LogIndex MaxBlockNumber is a non-negative int by design. + forwardProgress.Update(_logIndexStorage.MaxBlockNumber is { } max && (ulong)max >= pivotNumber + ? (ulong)max - pivotNumber + 1UL + : 0UL); forwardProgress.CurrentQueued = forward.Queue!.QueueCount; } ref DirectionState backward = ref Direction(isForward: false); if (backward.Progress is { HasEnded: false } backwardProgress) { - backwardProgress.TargetValue = pivotNumber - MinTargetBlockNumber; - backwardProgress.Update(_logIndexStorage.MinBlockNumber is { } min ? pivotNumber - min : 0); + // Both pivotNumber and MinTargetBlockNumber are ulong; no cast needed. + // Guard against underflow: MinTargetBlockNumber should never exceed pivotNumber in normal + // operation, but we defend explicitly to avoid wrapping on ulong subtraction. + backwardProgress.TargetValue = pivotNumber >= MinTargetBlockNumber + ? pivotNumber - MinTargetBlockNumber + : 0UL; + // (ulong)min is safe: LogIndex MinBlockNumber is a non-negative int by design. + // Guard against underflow: min should never exceed pivotNumber in normal operation. + backwardProgress.Update(_logIndexStorage.MinBlockNumber is { } min && pivotNumber >= (ulong)min + ? pivotNumber - (ulong)min + : 0UL); backwardProgress.CurrentQueued = backward.Queue!.QueueCount; } } @@ -444,9 +480,11 @@ private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts if (to - from > buffer.Length) throw new InvalidOperationException($"{GetLogPrefix()}: buffer size is too small: {buffer.Length} / {to - from}"); - // Check the immediate next block first + // LogIndex uses int block numbers internally for performance. The checked cast from int to + // ulong is safe here because 'from' and 'to' are always non-negative LogIndex int values + // (bounded by MinTargetBlockNumber / MaxTargetBlockNumber checks in DoQueueBlocks). int nextIndex = isForward ? from : to - 1; - if (!TryGetBlockReceipts(nextIndex, out buffer[0])) + if (!TryGetBlockReceipts((ulong)nextIndex, out buffer[0])) return ReadOnlySpan.Empty; Parallel.For(from, to, new() @@ -456,27 +494,34 @@ private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts }, i => { int bufferIndex = isForward ? i - from : to - 1 - i; + // Cast to ulong is safe: i is a non-negative LogIndex int block number (see above). if (buffer[bufferIndex] == default) - TryGetBlockReceipts(i, out buffer[bufferIndex]); + TryGetBlockReceipts((ulong)i, out buffer[bufferIndex]); }); + // Array.IndexOf returns int; -1 means no default element found (full buffer valid). int endIndex = Array.IndexOf(buffer, default); return endIndex < 0 ? buffer : buffer.AsSpan(..endIndex); } // TODO: move to IReceiptStorage? - private bool TryGetBlockReceipts(int i, out BlockReceipts blockReceipts) + // CAST NOTE: blockNumber is a LogIndex int block number promoted to ulong at the call site. + // LogIndex intentionally keeps int internally for performance; the caller is responsible for + // ensuring the value is non-negative before widening (guaranteed by DoQueueBlocks bounds checks). + private bool TryGetBlockReceipts(ulong blockNumber, out BlockReceipts blockReceipts) { blockReceipts = default; - if (_blockTree.FindBlock(i, BlockTreeLookupOptions.ExcludeTxHashes) is not { Hash: not null } block) + // BlockNumber is now ulong throughout the codebase; no cast needed here. + if (_blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.ExcludeTxHashes) is not { Hash: not null } block) { return false; } if (!block.Header.HasTransactions) { - blockReceipts = new(i, []); + // Cast back to int is safe: blockNumber originates from a LogIndex int (see above). + blockReceipts = new((int)blockNumber, []); return true; } @@ -487,7 +532,8 @@ private bool TryGetBlockReceipts(int i, out BlockReceipts blockReceipts) return false; // block should have transactions but nothing in storage } - blockReceipts = new(i, receipts); + // Cast back to int is safe: blockNumber originates from a LogIndex int (see above). + blockReceipts = new((int)blockNumber, receipts); return true; } diff --git a/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs b/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs index 81eb57f0d5f2..c28c642f4091 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs @@ -17,19 +17,18 @@ public abstract class LogScanner(ILogFinder logFinder, AddressFilter addressF private const int LogScanCutoffChunks = 128; private readonly ILogger _logger = logManager.GetClassLogger(typeof(LogScanner<>)); - public IEnumerable ScanLogs(long headBlockNumber, Predicate shouldStopScanning) + public IEnumerable ScanLogs(ulong headBlockNumber, Predicate shouldStopScanning) { BlockParameter end = new(headBlockNumber); for (int i = 0; i < LogScanCutoffChunks; i++) { bool atGenesis = false; - long startBlockNumber = end.BlockNumber!.Value - LogScanChunkSize; - if (startBlockNumber < 0) - { - atGenesis = true; - startBlockNumber = 0; - } + // headBlockNumber is ulong; chunk arithmetic is safe since we clamp to 0. + ulong startBlockNumber = end.BlockNumber!.Value > LogScanChunkSize + ? end.BlockNumber!.Value - LogScanChunkSize + : 0; + atGenesis = end.BlockNumber!.Value <= LogScanChunkSize; BlockParameter start = new(startBlockNumber); LogFilter logFilter = new(0, start, end, addressFilter, topicsFilter); @@ -60,7 +59,7 @@ public IEnumerable ScanLogs(long headBlockNumber, Predicate shouldStopScan } } - public IEnumerable ScanReceipts(long blockNumber, TxReceipt[] receipts) + public IEnumerable ScanReceipts(ulong blockNumber, TxReceipt[] receipts) { int count = 0; diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index dab0cb999367..e2ed03f23b59 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -31,7 +31,7 @@ public interface IBlockchainBridge : ILogFinder (TxReceipt? Receipt, ulong BlockTimestamp, TxGasInfo? GasInfo, int LogIndexStart) GetTxReceiptInfo(Hash256 txHash); bool TryGetTransaction(Hash256 txHash, [NotNullWhen(true)] out TransactionLookupResult? result, bool checkTxnPool = true); CallOutput Call(BlockHeader header, Transaction tx, Dictionary? stateOverride = null, UInt256? blobBaseFeeOverride = null, CancellationToken cancellationToken = default); - SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, ISimulateBlockTracerFactory simulateBlockTracerFactory, long gasCapLimit, CancellationToken cancellationToken); + SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, ISimulateBlockTracerFactory simulateBlockTracerFactory, ulong gasCapLimit, CancellationToken cancellationToken); CallOutput EstimateGas(BlockHeader header, Transaction tx, int errorMarginBasisPoints, Dictionary? stateOverride = null, UInt256? blobBaseFeeOverride = null, CancellationToken cancellationToken = default); CallOutput CreateAccessList(BlockHeader header, Transaction tx, Dictionary? stateOverride, bool optimize, UInt256? blobBaseFeeOverride = null, CancellationToken cancellationToken = default); @@ -59,8 +59,8 @@ public interface IBlockchainBridge : ILogFinder Witness GenerateExecutionWitness(BlockHeader parent, Block block); Witness GenerateExecutionWitness(BlockHeader header, Transaction tx); - ReadOnlyBlockAccessList? GetBlockAccessList(long blockNumber, Hash256 blockHash); - MemoryManager? GetBlockAccessListRlp(long blockNumber, Hash256 blockHash); - void DeleteBlockAccessList(long blockNumber, Hash256 blockHash); + ReadOnlyBlockAccessList? GetBlockAccessList(ulong blockNumber, Hash256 blockHash); + MemoryManager? GetBlockAccessListRlp(ulong blockNumber, Hash256 blockHash); + void DeleteBlockAccessList(ulong blockNumber, Hash256 blockHash); } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/BlockModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/BlockModel.cs index 610a42a8bdb0..930fcf7f4a6e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/BlockModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/BlockModel.cs @@ -12,13 +12,13 @@ public class BlockModel { public UInt256 Difficulty { get; set; } public byte[] ExtraData { get; set; } - public UInt256 GasLimit { get; set; } - public UInt256 GasUsed { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } public Hash256 Hash { get; set; } public Address Miner { get; set; } public Hash256 MixHash { get; set; } - public UInt256 Nonce { get; set; } - public UInt256 Number { get; set; } + public ulong Nonce { get; set; } + public ulong Number { get; set; } public Hash256 ParentHash { get; set; } public Hash256 ReceiptsRoot { get; set; } public Hash256 Sha3Uncles { get; set; } @@ -34,14 +34,14 @@ public class BlockModel public Block ToBlock() { - Block block = new(new BlockHeader(ParentHash, Sha3Uncles, Miner, Difficulty, (long)Number, - (long)GasLimit, Timestamp, ExtraData)); + Block block = new(new BlockHeader(ParentHash, Sha3Uncles, Miner, Difficulty, Number, + GasLimit, Timestamp, ExtraData)); block.Header.StateRoot = StateRoot; - block.Header.GasUsed = (long)GasUsed; + block.Header.GasUsed = GasUsed; block.Header.Hash = Hash; block.Header.MixHash = MixHash; - block.Header.Nonce = (ulong)Nonce; + block.Header.Nonce = Nonce; block.Header.ReceiptsRoot = ReceiptsRoot; block.Header.TotalDifficulty = TotalDifficulty; block.Header.TxRoot = TransactionsRoot; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs index 6b58d0668223..a679c9e6682c 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs @@ -10,7 +10,7 @@ namespace Nethermind.Facade.Proxy.Models public class TransactionModel { public Hash256 Hash { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public Hash256 BlockHash { get; set; } public UInt256 BlockNumber { get; set; } public Address From { get; set; } @@ -24,13 +24,15 @@ public Transaction ToTransaction() => new() { Hash = Hash, + // CAST NOTE: Nonce/Value/GasPrice/Gas are UInt256 for JSON proxy model compat. + // Actual transaction field values are constrained well within ulong range. Nonce = Nonce, SenderAddress = From, To = To, Data = Input, - Value = Value, - GasLimit = (long)Gas, - GasPrice = GasPrice + Value = (ulong)Value, + GasLimit = (ulong)Gas, + GasPrice = (ulong)GasPrice }; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 8982f8a12c37..2758cee064e8 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -45,7 +45,7 @@ public override void StartNewBlockTrace(Block block) { _txIndex = 0; _logIndex = 0; - _blockNumber = (ulong)block.Number; + _blockNumber = block.Number; _blockTimestamp = block.Timestamp; _isTracingLogs &= !spec.GetSpec(block.Header).IsEip7708Enabled; base.StartNewBlockTrace(block); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockValidationTransactionsExecutor.cs index 90d39db5d858..5c4fea0d6616 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockValidationTransactionsExecutor.cs @@ -33,7 +33,7 @@ public void SetBlockExecutionContext(in BlockExecutionContext blockExecutionCont public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, BlockReceiptsTracer receiptsTracer, CancellationToken token = default) { - long startingGasLeft = simulateState.TotalGasLeft; + ulong startingGasLeft = simulateState.TotalGasLeft; if (!simulateState.Validate) { processingOptions |= ProcessingOptions.ForceProcessing | ProcessingOptions.NoValidation; @@ -42,7 +42,7 @@ public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processing TxReceipt[] result = baseTransactionExecutor.ProcessTransactions(block, processingOptions, receiptsTracer, token); // Many gas calculation not done with skip validation, but needed for response - long currentGasUsedTotal = 0; + ulong currentGasUsedTotal = 0; foreach (TxReceipt txReceipt in result) { currentGasUsedTotal += txReceipt.GasUsed; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index 00f3645aadd0..c29364813341 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -14,9 +14,11 @@ namespace Nethermind.Facade.Simulate; public sealed class SimulateBlockhashProvider(IBlockhashProvider blockhashProvider, IBlockTree blockTree) : IBlockhashProvider { - public Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec spec) + public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) { - long bestKnown = blockTree.BestKnownNumber; + // CAST NOTE: BestKnownNumber is ulong; safe to cast to long for blockhash lookup since + // block numbers reachable by the blockhash opcode are well within long range. + ulong bestKnown = blockTree.BestKnownNumber; return bestKnown < number && blockTree.BestSuggestedHeader is not null ? blockhashProvider.GetBlockhash(blockTree.BestSuggestedHeader!, bestKnown, spec) : blockhashProvider.GetBlockhash(currentBlock, number, spec); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index d9514064caaf..ba1154baf1b7 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -35,7 +35,7 @@ private void PrepareState( BlockStateCall blockStateCall, IWorldState stateProvider, IOverridableCodeInfoRepository codeInfoRepository, - long blockNumber, + ulong blockNumber, IReleaseSpec releaseSpec) { stateProvider.ApplyStateOverridesNoCommit(codeInfoRepository, blockStateCall.StateOverrides, releaseSpec); @@ -56,7 +56,7 @@ public SimulateOutput TrySimulate( SimulatePayload payload, IBlockTracer tracer, SimulateReadOnlyBlocksProcessingScope env, - long gasCapLimit, + ulong gasCapLimit, CancellationToken cancellationToken) { List> list = []; @@ -97,7 +97,7 @@ private void Simulate(BlockHeader parent, IBlockTracer tracer, SimulateReadOnlyBlocksProcessingScope env, List> output, - long gasCapLimit, + ulong gasCapLimit, CancellationToken cancellationToken) { IBlockTree blockTree = env.BlockTree; @@ -187,7 +187,7 @@ private BlockBody AssembleBody( private static BlockHeader GetParent(BlockHeader parent, SimulatePayload payload, IBlockTree blockTree) { Block? latestBlock = blockTree.FindLatestBlock(); - long latestBlockNumber = latestBlock?.Number ?? 0; + ulong latestBlockNumber = latestBlock?.Number ?? 0; if (latestBlockNumber < parent.Number) { @@ -196,10 +196,11 @@ private static BlockHeader GetParent(BlockHeader parent, SimulatePayload? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); - ulong lastKnown = (ulong)latestBlockNumber; + ulong lastKnown = latestBlockNumber; if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock.BlockOverrides?.Number < lastKnown) { - Block? searchResult = blockTree.FindBlock((long)firstBlock.BlockOverrides.Number - 1); + // CAST NOTE: firstBlock.BlockOverrides.Number is ulong and > 0, so subtracting 1 is safe. + Block? searchResult = blockTree.FindBlock(firstBlock.BlockOverrides.Number.Value - 1); if (searchResult is not null) { parent = searchResult.Header; @@ -224,7 +225,7 @@ private Transaction CreateTransaction( { if (stateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) { - cachedNonce = test.Nonce.ToUInt64(null); + cachedNonce = test.Nonce; // AccountStruct.Nonce is ulong } // else // Todo think if we shall create account here } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs index a4b0be4b9dbc..8b37a7341008 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs @@ -12,7 +12,7 @@ namespace Nethermind.Facade.Simulate; public class SimulateDictionaryBlockStore(IBlockStore readonlyBaseBlockStore) : IBlockStore { private readonly Dictionary _blockDict = []; - private readonly Dictionary _blockNumDict = []; + private readonly Dictionary _blockNumDict = []; private readonly BlockDecoder _blockDecoder = new(); public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) @@ -21,13 +21,13 @@ public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) _blockNumDict[block.Number] = block; } - public void Delete(long blockNumber, Hash256 blockHash) + public void Delete(ulong blockNumber, Hash256 blockHash) { _blockDict.Remove(blockHash); _blockNumDict.Remove(blockNumber); } - public Block? Get(long blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) + public Block? Get(ulong blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) { if (_blockNumDict.TryGetValue(blockNumber, out Block block)) { @@ -42,7 +42,7 @@ public void Delete(long blockNumber, Hash256 blockHash) return block; } - public byte[]? GetRlp(long blockNumber, Hash256 blockHash) + public byte[]? GetRlp(ulong blockNumber, Hash256 blockHash) { if (_blockNumDict.TryGetValue(blockNumber, out Block block)) { @@ -52,7 +52,7 @@ public void Delete(long blockNumber, Hash256 blockHash) return readonlyBaseBlockStore.GetRlp(blockNumber, blockHash); } - public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash) => + public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(ulong blockNumber, Hash256 blockHash) => _blockNumDict.TryGetValue(blockNumber, out Block block) ? new ReceiptRecoveryBlock(block) : readonlyBaseBlockStore.GetReceiptRecoveryBlock(blockNumber, blockHash); @@ -60,6 +60,6 @@ public void Delete(long blockNumber, Hash256 blockHash) public void Cache(Block block) => Insert(block); - public bool HasBlock(long blockNumber, Hash256 blockHash) + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => _blockNumDict.ContainsKey(blockNumber); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs index d4c87903e03a..7afa2f8bb431 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs @@ -19,7 +19,7 @@ namespace Nethermind.Facade.Simulate; public class SimulateDictionaryHeaderStore(IHeaderStore readonlyBaseHeaderStore) : IHeaderStore { private readonly Dictionary _headerDict = []; - private readonly Dictionary _blockNumberDict = []; + private readonly Dictionary _blockNumberDict = []; public void Insert(BlockHeader header) { @@ -35,7 +35,7 @@ public void BulkInsert(IReadOnlyList headers) } } - public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, long? blockNumber = null) + public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, ulong? blockNumber = null) { if (_headerDict.TryGetValue(blockHash, out BlockHeader? header)) { @@ -60,12 +60,12 @@ public void Delete(Hash256 blockHash) _blockNumberDict.Remove(blockHash); } - public void InsertBlockNumber(Hash256 blockHash, long blockNumber) => _blockNumberDict[blockHash] = blockNumber; + public void InsertBlockNumber(Hash256 blockHash, ulong blockNumber) => _blockNumberDict[blockHash] = blockNumber; - public long? GetBlockNumber(Hash256 blockHash) => - _blockNumberDict.TryGetValue(blockHash, out long blockNumber) ? blockNumber : readonlyBaseHeaderStore.GetBlockNumber(blockHash); + public ulong? GetBlockNumber(Hash256 blockHash) => + _blockNumberDict.TryGetValue(blockHash, out ulong blockNumber) ? blockNumber : readonlyBaseHeaderStore.GetBlockNumber(blockHash); - public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, Hash256 endBlockHash, int count) + public IOwnedReadOnlyList FindReversedHeaders(ulong endBlockNumber, Hash256 endBlockHash, int count) { BlockHeader? cursor = Get(endBlockHash, shouldCache: false, blockNumber: endBlockNumber); if (cursor is null) return ArrayPoolList.Empty(); @@ -73,7 +73,9 @@ public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, ArrayPoolList result = new(count) { cursor }; while (result.Count < count && cursor.ParentHash is not null) { - cursor = Get(cursor.ParentHash, shouldCache: false, blockNumber: cursor.Number - 1); + // Safe subtraction: block 0 has no parent, so cursor.Number > 0 here + ulong parentNumber = cursor.Number > 0 ? cursor.Number - 1 : 0; + cursor = Get(cursor.ParentHash, shouldCache: false, blockNumber: parentNumber); if (cursor is null) break; result.Add(cursor); } @@ -82,5 +84,5 @@ public IOwnedReadOnlyList FindReversedHeaders(long endBlockNumber, return result; } - public BlockHeader? Get(Hash256 blockHash, long? blockNumber = null) => Get(blockHash, true, blockNumber); + public BlockHeader? Get(Hash256 blockHash, ulong? blockNumber = null) => Get(blockHash, true, blockNumber); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateRequestState.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateRequestState.cs index b7d4cf39f4ad..42dd449d48bf 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateRequestState.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateRequestState.cs @@ -9,7 +9,7 @@ public class SimulateRequestState : IBlobBaseFeeOverrideProvider { public bool Validate { get; set; } public UInt256? BlobBaseFeeOverride { get; set; } - public long TotalGasLeft { get; set; } - public long BlockGasLeft { get; set; } + public ulong TotalGasLeft { get; set; } + public ulong BlockGasLeft { get; set; } public bool[] TxsWithExplicitGas { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessorAdapter.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessorAdapter.cs index 1d7cac6467dc..e29bb5c96693 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessorAdapter.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessorAdapter.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Crypto; using Nethermind.Evm; @@ -17,7 +18,7 @@ public TransactionResult Execute(Transaction transaction, ITxTracer txTracer) // The gas limit per tx go down as the block is processed. if (!simulateRequestState.TxsWithExplicitGas[_currentTxIndex]) { - transaction.GasLimit = long.Min(simulateRequestState.BlockGasLeft, simulateRequestState.TotalGasLeft); + transaction.GasLimit = Math.Min(simulateRequestState.BlockGasLeft, simulateRequestState.TotalGasLeft); } if (simulateRequestState.TotalGasLeft < transaction.GasLimit) @@ -29,7 +30,7 @@ public TransactionResult Execute(Transaction transaction, ITxTracer txTracer) TransactionResult result = simulateRequestState.Validate ? transactionProcessor.Execute(transaction, txTracer) : transactionProcessor.Trace(transaction, txTracer); // Keep track of gas left - long blockGasUsed = transaction.BlockGasUsed; + ulong blockGasUsed = transaction.BlockGasUsed; simulateRequestState.TotalGasLeft -= blockGasUsed; simulateRequestState.BlockGasLeft -= blockGasUsed; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 0914256f87d5..9c13a9c24dbd 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -52,7 +52,7 @@ public SimulateTxTracer( public int LogCount => _logs.Count; public SimulateCallResult? TraceResult { get; set; } - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); if (!_isTracingTransfers) return; @@ -81,8 +81,8 @@ public override void ReportLog(LogEntry log) public override void MarkAsSuccess(Address recipient, in GasConsumed gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) => TraceResult = new SimulateCallResult { - GasUsed = (ulong)gasSpent.SpentGas, - MaxUsedGas = (ulong)gasSpent.EffectiveMaxUsedGas, + GasUsed = gasSpent.SpentGas, + MaxUsedGas = gasSpent.EffectiveMaxUsedGas, ReturnData = output, Status = StatusCode.Success, Logs = _logs.Select((entry, i) => new Log @@ -101,8 +101,8 @@ public override void ReportLog(LogEntry log) public override void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] output, string? error, Hash256? stateRoot = null) => TraceResult = new SimulateCallResult { - GasUsed = (ulong)gasSpent.SpentGas, - MaxUsedGas = (ulong)gasSpent.EffectiveMaxUsedGas, + GasUsed = gasSpent.SpentGas, + MaxUsedGas = gasSpent.EffectiveMaxUsedGas, Error = new Error { Message = error is TransactionSubstate.Revert ? "execution reverted" : "execution reverted: " + error, diff --git a/src/Nethermind/Nethermind.Flashbots/Data/BidTrace.cs b/src/Nethermind/Nethermind.Flashbots/Data/BidTrace.cs index b8bc7cc64d50..b9b37c360ca8 100644 --- a/src/Nethermind/Nethermind.Flashbots/Data/BidTrace.cs +++ b/src/Nethermind/Nethermind.Flashbots/Data/BidTrace.cs @@ -17,8 +17,8 @@ public class BidTrace( PublicKey builderPublicKey, PublicKey proposerPublicKey, Address proposerFeeRecipient, - long gasLimit, - long gasUsed, + ulong gasLimit, + ulong gasUsed, UInt256 value) { [JsonPropertyName("slot")] @@ -42,10 +42,10 @@ public class BidTrace( public Address ProposerFeeRecipient { get; set; } = proposerFeeRecipient; [JsonPropertyName("gas_limit")] - public long GasLimit { get; set; } = gasLimit; + public ulong GasLimit { get; set; } = gasLimit; [JsonPropertyName("gas_used")] - public long GasUsed { get; set; } = gasUsed; + public ulong GasUsed { get; set; } = gasUsed; [JsonPropertyName("value")] public UInt256 Value { get; set; } = value; diff --git a/src/Nethermind/Nethermind.Flashbots/Data/BuilderBlockValidationRequest.cs b/src/Nethermind/Nethermind.Flashbots/Data/BuilderBlockValidationRequest.cs index ef95488f4653..807906523328 100644 --- a/src/Nethermind/Nethermind.Flashbots/Data/BuilderBlockValidationRequest.cs +++ b/src/Nethermind/Nethermind.Flashbots/Data/BuilderBlockValidationRequest.cs @@ -12,7 +12,7 @@ public class BuilderBlockValidationRequest( RExecutionPayloadV3 executionPayload, BlobsBundleV1 blobsBundle, byte[] signature, - long registeredGasLimit, + ulong registeredGasLimit, Hash256 parentBeaconBlockRoot) { [JsonRequired] @@ -32,7 +32,7 @@ public class BuilderBlockValidationRequest( [JsonRequired] [JsonPropertyName("registered_gas_limit")] - public long RegisteredGasLimit { get; set; } = registeredGasLimit; + public ulong RegisteredGasLimit { get; set; } = registeredGasLimit; /// /// The block hash of the parent beacon block. diff --git a/src/Nethermind/Nethermind.Flashbots/Data/RExecutionPayloadV3.cs b/src/Nethermind/Nethermind.Flashbots/Data/RExecutionPayloadV3.cs index 4d63ea6527da..f4513ab40d0d 100644 --- a/src/Nethermind/Nethermind.Flashbots/Data/RExecutionPayloadV3.cs +++ b/src/Nethermind/Nethermind.Flashbots/Data/RExecutionPayloadV3.cs @@ -16,9 +16,9 @@ public class RExecutionPayloadV3 public Hash256 receipts_root { get; set; } public Bloom logs_bloom { get; set; } public Hash256 prev_randao { get; set; } - public long block_number { get; set; } - public long gas_limit { get; set; } - public long gas_used { get; set; } + public ulong block_number { get; set; } + public ulong gas_limit { get; set; } + public ulong gas_used { get; set; } public ulong timestamp { get; set; } public byte[] extra_data { get; set; } public UInt256 base_fee_per_gas { get; set; } @@ -78,9 +78,9 @@ public RExecutionPayloadV3( Hash256 receipts_root, Bloom logs_bloom, Hash256 prev_randao, - long block_number, - long gas_limit, - long gas_used, + ulong block_number, + ulong gas_limit, + ulong gas_used, ulong timestamp, byte[] extra_data, UInt256 base_fee_per_gas, diff --git a/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs b/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs index 4d6e4ed9bcbd..9e86c5d537bc 100644 --- a/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs +++ b/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs @@ -91,7 +91,7 @@ public Task> ValidateSubmission(BuilderBlockValid return FlashbotsResult.Valid(); } - private bool ValidateBlock(Block block, BidTrace message, long registeredGasLimit, IReleaseSpec releaseSpec, out string? error) + private bool ValidateBlock(Block block, BidTrace message, ulong registeredGasLimit, IReleaseSpec releaseSpec, out string? error) { error = null; @@ -178,7 +178,7 @@ private bool ValidateBlobsBundle(Transaction[] transactions, BlobsBundleV1 blobs return true; } - private bool ValidatePayload(Block block, Address feeRecipient, UInt256 expectedProfit, long registerGasLimit, bool useBalanceDiffProfit, bool excludeWithdrawals, IReleaseSpec releaseSpec, out string? error) + private bool ValidatePayload(Block block, Address feeRecipient, UInt256 expectedProfit, ulong registerGasLimit, bool useBalanceDiffProfit, bool excludeWithdrawals, IReleaseSpec releaseSpec, out string? error) { BlockHeader? parentHeader = _blockTree.FindHeader(block.ParentHash!, BlockTreeLookupOptions.DoNotCreateLevelIfMissing); @@ -256,7 +256,7 @@ private void RecoverSenderAddress(Block block, IReleaseSpec spec) } } - private bool ValidateBlockMetadata(Block block, long registerGasLimit, BlockHeader parentHeader, IReleaseSpec releaseSpec, out string? error) + private bool ValidateBlockMetadata(Block block, ulong registerGasLimit, BlockHeader parentHeader, IReleaseSpec releaseSpec, out string? error) { if (!_headerValidator.Validate(block.Header, parentHeader, false, out error)) { @@ -275,7 +275,7 @@ private bool ValidateBlockMetadata(Block block, long registerGasLimit, BlockHead return false; } - long calculatedGasLimit = GetGasLimit(parentHeader, registerGasLimit, releaseSpec); + ulong calculatedGasLimit = GetGasLimit(parentHeader, registerGasLimit, releaseSpec); if (calculatedGasLimit != block.Header.GasLimit) { @@ -286,20 +286,26 @@ private bool ValidateBlockMetadata(Block block, long registerGasLimit, BlockHead return true; } - private long GetGasLimit(BlockHeader parentHeader, long desiredGasLimit, IReleaseSpec releaseSpec) + private ulong GetGasLimit(BlockHeader parentHeader, ulong desiredGasLimit, IReleaseSpec releaseSpec) { - long parentGasLimit = parentHeader.GasLimit; - long gasLimit = parentGasLimit; + ulong parentGasLimit = parentHeader.GasLimit; + ulong gasLimit = parentGasLimit; + ulong newBlockNumber = parentHeader.Number + 1; - long? targetGasLimit = desiredGasLimit; - long newBlockNumber = parentHeader.Number + 1; + // Non-trivial: GasLimitBoundDivisor is a positive ulong; dividing a ulong by it is safe. + // The subtraction `/ divisor - 1` could underflow if parentGasLimit < divisor, hence + // the Math.Max(0, ...) guard — replicated here using ulong-safe clamping. + ulong rawDiff = parentGasLimit / releaseSpec.GasLimitBoundDivisor; + ulong maxGasLimitDifference = rawDiff > 0 ? rawDiff - 1 : 0; - if (targetGasLimit is not null) + if (desiredGasLimit > parentGasLimit) { - long maxGasLimitDifference = Math.Max(0, parentGasLimit / releaseSpec.GasLimitBoundDivisor - 1); - gasLimit = targetGasLimit.Value > parentGasLimit - ? parentGasLimit + Math.Min(targetGasLimit.Value - parentGasLimit, maxGasLimitDifference) - : parentGasLimit - Math.Min(parentGasLimit - targetGasLimit.Value, maxGasLimitDifference); + gasLimit = parentGasLimit + Math.Min(desiredGasLimit - parentGasLimit, maxGasLimitDifference); + } + else if (desiredGasLimit < parentGasLimit) + { + // Non-trivial: parentGasLimit - desiredGasLimit is safe (parentGasLimit > desiredGasLimit here). + gasLimit = parentGasLimit - Math.Min(parentGasLimit - desiredGasLimit, maxGasLimitDifference); } gasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(releaseSpec, gasLimit, newBlockNumber); @@ -383,7 +389,6 @@ private bool ValidateProcessedBlock(Block processedBlock, Address feeRecipient, return false; } - error = null; return true; } diff --git a/src/Nethermind/Nethermind.Flashbots/Modules/Rbuilder/IRbuilderRpcModule.cs b/src/Nethermind/Nethermind.Flashbots/Modules/Rbuilder/IRbuilderRpcModule.cs index 65ca1c98c057..b9f841d7b6d4 100644 --- a/src/Nethermind/Nethermind.Flashbots/Modules/Rbuilder/IRbuilderRpcModule.cs +++ b/src/Nethermind/Nethermind.Flashbots/Modules/Rbuilder/IRbuilderRpcModule.cs @@ -45,7 +45,7 @@ ResultWrapper rbuilder_calculateStateRoot(BlockParameter block, public class AccountChange { [JsonPropertyName("nonce")] - public UInt256? Nonce { get; set; } + public ulong? Nonce { get; set; } [JsonPropertyName("balance")] public UInt256? Balance { get; set; } diff --git a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs index be520e9bd274..ef8c95e4a51a 100644 --- a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs +++ b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs @@ -48,7 +48,7 @@ public void CheckHealth_returns_expected_results([ValueSource(nameof(CheckHealth drive.TotalSize.Returns((long)(_freeSpaceBytes * 100.0 / test.AvailableDiskSpacePercent)); drive.RootDirectory.FullName.Returns("C:/"); - static BlockHeaderBuilder GetBlockHeader(int blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); + static BlockHeaderBuilder GetBlockHeader(ulong blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); blockFinder.Head.Returns(new Block(GetBlockHeader(4).TestObject)); if (test.IsSyncing) { @@ -87,7 +87,7 @@ public void post_merge_health_checks([ValueSource(nameof(CheckHealthPostMergeTes drive.TotalSize.Returns((long)(_freeSpaceBytes * 100.0 / test.AvailableDiskSpacePercent)); drive.RootDirectory.FullName.Returns("C:/"); - static BlockHeaderBuilder GetBlockHeader(int blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); + static BlockHeaderBuilder GetBlockHeader(ulong blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); blockFinder.Head.Returns(new Block(GetBlockHeader(4).WithDifficulty(0).TestObject)); if (test.IsSyncing) diff --git a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs index f9c385c00759..5debe34cf3fc 100644 --- a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs +++ b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs @@ -31,7 +31,7 @@ namespace Nethermind.History.Test; public class HistoryPrunerTests { private const long SecondsPerSlot = 1; - private const long BeaconGenesisBlockNumber = 50; + private const ulong BeaconGenesisBlockNumber = 50; private static readonly IBlocksConfig BlocksConfig = new BlocksConfig() { SecondsPerSlot = SecondsPerSlot @@ -174,9 +174,9 @@ public async Task Prunes_history( for (int i = 1; i <= blocks; i++) { if (i < expectedPruneBelow) - CheckBlockPruned(testBlockchain, blockHashes, i); + CheckBlockPruned(testBlockchain, blockHashes, (ulong)i); else - CheckBlockPreserved(testBlockchain, blockHashes, i); + CheckBlockPreserved(testBlockchain, blockHashes, (ulong)i); } CheckHeadPreserved(testBlockchain, blocks); @@ -229,7 +229,7 @@ public async Task Does_not_prune_when_disabled() for (int i = 1; i <= blocks; i++) { - CheckBlockPreserved(testBlockchain, blockHashes, i); + CheckBlockPreserved(testBlockchain, blockHashes, (ulong)i); } CheckHeadPreserved(testBlockchain, blocks); @@ -327,14 +327,14 @@ private static void CheckGenesisPreserved(BasicTestBlockchain testBlockchain, Ha { using (Assert.EnterMultipleScope()) { - Assert.That(testBlockchain.BlockTree.FindBlock(0, BlockTreeLookupOptions.None), Is.Not.Null, "Genesis block should still exist"); - Assert.That(testBlockchain.BlockTree.FindHeader(0, BlockTreeLookupOptions.None), Is.Not.Null, "Genesis block header should still exist"); - Assert.That(testBlockchain.BlockTree.FindCanonicalBlockInfo(0), Is.Not.Null, "Genesis block info should still exist"); - Assert.That(testBlockchain.ReceiptStorage.HasBlock(0, genesisHash), Is.True, "Genesis block receipt should still exist"); + Assert.That(testBlockchain.BlockTree.FindBlock(0UL, BlockTreeLookupOptions.None), Is.Not.Null, "Genesis block should still exist"); + Assert.That(testBlockchain.BlockTree.FindHeader(0UL, BlockTreeLookupOptions.None), Is.Not.Null, "Genesis block header should still exist"); + Assert.That(testBlockchain.BlockTree.FindCanonicalBlockInfo(0UL), Is.Not.Null, "Genesis block info should still exist"); + Assert.That(testBlockchain.ReceiptStorage.HasBlock(0UL, genesisHash), Is.True, "Genesis block receipt should still exist"); } } - private static void CheckHeadPreserved(BasicTestBlockchain testBlockchain, long headNumber) + private static void CheckHeadPreserved(BasicTestBlockchain testBlockchain, ulong headNumber) { using (Assert.EnterMultipleScope()) { @@ -343,23 +343,23 @@ private static void CheckHeadPreserved(BasicTestBlockchain testBlockchain, long } } - private static void CheckBlockPreserved(BasicTestBlockchain testBlockchain, List blockHashes, int blockNumber) + private static void CheckBlockPreserved(BasicTestBlockchain testBlockchain, List blockHashes, ulong blockNumber) { using (Assert.EnterMultipleScope()) { Assert.That(testBlockchain.BlockTree.FindBlock(blockNumber, BlockTreeLookupOptions.None), Is.Not.Null, $"Block {blockNumber} should still exist"); Assert.That(testBlockchain.BlockTree.FindHeader(blockNumber, BlockTreeLookupOptions.None), Is.Not.Null, $"Header {blockNumber} should still exist"); Assert.That(testBlockchain.BlockTree.FindCanonicalBlockInfo(blockNumber), Is.Not.Null, $"Block info {blockNumber} should still exist"); - Assert.That(testBlockchain.ReceiptStorage.HasBlock(blockNumber, blockHashes[blockNumber]), Is.True, $"Receipt for block {blockNumber} should still exist"); + Assert.That(testBlockchain.ReceiptStorage.HasBlock(blockNumber, blockHashes[(int)blockNumber]), Is.True, $"Receipt for block {blockNumber} should still exist"); } } - private static void CheckBlockPruned(BasicTestBlockchain testBlockchain, List blockHashes, int blockNumber) + private static void CheckBlockPruned(BasicTestBlockchain testBlockchain, List blockHashes, ulong blockNumber) { using (Assert.EnterMultipleScope()) { Assert.That(testBlockchain.BlockTree.FindBlock(blockNumber, BlockTreeLookupOptions.None), Is.Null, $"Block {blockNumber} should be pruned"); - Assert.That(testBlockchain.ReceiptStorage.HasBlock(blockNumber, blockHashes[blockNumber]), Is.False, $"Receipt for block {blockNumber} should be pruned"); + Assert.That(testBlockchain.ReceiptStorage.HasBlock(blockNumber, blockHashes[(int)blockNumber]), Is.False, $"Receipt for block {blockNumber} should be pruned"); // should still be preserved Assert.That(testBlockchain.BlockTree.FindHeader(blockNumber, BlockTreeLookupOptions.None), Is.Not.Null, $"Header {blockNumber} should still exist"); @@ -392,7 +392,7 @@ private static async Task CreateBlockchainWithBlocks( blockHashes?.Add(bc.BlockTree.Head!.Hash!); } if (syncPivot is { } pivot) - bc.BlockTree.SyncPivot = (pivot, Hash256.Zero); + bc.BlockTree.SyncPivot = ((ulong)pivot, Hash256.Zero); return bc; } diff --git a/src/Nethermind/Nethermind.History/HistoryPruner.cs b/src/Nethermind/Nethermind.History/HistoryPruner.cs index 40e773d35b44..cbb861c855d1 100644 --- a/src/Nethermind/Nethermind.History/HistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/HistoryPruner.cs @@ -40,17 +40,19 @@ public class HistoryPruner : IHistoryPruner private readonly IBackgroundTaskScheduler _backgroundTaskScheduler; private readonly IHistoryConfig _historyConfig; private readonly bool _enabled; - private readonly long _pruningInterval; + private readonly ulong _pruningInterval; + // MinHistoryRetentionEpochs / MinBalRetentionEpochs come from IReleaseSpec which still returns long. private readonly long _minHistoryRetentionEpochs; private readonly long _minBalRetentionEpochs; - private readonly int _deletionProgressLoggingInterval; - private readonly long _ancientBarrier; - private readonly long _minDeletableBlockNumber; - - private long _blocksDeletePointer = 1; - private long _balsDeletePointer = 1; - private long _lastSavedBlocksDeletePointer = 1; - private long _lastSavedBalsDeletePointer = 1; + private readonly ulong _ancientBarrier; + private readonly ulong _minDeletableBlockNumber; + + private ulong _blocksDeletePointer = 1; + private ulong _balsDeletePointer = 1; + private ulong _lastSavedBlocksDeletePointer = 1; + // ulong.MaxValue is used as a sentinel meaning "never persisted yet", + // forcing a save on the first call to SaveDeletePointers after load. + private ulong _lastSavedBalsDeletePointer = 1; private BlockHeader? _oldestBlockHeader; private bool _hasLoadedDeletePointers; private int _currentlyPruning; @@ -85,7 +87,8 @@ public HistoryPruner( _backgroundTaskScheduler = backgroundTaskScheduler; _historyConfig = historyConfig; _enabled = historyConfig.Enabled(); - _pruningInterval = historyConfig.PruningInterval * SlotsPerEpoch; + // PruningInterval is uint, SlotsPerEpoch is int; promote both to ulong before multiply. + _pruningInterval = (ulong)historyConfig.PruningInterval * (ulong)SlotsPerEpoch; _minHistoryRetentionEpochs = specProvider.GenesisSpec.MinHistoryRetentionEpochs; _minBalRetentionEpochs = specProvider.GenesisSpec.MinBalRetentionEpochs; _minDeletableBlockNumber = (_blockTree.Genesis?.Number ?? 0) + 1; // do not remove genesis @@ -96,7 +99,7 @@ public HistoryPruner( { if (historyConfig.Pruning == PruningModes.UseAncientBarriers) { - _ancientBarrier = long.Min(syncConfig.AncientBodiesBarrierCalc, syncConfig.AncientReceiptsBarrierCalc); + _ancientBarrier = ulong.Min(syncConfig.AncientBodiesBarrierCalc, syncConfig.AncientReceiptsBarrierCalc); } Metrics.PruningCutoffBlocknumber = CutoffBlockNumber; Metrics.BlockAccessListPruningCutoffBlocknumber = BalCutoffBlockNumber; @@ -105,7 +108,9 @@ public HistoryPruner( } } - public long? CutoffBlockNumber + // ── Public API ──────────────────────────────────────────────────────────── + + public ulong? CutoffBlockNumber { get { @@ -120,9 +125,9 @@ public long? CutoffBlockNumber } } - public long? BalCutoffBlockNumber => _enabled ? CalculateRollingCutoff(_historyConfig.BalRetentionEpochs) : null; + public ulong? BalCutoffBlockNumber => _enabled ? CalculateRollingCutoff(_historyConfig.BalRetentionEpochs) : null; - internal long BalsDeletePointer => _balsDeletePointer; + internal ulong BalsDeletePointer => _balsDeletePointer; public BlockHeader? OldestBlockHeader { @@ -161,16 +166,18 @@ public BlockHeader? OldestBlockHeader } } - private long? CalculateRollingCutoff(uint retentionEpochs) + // ── Internal helpers ────────────────────────────────────────────────────── + + private ulong? CalculateRollingCutoff(uint retentionEpochs) { - long? head = _blockTree.Head?.Number; + ulong? head = _blockTree.Head?.Number; if (head is null) { return null; } - long blocksToRetain = (long)retentionEpochs * SlotsPerEpoch; - return long.Max(head.Value - blocksToRetain, 0); + ulong blocksToRetain = retentionEpochs * SlotsPerEpoch; + return ulong.Max(head.Value - blocksToRetain, 0); } private void OnBlockProcessorQueueEmpty(object? sender, EventArgs e) @@ -248,19 +255,20 @@ internal void TryPruneHistory(CancellationToken cancellationToken) return; } - long? blockCutoff = CutoffBlockNumber; - long? balCutoff = BalCutoffBlockNumber; + ulong? blockCutoff = CutoffBlockNumber; + ulong? balCutoff = BalCutoffBlockNumber; Metrics.PruningCutoffBlocknumber = blockCutoff; Metrics.BlockAccessListPruningCutoffBlocknumber = balCutoff; - long syncPivot = _blockTree.SyncPivot.BlockNumber; - long blockUpper = blockCutoff is null ? _blocksDeletePointer : long.Min(blockCutoff.Value, syncPivot); - long balUpper = balCutoff is null ? _balsDeletePointer : long.Min(balCutoff.Value, syncPivot); + ulong syncPivot = _blockTree.SyncPivot.BlockNumber; + ulong blockUpper = blockCutoff is null ? _blocksDeletePointer : ulong.Min(blockCutoff.Value, syncPivot); + ulong balUpper = balCutoff is null ? _balsDeletePointer : ulong.Min(balCutoff.Value, syncPivot); if (_logger.IsInfo) { - long blocksRemaining = long.Max(0, blockUpper - _blocksDeletePointer); - long balsRemaining = long.Max(0, balUpper - _balsDeletePointer); + // Guarded subtractions: avoid underflow if pointer is ahead of upper bound. + ulong blocksRemaining = blockUpper > _blocksDeletePointer ? blockUpper - _blocksDeletePointer : 0; + ulong balsRemaining = balUpper > _balsDeletePointer ? balUpper - _balsDeletePointer : 0; _logger.Info($"Pruning historical blocks up to #{blockUpper} ({blocksRemaining} estimated) and block access lists up to #{balUpper} ({balsRemaining} estimated)."); } @@ -291,7 +299,11 @@ void SkipLocalPruning() internal bool SetDeletePointerToOldestBlock() { - long? oldestBlockNumber = BlockTree.BinarySearchBlockNumber(_minDeletableBlockNumber, _blockTree.SyncPivot.BlockNumber, BlockExists, BlockTree.BinarySearchDirection.Down); + ulong? oldestBlockNumber = BlockTree.BinarySearchBlockNumber( + _minDeletableBlockNumber, + _blockTree.SyncPivot.BlockNumber, + BlockExists, + BlockTree.BinarySearchDirection.Down); if (oldestBlockNumber is not null) { @@ -303,7 +315,11 @@ internal bool SetDeletePointerToOldestBlock() return false; } - private bool BlockExists(long n, bool _) + /// + /// Callback for . Must match + /// Func<ulong, bool, bool>. + /// + private bool BlockExists(ulong n, bool _) { ChainLevelInfo? info = _chainLevelInfoRepository.LoadLevel(n); @@ -343,21 +359,24 @@ private bool ShouldPruneHistory() return false; } - long? blockCutoff = CutoffBlockNumber; - long? balCutoff = BalCutoffBlockNumber; + ulong? blockCutoff = CutoffBlockNumber; + ulong? balCutoff = BalCutoffBlockNumber; return (blockCutoff is { } bc && _blocksDeletePointer < bc) || (balCutoff is { } balC && _balsDeletePointer < balC); } private bool PruningIntervalHasElapsed() + // Both Head.Number and _pruningInterval are ulong; modulo is unambiguous. => _pruningInterval == 0 || _blockTree.Head!.Number % _pruningInterval == 0; - private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cancellationToken) + private readonly int _deletionProgressLoggingInterval; + + private void PruneBlocksAndReceipts(ulong upperExclusive, CancellationToken cancellationToken) { int deletedBlocks = 0; try { - for (long number = _blocksDeletePointer; number < upperExclusive; number++) + for (ulong number = _blocksDeletePointer; number < upperExclusive; number++) { if (cancellationToken.IsCancellationRequested) { @@ -365,7 +384,7 @@ private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cance break; } - // defensive guards against deleting genesis or anything past the (possibly moving) sync pivot + // Defensive guards: never delete genesis or blocks at/past the sync pivot. if (number < _minDeletableBlockNumber || number >= _blockTree.SyncPivot.BlockNumber) { if (_logger.IsWarn) _logger.Warn($"Encountered unexpected block #{number} while pruning history, this block will not be deleted. Should be in range [{_minDeletableBlockNumber}, {_blockTree.SyncPivot.BlockNumber})."); @@ -377,6 +396,7 @@ private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cance { foreach (BlockInfo blockInfo in chainLevelInfo.BlockInfos) { + // blockNumber param is ulong? — ulong is implicitly nullable here. Block? block = _blockTree.FindBlock(blockInfo.BlockHash, BlockTreeLookupOptions.None, number); if (block is null) { @@ -386,7 +406,8 @@ private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cance if (_logger.IsDebug) _logger.Debug($"Deleting old block {number} with hash {blockInfo.BlockHash}."); _blockTree.DeleteOldBlock(number, blockInfo.BlockHash); _receiptStorage.RemoveReceipts(block); - // Only delete the BAL if the BAL-only pass hasn't already covered this block; otherwise the delete is a no-op and the counter would over-report. + // Only delete the BAL if the BAL-only pass hasn't already covered this block; + // otherwise the delete is a no-op and the counter would over-report. if (number >= _balsDeletePointer) { _blockAccessListStore.Delete(number, blockInfo.BlockHash); @@ -399,7 +420,8 @@ private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cance if (_logger.IsInfo && deletedBlocks > 0 && deletedBlocks % _deletionProgressLoggingInterval == 0) { - long remaining = long.Max(0, upperExclusive - number - 1); + // Guarded subtraction: if number+1 == upperExclusive, remaining is 0. + ulong remaining = number + 1 < upperExclusive ? upperExclusive - (number + 1) : 0; _logger.Info($"Historical block pruning in progress... Deleted {deletedBlocks} blocks, with {remaining} remaining."); } @@ -422,14 +444,14 @@ private void PruneBlocksAndReceipts(long upperExclusive, CancellationToken cance } } - private void PruneBlockAccessLists(long upperExclusive, CancellationToken cancellationToken) + private void PruneBlockAccessLists(ulong upperExclusive, CancellationToken cancellationToken) { // BAL-only pruning for the range past the block cutoff. Blocks (with their BALs) up to // _blocksDeletePointer have already been pruned by PruneBlocksAndReceipts. int deletedBals = 0; try { - for (long number = _balsDeletePointer; number < upperExclusive; number++) + for (ulong number = _balsDeletePointer; number < upperExclusive; number++) { if (cancellationToken.IsCancellationRequested) { @@ -459,7 +481,7 @@ private void PruneBlockAccessLists(long upperExclusive, CancellationToken cancel if (_logger.IsInfo && deletedBals > 0 && deletedBals % _deletionProgressLoggingInterval == 0) { - long remaining = long.Max(0, upperExclusive - number - 1); + ulong remaining = number + 1 < upperExclusive ? upperExclusive - (number + 1) : 0; _logger.Info($"Historical block access list pruning in progress... Deleted {deletedBals} BALs, with {remaining} remaining."); } } @@ -492,7 +514,8 @@ private bool TryLoadDeletePointers() } else { - UpdateBlocksDeletePointer(long.Max(blocksVal.AsRlpValueContext().DecodeLong(), _minDeletableBlockNumber)); + // Rlp.Encode(long) stores as unsigned big-endian; DecodeULong() correctly reverses it. + UpdateBlocksDeletePointer(ulong.Max(blocksVal.AsRlpValueContext().DecodeULong(), _minDeletableBlockNumber)); _lastSavedBlocksDeletePointer = _blocksDeletePointer; } @@ -501,8 +524,9 @@ private bool TryLoadDeletePointers() // deleted alongside blocks in PruneBlocksAndReceipts. Default to the blocks pointer on first load. _balsDeletePointer = balsVal is null ? _blocksDeletePointer - : long.Max(balsVal.AsRlpValueContext().DecodeLong(), _blocksDeletePointer); - _lastSavedBalsDeletePointer = balsVal is null ? long.MinValue : _balsDeletePointer; + : ulong.Max(balsVal.AsRlpValueContext().DecodeULong(), _blocksDeletePointer); + // ulong.MaxValue is used as sentinel: guarantees SaveDeletePointers saves on the very first call. + _lastSavedBalsDeletePointer = balsVal is null ? ulong.MaxValue : _balsDeletePointer; Metrics.OldestStoredBlockAccessListBlockNumber = _balsDeletePointer; _hasLoadedDeletePointers = true; @@ -519,20 +543,23 @@ private void SaveDeletePointers() if (_blocksDeletePointer != _lastSavedBlocksDeletePointer) { - _metadataDb.Set(MetadataDbKeys.HistoryPruningDeletePointer, Rlp.Encode(_blocksDeletePointer).Bytes); + // Safe cast: block delete pointer is a realistic chain height, well within long.MaxValue. + // Rlp.Encode(long) is used for backward-compatibility with existing persisted values. + _metadataDb.Set(MetadataDbKeys.HistoryPruningDeletePointer, Rlp.Encode((long)_blocksDeletePointer).Bytes); _lastSavedBlocksDeletePointer = _blocksDeletePointer; if (_logger.IsDebug) _logger.Debug($"Persisting oldest block stored = #{_blocksDeletePointer} to disk."); } if (_balsDeletePointer != _lastSavedBalsDeletePointer) { - _metadataDb.Set(MetadataDbKeys.BlockAccessListPruningDeletePointer, Rlp.Encode(_balsDeletePointer).Bytes); + // Safe cast: same rationale as above. + _metadataDb.Set(MetadataDbKeys.BlockAccessListPruningDeletePointer, Rlp.Encode((long)_balsDeletePointer).Bytes); _lastSavedBalsDeletePointer = _balsDeletePointer; if (_logger.IsDebug) _logger.Debug($"Persisting oldest BAL stored = #{_balsDeletePointer} to disk."); } } - private void UpdateBlocksDeletePointer(long newDeletePointer, bool isFinalUpdate = true) + private void UpdateBlocksDeletePointer(ulong newDeletePointer, bool isFinalUpdate = true) { _blocksDeletePointer = newDeletePointer; Metrics.OldestStoredBlockNumber = _blocksDeletePointer; diff --git a/src/Nethermind/Nethermind.History/IHistoryPruner.cs b/src/Nethermind/Nethermind.History/IHistoryPruner.cs index f9396b493e2b..c9f3b25af2ab 100644 --- a/src/Nethermind/Nethermind.History/IHistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/IHistoryPruner.cs @@ -8,8 +8,12 @@ namespace Nethermind.History; public interface IHistoryPruner { - public long? CutoffBlockNumber { get; } - public long? BalCutoffBlockNumber { get; } + /// Block number below which historical blocks may be pruned. null when pruning is disabled. + public ulong? CutoffBlockNumber { get; } + + /// Block number below which historical block-access-lists may be pruned. null when pruning is disabled. + public ulong? BalCutoffBlockNumber { get; } + public BlockHeader? OldestBlockHeader { get; } event EventHandler NewOldestBlock; diff --git a/src/Nethermind/Nethermind.History/Metrics.cs b/src/Nethermind/Nethermind.History/Metrics.cs index ef3f774e04ae..76d5ad008eae 100644 --- a/src/Nethermind/Nethermind.History/Metrics.cs +++ b/src/Nethermind/Nethermind.History/Metrics.cs @@ -10,11 +10,11 @@ public static class Metrics { [GaugeMetric] [Description("The number of the oldest block stored.")] - public static long OldestStoredBlockNumber { get; set; } + public static ulong OldestStoredBlockNumber { get; set; } [GaugeMetric] [Description("The number of the oldest block access list stored.")] - public static long OldestStoredBlockAccessListBlockNumber { get; set; } + public static ulong OldestStoredBlockAccessListBlockNumber { get; set; } [CounterMetric] [Description("The number of the historical blocks that have been pruned (since restart).")] @@ -26,9 +26,9 @@ public static class Metrics [GaugeMetric] [Description("The cutoff block number from which historical blocks will be pruned.")] - public static long? PruningCutoffBlocknumber { get; set; } + public static ulong? PruningCutoffBlocknumber { get; set; } [GaugeMetric] [Description("The cutoff block number from which historical block access lists will be pruned.")] - public static long? BlockAccessListPruningCutoffBlocknumber { get; set; } + public static ulong? BlockAccessListPruningCutoffBlocknumber { get; set; } } diff --git a/src/Nethermind/Nethermind.Init/Modules/FlatRocksDbConfigAdjuster.cs b/src/Nethermind/Nethermind.Init/Modules/FlatRocksDbConfigAdjuster.cs index e2f936bbd95b..f812afc16dd2 100644 --- a/src/Nethermind/Nethermind.Init/Modules/FlatRocksDbConfigAdjuster.cs +++ b/src/Nethermind/Nethermind.Init/Modules/FlatRocksDbConfigAdjuster.cs @@ -44,7 +44,7 @@ public IRocksDbConfig GetForDatabase(string databaseName, string? columnName) if (columnName == nameof(FlatDbColumns.Account)) { ulong cacheCapacity = (ulong)(flatDbConfig.BlockCacheSizeBudget * 0.3); - if (_logger.IsInfo) _logger.Info($"Setting {(cacheCapacity / (ulong)1.MiB):N0} MB of block cache to account"); + if (_logger.IsInfo) _logger.Info($"Setting {(cacheCapacity / 1UL.MiB):N0} MB of block cache to account"); HyperClockCacheWrapper cacheWrapper = new(cacheCapacity); cacheHandle = cacheWrapper.Handle; disposeStack.Push(cacheWrapper); @@ -53,7 +53,7 @@ public IRocksDbConfig GetForDatabase(string databaseName, string? columnName) if (columnName == nameof(FlatDbColumns.Storage)) { ulong cacheCapacity = (ulong)(flatDbConfig.BlockCacheSizeBudget * 0.7); - if (_logger.IsInfo) _logger.Info($"Setting {(cacheCapacity / (ulong)1.MiB):N0} MB of block cache to storage"); + if (_logger.IsInfo) _logger.Info($"Setting {(cacheCapacity / 1UL.MiB):N0} MB of block cache to storage"); HyperClockCacheWrapper cacheWrapper = new(cacheCapacity); cacheHandle = cacheWrapper.Handle; disposeStack.Push(cacheWrapper); diff --git a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs index 1d8927b5453d..094999d0d8a5 100644 --- a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs +++ b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs @@ -220,19 +220,19 @@ private class DelayedFinalizedStateProvider( int pruningConfigSimulateLongFinalizationDepth ) : IFinalizedStateProvider { - private long? _lastFinalizedBlockNumber = null; + private ulong? _lastFinalizedBlockNumber = null; - public long FinalizedBlockNumber + public ulong FinalizedBlockNumber { get { - long baseFinalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; + ulong baseFinalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; // Need to limit by head, otherwise it does not work for forward sync. - long headNumber = blockTree.Head?.Number ?? 0; - baseFinalizedBlockNumber = Math.Min(baseFinalizedBlockNumber, headNumber + pruningConfigSimulateLongFinalizationDepth / 2); + ulong headNumber = blockTree.Head?.Number ?? 0UL; + baseFinalizedBlockNumber = Math.Min(baseFinalizedBlockNumber, headNumber + (ulong)pruningConfigSimulateLongFinalizationDepth / 2); - if (_lastFinalizedBlockNumber is null || baseFinalizedBlockNumber - _lastFinalizedBlockNumber > pruningConfigSimulateLongFinalizationDepth) + if (_lastFinalizedBlockNumber is null || baseFinalizedBlockNumber - _lastFinalizedBlockNumber.Value > (ulong)pruningConfigSimulateLongFinalizationDepth) { _lastFinalizedBlockNumber = baseFinalizedBlockNumber; } @@ -241,6 +241,6 @@ public long FinalizedBlockNumber } } - public Hash256? GetFinalizedStateRootAt(long blockNumber) => finalizedStateProvider.GetFinalizedStateRootAt(blockNumber); + public Hash256? GetFinalizedStateRootAt(ulong blockNumber) => finalizedStateProvider.GetFinalizedStateRootAt(blockNumber); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/BloomMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/BloomMigration.cs index e319a3e4f6a8..daa636d2bde5 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/BloomMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/BloomMigration.cs @@ -28,12 +28,12 @@ public class BloomMigration( IBloomConfig bloomConfig, ILogManager logManager) : IDatabaseMigration { - private static readonly BlockHeader EmptyHeader = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.Zero, 0L, 0L, 0UL, []); + private static readonly BlockHeader EmptyHeader = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.Zero, 0UL, 0UL, 0UL, []); private readonly ILogger _logger = logManager.GetClassLogger(); private Stopwatch? _stopwatch; private readonly ProgressLogger _progressLogger = new("Bloom migration ", logManager); - private long _migrateCount; + private ulong _migrateCount; private Average[]? _averages; private readonly StringBuilder _builder = new(); private readonly IBloomConfig _bloomConfig = bloomConfig; @@ -70,23 +70,23 @@ public async Task Run(CancellationToken cancellationToken) private static bool CanMigrate(SyncMode syncMode) => syncMode.NotSyncing(); - private long MinBlockNumber => - bloomStorage.MinBlockNumber == long.MaxValue + private ulong MinBlockNumber => + bloomStorage.MinBlockNumber == ulong.MaxValue ? blockTree.BestKnownNumber : bloomStorage.MinBlockNumber - 1; private void RunBloomMigration(CancellationToken token) { - BlockHeader GetMissingBlockHeader(long i) + BlockHeader GetMissingBlockHeader(ulong i) { if (_logger.IsWarn) _logger.Warn(GetLogMessage("warning", $"Header for block {i} not found. Logs will not be searchable for this block.")); return EmptyHeader; } IBloomStorage storage = bloomStorage; - long to = MinBlockNumber; - long synced = storage.MigratedBlockNumber + 1; - long from = synced; + ulong to = MinBlockNumber; + ulong synced = storage.MigratedBlockNumber + 1; + ulong from = synced; _migrateCount = to + 1; _averages = bloomStorage.Averages.ToArray(); @@ -113,7 +113,7 @@ BlockHeader GetMissingBlockHeader(long i) IEnumerable GetHeadersForMigration() { - bool TryGetMainChainBlockHashFromLevel(long number, out Hash256? blockHash) + bool TryGetMainChainBlockHashFromLevel(ulong number, out Hash256? blockHash) { using BatchWrite batch = chainLevelInfoRepository.StartBatch(); ChainLevelInfo? level = chainLevelInfoRepository.LoadLevel(number); @@ -138,7 +138,7 @@ bool TryGetMainChainBlockHashFromLevel(long number, out Hash256? blockHash) } } - for (long i = from; i <= to; i++) + for (ulong i = from; i <= to; i++) { if (token.IsCancellationRequested) { diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs index 85cc862f29cd..5087c5aedf06 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs @@ -36,7 +36,7 @@ public async Task Run(CancellationToken cancellationToken) { MissingReceiptsFixVisitor visitor = new( syncConfig.AncientReceiptsBarrierCalc, - blockTree.Head?.Number - 2 ?? 0, + blockTree.Head?.Number - 2 ?? 0UL, receiptStorage, logManager, syncPeerPool, @@ -60,8 +60,8 @@ public async Task Run(CancellationToken cancellationToken) } private class MissingReceiptsFixVisitor( - long startLevel, - long endLevel, + ulong startLevel, + ulong endLevel, IReceiptStorage receiptStorage, ILogManager logManager, ISyncPeerPool syncPeerPool, diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs index f5a964040868..9ab3d07ff115 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs @@ -72,7 +72,7 @@ ILogManager logManager } // Actually start running it. - public async Task Run(long from, long to) + public async Task Run(ulong from, ulong to) { _cancellationTokenSource?.Cancel(); try @@ -109,9 +109,9 @@ public async Task Run(CancellationToken cancellationToken) private void RunIfNeeded(CancellationToken cancellationToken) { // Note, it start in decreasing order from this high number. - long migrateToBlockNumber = _receiptStorage.MigratedBlockNumber == long.MaxValue + ulong migrateToBlockNumber = _receiptStorage.MigratedBlockNumber == ulong.MaxValue ? _syncModeSelector.Current.NotSyncing() - ? _blockTree.Head?.Number ?? 0 + ? _blockTree.Head?.Number ?? 0UL : _blockTree.BestKnownNumber : _receiptStorage.MigratedBlockNumber - 1; @@ -132,10 +132,10 @@ private void RunIfNeeded(CancellationToken cancellationToken) } } - private void RunMigration(long from, long to, bool updateReceiptMigrationPointer, CancellationToken token) + private void RunMigration(ulong from, ulong to, bool updateReceiptMigrationPointer, CancellationToken token) { from = Math.Min(from, to); - long synced = 0; + ulong synced = 0; if (_logger.IsWarn) _logger.Warn($"Running migration from {from} to {to}"); @@ -159,7 +159,7 @@ private void RunMigration(long from, long to, bool updateReceiptMigrationPointer GetBlockBodiesForMigration(from, to, updateReceiptMigrationPointer, token) .AsParallel().WithDegreeOfParallelism(parallelism).ForAll((item) => { - (long blockNum, Hash256 blockHash) = item; + (ulong blockNum, Hash256 blockHash) = item; Block? block = _blockTree.FindBlock(blockHash!, BlockTreeLookupOptions.None); bool usingEmptyBlock = block is null; if (usingEmptyBlock) @@ -198,7 +198,7 @@ private void RunMigration(long from, long to, bool updateReceiptMigrationPointer } } - Block GetMissingBlock(long i, Hash256? blockHash) + Block GetMissingBlock(ulong i, Hash256? blockHash) { if (_logger.IsDebug) _logger.Debug($"Block {i} not found. Logs will not be searchable for this block."); Block emptyBlock = EmptyBlock.Get(); @@ -209,9 +209,9 @@ Block GetMissingBlock(long i, Hash256? blockHash) static void ReturnMissingBlock(Block emptyBlock) => EmptyBlock.Return(emptyBlock); - IEnumerable<(long, Hash256)> GetBlockBodiesForMigration(long from, long to, bool updateReceiptMigrationPointer, CancellationToken token) + IEnumerable<(ulong, Hash256)> GetBlockBodiesForMigration(ulong from, ulong to, bool updateReceiptMigrationPointer, CancellationToken token) { - bool TryGetMainChainBlockHashFromLevel(long number, out Hash256? blockHash) + bool TryGetMainChainBlockHashFromLevel(ulong number, out Hash256? blockHash) { using BatchWrite batch = _chainLevelInfoRepository.StartBatch(); ChainLevelInfo? level = _chainLevelInfoRepository.LoadLevel(number); @@ -236,7 +236,7 @@ bool TryGetMainChainBlockHashFromLevel(long number, out Hash256? blockHash) } } - for (long i = to; i >= from; i--) + for (ulong i = to; i >= from; i--) { if (token.IsCancellationRequested) { @@ -281,7 +281,7 @@ private void MigrateBlock(Block block) _receiptsBlockDb.Delete(block.Hash!); // Remove old tx index - bool txIndexExpired = _receiptConfig.TxLookupLimit != 0 && _blockTree.Head?.Number - block.Number > _receiptConfig.TxLookupLimit; + bool txIndexExpired = _receiptConfig.TxLookupLimit != 0 && (long?)(_blockTree.Head?.Number - block.Number) > _receiptConfig.TxLookupLimit; bool neverIndexTx = _receiptConfig.TxLookupLimit == -1; if (neverIndexTx || txIndexExpired) { @@ -303,13 +303,13 @@ private void ResetMigrationIndexIfNeeded() { if (_receiptConfig.ForceReceiptsMigration) { - _receiptStorage.MigratedBlockNumber = long.MaxValue; + _receiptStorage.MigratedBlockNumber = ulong.MaxValue; return; } - if (_receiptStorage.MigratedBlockNumber != long.MaxValue) + if (_receiptStorage.MigratedBlockNumber != ulong.MaxValue) { - long blockNumber = _blockTree.Head?.Number ?? 0; + ulong blockNumber = _blockTree.Head?.Number ?? 0UL; while (blockNumber > 0) { ChainLevelInfo? level = _chainLevelInfoRepository.LoadLevel(blockNumber); @@ -321,7 +321,7 @@ private void ResetMigrationIndexIfNeeded() { if (IsMigrationNeeded(blockNumber, firstBlockInfo.BlockHash, receipts)) { - _receiptStorage.MigratedBlockNumber = long.MaxValue; + _receiptStorage.MigratedBlockNumber = ulong.MaxValue; } break; @@ -333,7 +333,7 @@ private void ResetMigrationIndexIfNeeded() } } - private bool IsMigrationNeeded(long blockNumber, Hash256 blockHash, TxReceipt[] receipts) + private bool IsMigrationNeeded(ulong blockNumber, Hash256 blockHash, TxReceipt[] receipts) { if (!_receiptConfig.CompactReceiptStore && _recovery.NeedRecover(receipts)) { @@ -354,7 +354,7 @@ private bool IsMigrationNeeded(long blockNumber, Hash256 blockHash, TxReceipt[] private class EmptyBlockObjectPolicy : IPooledObjectPolicy { - public Block Create() => new(new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.Zero, 0L, 0L, 0UL, [])); + public Block Create() => new(new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.Zero, 0UL, 0UL, 0UL, [])); public bool Return(Block obj) => true; } diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/TotalDifficultyFixMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/TotalDifficultyFixMigration.cs index f146fb1b617d..132c0e317d3d 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/TotalDifficultyFixMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/TotalDifficultyFixMigration.cs @@ -38,13 +38,13 @@ public Task Run(CancellationToken cancellationToken) return Task.CompletedTask; } - private void RunMigration(long startingBlock, long? lastBlock, CancellationToken cancellationToken) + private void RunMigration(ulong startingBlock, ulong? lastBlock, CancellationToken cancellationToken) { lastBlock ??= _blockTree.BestKnownNumber; if (_logger.IsInfo) _logger.Info($"Starting TotalDifficultyFixMigration. From block {startingBlock} to block {lastBlock}"); - for (long blockNumber = startingBlock; blockNumber <= lastBlock; ++blockNumber) + for (ulong blockNumber = startingBlock; blockNumber <= lastBlock; ++blockNumber) { cancellationToken.ThrowIfCancellationRequested(); @@ -79,7 +79,7 @@ private void RunMigration(long startingBlock, long? lastBlock, CancellationToken if (_logger.IsInfo) _logger.Info("Ended TotalDifficultyFixMigration."); } - UInt256? FindParentTd(BlockHeader blockHeader, long level) + UInt256? FindParentTd(BlockHeader blockHeader, ulong level) { if (blockHeader.ParentHash is null) return null; Hash256? parentHash = _blockTree.FindHeader(blockHeader.ParentHash)?.Hash; diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingAllocsBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingAllocsBenchmarks.cs index 75ff5ee642b9..2123ae06eb0d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingAllocsBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingAllocsBenchmarks.cs @@ -87,9 +87,9 @@ private void RunTx(GethLikeTxDirectStreamingTracer tracer) for (int op = 0; op < OpcodesPerTx; op++) { int depth = (op % 4) + 1; - tracer.StartOperation(op, Instruction.SSTORE, 1_000_000 - op, _envByDepth[depth - 1]); + tracer.StartOperation(op, Instruction.SSTORE, (ulong)(1_000_000 - op), _envByDepth[depth - 1]); tracer.SetOperationStorage(Address.Zero, new UInt256((ulong)op), valueSpan, valueSpan); - tracer.ReportOperationRemainingGas(900_000 - op); + tracer.ReportOperationRemainingGas((ulong)(900_000 - op)); } tracer.BuildResult(); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingBenchmarks.cs index e54a504301fc..9a0be949d04a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/DebugTraceStreamingBenchmarks.cs @@ -173,8 +173,8 @@ private void DriveGethOpcodes(GethLikeTxTracer tracer, int opcodeCount) { for (int op = 0; op < opcodeCount; op++) { - tracer.StartOperation(op, Instruction.SSTORE, 1_000_000 - op, _env); - tracer.ReportOperationRemainingGas(900_000 - op); + tracer.StartOperation(op, Instruction.SSTORE, (ulong)(1_000_000 - op), _env); + tracer.ReportOperationRemainingGas((ulong)(900_000 - op)); } tracer.MarkAsSuccess(Address.Zero, default, [], []); } @@ -224,7 +224,7 @@ private static void WriteSyntheticOpcode(Utf8JsonWriter writer, int pc) ProgramCounter = pc, Opcode = "ADD", Depth = 1, - Gas = 1_000_000 - pc, + Gas = (ulong)(1_000_000 - pc), GasCost = 3, Memory = ["0x0000000000000000000000000000000000000000000000000000000000000000"], Stack = ["0x1", "0x2"], diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingAllocsBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingAllocsBenchmarks.cs index 1c2ce9ca28aa..51d897e5938c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingAllocsBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingAllocsBenchmarks.cs @@ -111,10 +111,10 @@ private void DriveTx(ParityLikeTxTracer tracer) int opsAtDepth = OpcodesPerTx / CallDepthPerTx; for (int op = 0; op < opsAtDepth; op++) { - tracer.StartOperation(op, Instruction.SSTORE, 1_000_000 - op, _envByDepth[depth]); + tracer.StartOperation(op, Instruction.SSTORE, (ulong)(1_000_000 - op), _envByDepth[depth]); tracer.ReportStackPush(value); tracer.ReportStorageChange(value, value); - tracer.ReportOperationRemainingGas(900_000 - op); + tracer.ReportOperationRemainingGas((ulong)(900_000 - op)); } } for (int depth = 1; depth <= CallDepthPerTx; depth++) diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingBenchmarks.cs index c30bea7b632b..85423ca82245 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/TraceStreamingBenchmarks.cs @@ -179,10 +179,10 @@ private void DriveOpcodes(ParityLikeTxTracer tracer, int opcodeCount) tracer.ReportAction(1_000_000, UInt256.Zero, Address.Zero, Address.Zero, default, ExecutionType.CALL); for (int op = 0; op < opcodeCount; op++) { - tracer.StartOperation(op, Instruction.SSTORE, 1_000_000 - op, _env); + tracer.StartOperation(op, Instruction.SSTORE, (ulong)(1_000_000 - op), _env); tracer.ReportStackPush(value); tracer.ReportStorageChange(value, value); - tracer.ReportOperationRemainingGas(900_000 - op); + tracer.ReportOperationRemainingGas((ulong)(900_000 - op)); } tracer.ReportActionEnd(0, default); tracer.MarkAsSuccess(Address.Zero, default, [], []); @@ -232,7 +232,7 @@ private static void WriteSyntheticOpcode(Utf8JsonWriter writer, int pc) { Pc = pc, Cost = 3, - Used = 1_000_000 - pc, + Used = (ulong)(1_000_000 - pc), Push = [], }; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs index 646ecae828bc..87e74b586d48 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs @@ -74,7 +74,7 @@ public async Task CompareGethTxTrace(Uri uri1, Uri uri2, Hash256? transactionHas } [TestCaseSource(nameof(Tests))] - public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, long blockNumber) + public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, ulong blockNumber) { using IConsensusDataSource> receipt1Source = GetSource>(uri1); using IConsensusDataSource> receipt2Source = GetSource>(uri2); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Data/BlockParameterConverterTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Data/BlockParameterConverterTests.cs index e6618ad7a8cf..6bb51c89eff3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Data/BlockParameterConverterTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Data/BlockParameterConverterTests.cs @@ -27,15 +27,15 @@ public void SetUp() public void TearDown() => EthereumJsonSerializer.StrictHexFormat = _previousStrictHexFormat; - [TestCase("0", 0)] - [TestCase("100", 100)] - [TestCase("\"0x0\"", 0)] - [TestCase("\"0xA\"", 10)] - [TestCase("\"0xa\"", 10)] - [TestCase("\"0\"", 0)] - [TestCase("\"100\"", 100)] - [TestCase("{ \"blockNumber\": \"0xa\" }", 10)] - public void Can_read_block_number(string input, long output) + [TestCase("0", 0UL)] + [TestCase("100", 100UL)] + [TestCase("\"0x0\"", 0UL)] + [TestCase("\"0xA\"", 10UL)] + [TestCase("\"0xa\"", 10UL)] + [TestCase("\"0\"", 0UL)] + [TestCase("\"100\"", 100UL)] + [TestCase("{ \"blockNumber\": \"0xa\" }", 10UL)] + public void Can_read_block_number(string input, ulong output) { IJsonSerializer serializer = new EthereumJsonSerializer(); @@ -136,9 +136,9 @@ public void Can_write_type(string output, BlockParameterType input) Assert.That(result, Is.EqualTo(output)); } - [TestCase("\"0x0\"", 0)] - [TestCase("\"0xa\"", 10)] - public void Can_write_number(string output, long input) + [TestCase("\"0x0\"", 0UL)] + [TestCase("\"0xa\"", 10UL)] + public void Can_write_number(string output, ulong input) { BlockParameter blockParameter = new(input); @@ -157,8 +157,8 @@ public void Can_do_roundtrip() TestRoundtrip(BlockParameter.Earliest, "earliest"); TestRoundtrip(BlockParameter.Finalized, "finalized"); TestRoundtrip(BlockParameter.Safe, "safe"); - TestRoundtrip(new BlockParameter(0L), "zero"); - TestRoundtrip(new BlockParameter(long.MaxValue), "max"); + TestRoundtrip(new BlockParameter(0UL), "zero"); + TestRoundtrip(new BlockParameter(ulong.MaxValue), "max"); TestRoundtrip(new BlockParameter(TestItem.KeccakA), "hash"); TestRoundtrip(new BlockParameter(TestItem.KeccakA, true), "hash with canonical"); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index f7c749eb2b1a..de9ef70cb746 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -149,7 +149,7 @@ public void Eth_module_populates_block_data(bool assertSize, long expected) ISpecProvider specProvider = Substitute.For(); ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); BlockForRpc result = RpcTest.AssertSuccess(TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true")); - Assert.That(assertSize ? result.Size : result.Number, Is.EqualTo(expected)); + Assert.That(assertSize ? (long)result.Size : (long)result.Number!.Value, Is.EqualTo(expected)); } [Test] @@ -420,7 +420,7 @@ public void Raw_utf8_params_invalid_arguments_return_invalid_params_before_invoc } else { - ethRpcModule.DidNotReceive().eth_feeHistory(Arg.Any(), Arg.Any(), Arg.Any()); + ethRpcModule.DidNotReceive().eth_feeHistory(Arg.Any(), Arg.Any(), Arg.Any()); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs index 54e1645519e8..b2f42beb8da0 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs @@ -63,7 +63,7 @@ public void Debug_traceCallMany_streams_under_live_cancellation_token() _blockFinder.FindHeader(Arg.Any()).ReturnsForAnyArgs(header); _blockchainBridge.HasStateForBlock(Arg.Any()).Returns(true); _debugBridge - .GetBundleTraces(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .GetBundleTraces(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(static c => StreamBundles(c.ArgAt(3))); DebugRpcModule rpcModule = CreateDebugRpcModule(_debugBridge); @@ -140,7 +140,7 @@ public async Task Get_raw_header() HeaderDecoder decoder = new(); Block blk = Build.A.Block.WithNumber(0).TestObject; Rlp rlp = decoder.Encode(blk.Header); - _debugBridge.GetBlock(new BlockParameter((long)0)).Returns(blk); + _debugBridge.GetBlock(new BlockParameter(0UL)).Returns(blk); DebugRpcModule rpcModule = CreateDebugRpcModule(_debugBridge); using JsonRpcResponse response = await RpcTest.TestRequest(rpcModule, "debug_getRawHeader", "0x"); @@ -387,7 +387,7 @@ public void Debug_traceCall_test() [Test] public async Task Migrate_receipts() { - _debugBridge.MigrateReceipts(Arg.Any(), Arg.Any()).Returns(true); + _debugBridge.MigrateReceipts(Arg.Any(), Arg.Any()).Returns(true); IDebugRpcModule rpcModule = CreateDebugRpcModule(_debugBridge); string response = await RpcTest.TestSerializedRequest(rpcModule, "debug_migrateReceipts", 100); Assert.That(response, Is.Not.Null); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs index 45050395fb65..3fea25678089 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs @@ -31,7 +31,7 @@ public partial class DebugRpcModuleTests { [Test] [TestCaseSource(nameof(ExecutionWitnessSource))] - public async Task Debug_executionWitness_can_be_used_for_stateless_execution_for_multiple_blocks(long blockNumber) + public async Task Debug_executionWitness_can_be_used_for_stateless_execution_for_multiple_blocks(ulong blockNumber) { using Context ctx = await Context.Create(); TestRpcBlockchain blockchain = ctx.Blockchain; @@ -157,7 +157,7 @@ public async Task Debug_witness_includes_trie_nodes_for_storage_set_without_prio /// private static async Task
DeployAndCallContractWithStorage(TestRpcBlockchain blockchain, UInt256 storageSlot) { - UInt256 deployNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong deployNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); byte[] runtimeCode = Prepare.EvmCode .PushData(1) // value @@ -177,7 +177,7 @@ private static async Task
DeployAndCallContractWithStorage(TestRpcBlock await blockchain.AddBlock(deployTx); // Call the contract to execute the SSTORE and commit storage to the trie - UInt256 callNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong callNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction callTx = Build.A.Transaction .WithNonce(callNonce) .To(contractAddress) @@ -227,7 +227,7 @@ public async Task Debug_executionWitnessCall_against_contract() Address contractAddress = await CreateDeployTx(blockchain, transferBlock.Number); // Call the deployed contract to generate a witness - long blockNumber = blockchain.BlockTree.Head!.Number; + ulong blockNumber = blockchain.BlockTree.Head!.Number; JsonRpcResponse response = await RpcTest.TestRequest(ctx.DebugRpcModule, "debug_executionWitnessCall", new { to = contractAddress.ToString(), gas = "0x30D40" }, $"0x{blockNumber:x}"); @@ -253,7 +253,7 @@ public async Task Debug_executionWitnessCall_without_gas_field_still_records_ful Block transferBlock = await CreateTransferTx(blockchain); Address contractAddress = await CreateDeployTx(blockchain, transferBlock.Number); - long blockNumber = blockchain.BlockTree.Head!.Number; + ulong blockNumber = blockchain.BlockTree.Head!.Number; // With gas explicitly passed — the control case. JsonRpcResponse withGas = await RpcTest.TestRequest(ctx.DebugRpcModule, "debug_executionWitnessCall", @@ -285,13 +285,13 @@ public async Task Debug_executionWitnessCall_without_gas_field_still_records_ful private static IEnumerable ExecutionWitnessSource() { // 7 blocks in the test where this test case source is used - for (long blockNumber = 0; blockNumber < 7; blockNumber++) + for (ulong blockNumber = 0; blockNumber < 7; blockNumber++) yield return new TestCaseData(blockNumber); } private static async Task CreateTransferTx(TestRpcBlockchain blockchain) { - UInt256 transferNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong transferNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transferTx = Build.A.Transaction .WithNonce(transferNonce) @@ -303,9 +303,9 @@ private static async Task CreateTransferTx(TestRpcBlockchain blockchain) return await blockchain.AddBlock(transferTx); } - private static async Task
CreateDeployTx(TestRpcBlockchain blockchain, long blockWhoseHashToGet) + private static async Task
CreateDeployTx(TestRpcBlockchain blockchain, ulong blockWhoseHashToGet) { - UInt256 deployNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong deployNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); byte[] runtimeCode = Prepare.EvmCode .PushData(0) .PushData(32) @@ -337,7 +337,7 @@ private static async Task
CreateDeployTx(TestRpcBlockchain blockchain, private static async Task CreateContractCallTx(TestRpcBlockchain blockchain, Address contractAddress) { - UInt256 callNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong callNonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction callTx = Build.A.Transaction .WithNonce(callNonce) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs index d9f7ba1f2049..f5b5b5fc3d43 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs @@ -16,7 +16,6 @@ using Nethermind.Blockchain.Tracing.GethStyle.Custom.Native.Call; using Nethermind.Blockchain.Tracing.GethStyle.Custom.Native.FourByte; using Nethermind.Blockchain.Tracing.GethStyle.Custom.Native.Prestate; -using Nethermind.Int256; using Nethermind.Specs; using Nethermind.Specs.Forks; using Nethermind.JsonRpc.Modules.DebugModule; @@ -65,7 +64,7 @@ public async Task Debug_traceBlockByNumber(Func TraceBlockSource() "result": [ { "result": { - "gas": 87700, + "gas": 88468, "failed": false, "returnValue": "0x", "structLogs": [ - { "pc": 0, "op": "PUSH32", "gas": 46536, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 33, "op": "PUSH1", "gas": 46533, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000"], "storage": {} }, - { "pc": 35, "op": "MSTORE", "gas": 46530, "gasCost": 6, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000", "0x0"], "storage": {} }, - { "pc": 36, "op": "PUSH32", "gas": 46524, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 69, "op": "PUSH1", "gas": 46521, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 71, "op": "PUSH1", "gas": 46518, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6"], "storage": {} }, - { "pc": 73, "op": "PUSH1", "gas": 46515, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0"], "storage": {} }, - { "pc": 75, "op": "CREATE2", "gas": 46512, "gasCost": 32006, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0", "0x0"], "storage": {} }, - { "pc": 0, "op": "PUSH1", "gas": 14280, "gasCost": 3, "depth": 2, "error": null, "stack": [], "storage": {} }, - { "pc": 2, "op": "PUSH1", "gas": 14277, "gasCost": 3, "depth": 2, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 4, "op": "SSTORE", "gas": 14274, "gasCost": 2200, "depth": 2, "error": null, "stack": ["0x0", "0x20"], "storage": {} }, - { "pc": 5, "op": "STOP", "gas": 12074, "gasCost": 0, "depth": 2, "error": null, "stack": [], "storage": {} }, - { "pc": 76, "op": "STOP", "gas": 12300, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} } + { "pc": 0, "op": "PUSH32", "gas": 45768, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 33, "op": "PUSH1", "gas": 45765, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000"], "storage": {} }, + { "pc": 35, "op": "MSTORE", "gas": 45762, "gasCost": 6, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000", "0x0"], "storage": {} }, + { "pc": 36, "op": "PUSH32", "gas": 45756, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 69, "op": "PUSH1", "gas": 45753, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 71, "op": "PUSH1", "gas": 45750, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6"], "storage": {} }, + { "pc": 73, "op": "PUSH1", "gas": 45747, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0"], "storage": {} }, + { "pc": 75, "op": "CREATE2", "gas": 45744, "gasCost": 32006, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0", "0x0"], "storage": {} }, + { "pc": 0, "op": "PUSH1", "gas": 13524, "gasCost": 3, "depth": 2, "error": null, "stack": [], "storage": {} }, + { "pc": 2, "op": "PUSH1", "gas": 13521, "gasCost": 3, "depth": 2, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 4, "op": "SSTORE", "gas": 13518, "gasCost": 2200, "depth": 2, "error": null, "stack": ["0x0", "0x20"], "storage": {} }, + { "pc": 5, "op": "STOP", "gas": 11318, "gasCost": 0, "depth": 2, "error": null, "stack": [], "storage": {} }, + { "pc": 76, "op": "STOP", "gas": 11532, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} } ] }, "txHash": "0xb5a78a1eda0ae98d4f62eec3e0b7f5bf81810cd57bc75006b611982667bcdbe7" }, { "result": { - "gas": 56141, + "gas": 56213, "failed": false, "returnValue": "0x", "structLogs": [ - { "pc": 0, "op": "PUSH1", "gas": 46480, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 2, "op": "PUSH1", "gas": 46477, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 4, "op": "PUSH1", "gas": 46474, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0"], "storage": {} }, - { "pc": 6, "op": "PUSH1", "gas": 46471, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 8, "op": "PUSH1", "gas": 46468, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 10, "op": "PUSH20", "gas": 46465, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 31, "op": "PUSH3", "gas": 46462, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} }, - { "pc": 35, "op": "CALL", "gas": 46459, "gasCost": 45774, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "0x186a0"], "storage": {} }, - { "pc": 36, "op": "STOP", "gas": 43859, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x1"], "storage": {} } + { "pc": 0, "op": "PUSH1", "gas": 46408, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 2, "op": "PUSH1", "gas": 46405, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 4, "op": "PUSH1", "gas": 46402, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0"], "storage": {} }, + { "pc": 6, "op": "PUSH1", "gas": 46399, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 8, "op": "PUSH1", "gas": 46396, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 10, "op": "PUSH20", "gas": 46393, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 31, "op": "PUSH3", "gas": 46390, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} }, + { "pc": 35, "op": "CALL", "gas": 46387, "gasCost": 45703, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "0x186a0"], "storage": {} }, + { "pc": 36, "op": "STOP", "gas": 43787, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x1"], "storage": {} } ] }, "txHash": "0xdb3d8694a97364e8628aeb18993520ea6bac0b65b02eed1abddaaed1ddd04e7b" @@ -175,11 +174,11 @@ private static IEnumerable TraceBlockSource() "jsonrpc": "2.0", "result": [ { - "result": [46536,46533,46530,46524,46521,46518,46515,46512,14280,14277,14274,12074,12300], + "result": [45768,45765,45762,45756,45753,45750,45747,45744,13524,13521,13518,11318,11532], "txHash": "0xb5a78a1eda0ae98d4f62eec3e0b7f5bf81810cd57bc75006b611982667bcdbe7" }, { - "result": [46480,46477,46474,46471,46468,46465,46462,46459,43859], + "result": [46408,46405,46402,46399,46396,46393,46390,46387,43787], "txHash": "0xdb3d8694a97364e8628aeb18993520ea6bac0b65b02eed1abddaaed1ddd04e7b" } ], @@ -229,7 +228,7 @@ private static IEnumerable TraceBlockSource() "to": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0x15694", + "gasUsed": "0x15994", "input": "0x7f60006020550000000000000000000000000000000000000000000000000000006000527f0000000000000000000000000000000000000000000000000000000000000000600660006000f500", "calls": [ { @@ -237,7 +236,7 @@ private static IEnumerable TraceBlockSource() "from": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "to": "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "value": "0x0", - "gas": "0x37c8", + "gas": "0x34d4", "gasUsed": "0x89e", "input": "0x600060205500" } @@ -252,7 +251,7 @@ private static IEnumerable TraceBlockSource() "to": "0x6b5887043de753ecfa6269f947129068263ffbe2", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0xdb4d", + "gasUsed": "0xdb95", "input": "0x600060006000600060007328156f6fdeeffd5667d51bb8d7d5069a920e0837620186a0f100", "calls": [ { @@ -260,7 +259,7 @@ private static IEnumerable TraceBlockSource() "from": "0x6b5887043de753ecfa6269f947129068263ffbe2", "to": "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "value": "0x0", - "gas": "0xa8a6", + "gas": "0xa85f", "gasUsed": "0x0", "input": "0x" } @@ -307,7 +306,7 @@ private static IEnumerable TraceBlockSource() { "result": { "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099": { - "balance": "0x3635c9adc5de9db350", + "balance": "0x3635c9adc5de9db050", "nonce": 4, "code": "0xabcd" }, @@ -315,7 +314,7 @@ private static IEnumerable TraceBlockSource() "balance": "0x0" }, "0x475674cb523a0a2736b7f7534390288fce16982c": { - "balance": "0x24cac" + "balance": "0x24fac" }, "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837": { "balance": "0x0", @@ -334,7 +333,7 @@ private static IEnumerable TraceBlockSource() private static Transaction[] CreateTraceBlockTransactions(TestRpcBlockchain blockchain) { - UInt256 nonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonce = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); byte[] contract = Prepare.EvmCode .PushData(0) .PushData(32) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceCallMany.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceCallMany.cs index 94a827dfbbb5..ed6d16640292 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceCallMany.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceCallMany.cs @@ -29,7 +29,7 @@ private static LegacyTransactionForRpc CreateTransaction( Address? from = null, Address? to = null, UInt256? value = null, - long gas = GasCostOf.Transaction) => + ulong gas = GasCostOf.Transaction) => new() { From = from ?? TestItem.AddressD, @@ -197,13 +197,13 @@ public async Task Debug_traceCallMany_mixed_bundles_preserves_order() public async Task Debug_traceCallMany_with_block_number_gap_returns_one_entry_per_bundle(int secondBundleOffset) { using Context ctx = await CreateContext(); - long headNumber = ctx.Blockchain.BlockTree.Head!.Number; + ulong headNumber = ctx.Blockchain.BlockTree.Head!.Number; TransactionBundle first = CreateBundle(CreateTransaction()); - first.BlockOverride = new BlockOverride { Number = (ulong)(headNumber + 1) }; + first.BlockOverride = new BlockOverride { Number = headNumber + 1 }; TransactionBundle second = CreateBundle(CreateTransaction(to: TestItem.AddressD)); - second.BlockOverride = new BlockOverride { Number = (ulong)(headNumber + secondBundleOffset) }; + second.BlockOverride = new BlockOverride { Number = headNumber + (ulong)secondBundleOffset }; ResultWrapper>> result = ctx.DebugRpcModule.debug_traceCallMany([first, second], BlockParameter.Latest); @@ -216,7 +216,7 @@ public async Task Debug_traceCallMany_with_block_number_gap_returns_one_entry_pe public async Task Debug_traceCallMany_caps_gas_to_gas_cap() { using Context ctx = await CreateContext(); - long gasCap = 50_000; + ulong gasCap = 50_000; IJsonRpcConfig config = ctx.Blockchain.Container.Resolve(); config.GasCap = gasCap; @@ -225,7 +225,7 @@ public async Task Debug_traceCallMany_caps_gas_to_gas_cap() byte[] runtimeCode = Bytes.FromHexString("5a60005260206000f3"); byte[] initCode = Prepare.EvmCode.ForInitOf(runtimeCode).Done; - UInt256 nonce = ctx.Blockchain.StateReader.GetNonce(ctx.Blockchain.BlockTree.Head!.Header, TestItem.AddressD); + ulong nonce = ctx.Blockchain.StateReader.GetNonce(ctx.Blockchain.BlockTree.Head!.Header, TestItem.AddressD); Address contractAddress = ContractAddress.From(TestItem.AddressD, nonce); Transaction deployTx = Build.A.Transaction @@ -241,9 +241,9 @@ public async Task Debug_traceCallMany_caps_gas_to_gas_cap() JArray result = await RunTraceCallManyAsJson(ctx, [bundle]); byte[] returnValue = Bytes.FromHexString((string)result[0][0]!["returnValue"]!); - long gasAvailable = (long)returnValue.ToUInt256(); + ulong gasAvailable = (ulong)returnValue.ToUInt256(); Assert.That(gasAvailable, Is.LessThan(gasCap)); - Assert.That(gasAvailable, Is.GreaterThan(0)); + Assert.That(gasAvailable, Is.GreaterThan(0UL)); } [Test] @@ -251,8 +251,8 @@ public async Task Debug_traceCallMany_without_gas_defaults_to_gas_cap_not_block_ { using Context ctx = await CreateContext(); - long blockGasLimit = ctx.Blockchain.BlockTree.Head!.Header.GasLimit; - long gasCap = blockGasLimit * 10; + ulong blockGasLimit = ctx.Blockchain.BlockTree.Head!.Header.GasLimit; + ulong gasCap = blockGasLimit * 10; IJsonRpcConfig config = ctx.Blockchain.Container.Resolve(); config.GasCap = gasCap; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs index 38ccdb2baecb..c935b7554d12 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs @@ -43,7 +43,7 @@ public async Task Debug_traceTransactionByBlockAndIndex(Func TraceTransactionContractSource() { "jsonrpc": "2.0", "result": { - "gas": 55278, + "gas": 55302, "failed": false, "returnValue": "0x", "structLogs": [ { "pc": 0, "op": "PUSH1", - "gas": 46928, + "gas": 46904, "gasCost": 3, "depth": 1, "error": null, @@ -209,7 +209,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 2, "op": "PUSH1", - "gas": 46925, + "gas": 46901, "gasCost": 3, "depth": 1, "error": null, @@ -221,7 +221,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 4, "op": "SSTORE", - "gas": 46922, + "gas": 46898, "gasCost": 2200, "depth": 1, "error": null, @@ -234,7 +234,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 5, "op": "STOP", - "gas": 44722, + "gas": 44698, "gasCost": 0, "depth": 1, "error": null, @@ -252,7 +252,7 @@ private static IEnumerable TraceTransactionContractSource() yield return new TestCaseData( contractTransaction, new GethTraceOptions { Tracer = "{gasUsed: [], step: function(log) { this.gasUsed.push(log.getGas()); }, result: function() { return this.gasUsed; }, fault: function(){}}" }, - """{"jsonrpc":"2.0","result":[46928,46925,46922,44722],"id":67}""" + """{"jsonrpc":"2.0","result":[46904,46901,46898,44698],"id":67}""" ) { TestName = "Contract with javaScriptTracer" }; @@ -275,7 +275,7 @@ private static IEnumerable TraceTransactionContractSource() "to": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0xd7ee", + "gasUsed": "0xd806", "input": "0x600060205500" }, "id": 67 diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.cs index d48c48fb5c0a..fbbf02490034 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.cs @@ -150,7 +150,7 @@ public async Task Debug_traceCall_with_state_override(string name, string transa public async Task Debug_traceCall_caps_gas_to_gas_cap() { using Context ctx = await Context.Create(); - long gasCap = 50_000; + ulong gasCap = 50_000; IJsonRpcConfig config = ctx.Blockchain.Container.Resolve(); config.GasCap = gasCap; @@ -166,9 +166,9 @@ public async Task Debug_traceCall_caps_gas_to_gas_cap() new { stateOverrides = stateOverride } ); - long gasAvailable = (long)ParseReturnValue(response).ToUInt256(); + ulong gasAvailable = (ulong)ParseReturnValue(response).ToUInt256(); Assert.That(gasAvailable, Is.LessThan(gasCap)); - Assert.That(gasAvailable, Is.GreaterThan(0)); + Assert.That(gasAvailable, Is.GreaterThan(0UL)); } [Test] @@ -176,8 +176,8 @@ public async Task Debug_traceCall_without_gas_defaults_to_gas_cap_not_block_gas_ { using Context ctx = await Context.Create(); - long blockGasLimit = ctx.Blockchain.BlockTree.Head!.Header.GasLimit; - long gasCap = blockGasLimit * 10; + ulong blockGasLimit = ctx.Blockchain.BlockTree.Head!.Header.GasLimit; + ulong gasCap = blockGasLimit * 10; IJsonRpcConfig config = ctx.Blockchain.Container.Resolve(); config.GasCap = gasCap; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugSimulateTestsBlocksAndTransactions.cs index 74f85293f3e9..a7a490afa1ca 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugSimulateTestsBlocksAndTransactions.cs @@ -38,7 +38,7 @@ protected override void AssertSerializationBlockResult(SimulateBlockResult().GasCap = gasCap; // Contract: GAS PUSH1 0 MSTORE PUSH1 32 PUSH1 0 RETURN — returns remaining gas diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs index 20ce666bc0b1..e51c9ff377c1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs @@ -124,7 +124,7 @@ public async Task Eth_create_access_list_calculates_proper_gas(bool optimize, lo public async Task Eth_estimate_gas_with_accessList(bool senderAccessList, long gasPriceWithoutAccessList, long gasPriceWithAccessList) { - TestRpcBlockchain test = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).WithConfig(new JsonRpcConfig() { EstimateErrorMargin = 0 }) + TestRpcBlockchain test = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).WithConfig(new JsonRpcConfig() { EstimateErrorMargin = 0, Timeout = -1 }) .Build(new TestSpecProvider(Berlin.Instance)); (byte[] code, AccessListForRpc accessList) = GetTestAccessList(2, senderAccessList); @@ -215,7 +215,7 @@ public async Task Estimate_gas_with_base_fee_opcode() $"{{\"from\": \"{SecondaryTestAddress}\", \"type\": \"0x2\", \"data\": \"{dataStr}\"}}"); string serialized = await ctx.Test.TestEthRpc("eth_estimateGas", transaction); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0xe891\",\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0xe8a9\",\"id\":67}")); } [Test] @@ -333,13 +333,13 @@ public async Task should_estimate_transaction_with_deployed_code_when_eip3607_en "Executes code from state override", """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0xc200000000000000000000000000000000000000","input":"0x60fe47b1112233445566778899001122334455667788990011223344556677889900112233445566778899001122"}""", """{"0xc200000000000000000000000000000000000000":{"code":"0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632a1afcd914603457806360fe47b114604d575b5f80fd5b603b5f5481565b60405190815260200160405180910390f35b605c6058366004605e565b5f55565b005b5f60208284031215606d575f80fd5b503591905056fea2646970667358221220fd4e5f3894be8e57fc7460afebb5c90d96c3486d79bf47b00c2ed666ab2f82b364736f6c634300081a0033"}}""", - """{"jsonrpc":"2.0","result":"0xabdd","id":67}""" // Store uint256 (cold access) + few other light instructions + intrinsic transaction cost + """{"jsonrpc":"2.0","result":"0xac0d","id":67}""" // Store uint256 (cold access) + few other light instructions + intrinsic transaction cost )] [TestCase( "Executes precompile using overridden address", """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0xc200000000000000000000000000000000000000","input":"0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4000000000000000000000000000000000000000000000000000000000000001C7B8B1991EB44757BC688016D27940DF8FB971D7C87F77A6BC4E938E3202C44037E9267B0AEAA82FA765361918F2D8ABD9CDD86E64AA6F2B81D3C4E0B69A7B055"}""", """{"0x0000000000000000000000000000000000000001":{"movePrecompileToAddress":"0xc200000000000000000000000000000000000000", "code": "0x"}}""", - """{"jsonrpc":"2.0","result":"0x6440","id":67}""" // ECRecover call + intrinsic transaction cost + """{"jsonrpc":"2.0","result":"0x6608","id":67}""" // ECRecover call + intrinsic transaction cost )] public async Task Estimate_gas_with_state_override(string name, string transactionJson, string stateOverrideJson, string expectedResult) { @@ -392,15 +392,19 @@ public async Task Estimate_gas_with_state_override_does_not_affect_other_calls(s [Test] public async Task Estimate_gas_uses_block_gas_limit_when_not_specified() { - using Context ctx = await Context.Create(); + using Context ctx = await Context.Create(configurer: builder => builder + .WithGenesisPostProcessor((block, worldState) => + { + block.Header.GasLimit = 100000; + })); string blockNumberResponse = await ctx.Test.TestEthRpc("eth_blockNumber"); string blockNumber = JToken.Parse(blockNumberResponse).Value("result")!; string blockResponse = await ctx.Test.TestEthRpc("eth_getBlockByNumber", blockNumber, false); - long blockGasLimit = Convert.ToInt64(JToken.Parse(blockResponse).SelectToken("result.gasLimit")!.Value(), 16); + ulong blockGasLimit = Convert.ToUInt64(JToken.Parse(blockResponse).SelectToken("result.gasLimit")!.Value(), 16); // gasCap above blockGasLimit — estimate should be bounded by blockGasLimit, not gasCap (matches Geth) - ctx.Test.RpcConfig.GasCap = blockGasLimit + 1_000_000; + ctx.Test.RpcConfig.GasCap = blockGasLimit + 100000; await TestEstimateGasOutOfGas(ctx, null, blockGasLimit, $"gas required exceeds allowance ({blockGasLimit})"); } @@ -424,16 +428,20 @@ public async Task Estimate_gas_not_limited_by_latest_block_gas_used() [Test] public async Task Estimate_gas_uses_specified_gas_limit() { - using Context ctx = await Context.Create(); - await TestEstimateGasOutOfGas(ctx, 30000000, 30000000, $"gas required exceeds allowance ({30000000})"); + using Context ctx = await Context.Create(configurer: builder => builder + .WithGenesisPostProcessor((block, worldState) => + { + block.Header.GasLimit = 100000; + })); + await TestEstimateGasOutOfGas(ctx, 100000, 100000, $"gas required exceeds allowance ({100000})"); } [Test] public async Task Estimate_gas_cannot_exceed_gas_cap() { using Context ctx = await Context.Create(); - ctx.Test.RpcConfig.GasCap = 50000000; - await TestEstimateGasOutOfGas(ctx, 300000000, 50000000, $"gas required exceeds allowance ({50000000})"); + ctx.Test.RpcConfig.GasCap = 100000; + await TestEstimateGasOutOfGas(ctx, 300000000, 100000, $"gas required exceeds allowance ({100000})"); } [Test] @@ -546,49 +554,49 @@ public async Task Eth_estimateGas_returns_execution_reverted_when_gas_price_set_ private static IEnumerable EstimateGasFloorCostCases() { // EIP-7976: 100 zero bytes → floor = 21000 + 100 * 4 * 16 = 27400 - long eip7976Floor100 = GasCostOf.Transaction + 100 * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; - yield return new TestCaseData(Eip7976Spec, new byte[100], 100_000L, null, + ulong eip7976Floor100 = GasCostOf.Transaction + 100UL * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; + yield return new TestCaseData(Eip7976Spec, new byte[100], 100_000UL, null, $"{{\"jsonrpc\":\"2.0\",\"result\":\"{eip7976Floor100.ToHexString(true)}\",\"id\":67}}") .SetName("EIP-7976: data heavy tx returns floor cost"); // EIP-7623: 100 zero bytes → floor = 21000 + 100 * 10 = 22000 - long eip7623Floor100 = GasCostOf.Transaction + 100 * Prague.Instance.GasCosts.TotalCostFloorPerToken; - yield return new TestCaseData(Prague.Instance, new byte[100], 100_000L, null, + ulong eip7623Floor100 = GasCostOf.Transaction + 100UL * Prague.Instance.GasCosts.TotalCostFloorPerToken; + yield return new TestCaseData(Prague.Instance, new byte[100], 100_000UL, null, $"{{\"jsonrpc\":\"2.0\",\"result\":\"{eip7623Floor100.ToHexString(true)}\",\"id\":67}}") .SetName("EIP-7623: data heavy tx returns lower floor"); // EIP-7976: intrinsic gas too low - const long belowFloor = GasCostOf.Transaction + GasCostOf.TxDataZero; - long eip7976Floor1Byte = GasCostOf.Transaction + 1 * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; + const ulong belowFloor = GasCostOf.Transaction + GasCostOf.TxDataZero; + ulong eip7976Floor1Byte = GasCostOf.Transaction + 1UL * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; yield return new TestCaseData(Eip7976Spec, new byte[] { 0 }, belowFloor, null, $"{{\"jsonrpc\":\"2.0\",\"error\":{{\"code\":-32000,\"message\":\"intrinsic gas too low: have {belowFloor}, want {eip7976Floor1Byte}\"}},\"id\":67}}") .SetName("EIP-7976: insufficient gas for floor"); // EIP-7976: mixed calldata (0x00001122 = 2 zero + 2 nonzero bytes) - long eip7976Floor4 = GasCostOf.Transaction + 4 * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; - yield return new TestCaseData(Eip7976Spec, new byte[] { 0x00, 0x00, 0x11, 0x22 }, 100_000L, null, + ulong eip7976Floor4 = GasCostOf.Transaction + 4UL * Eip7976Spec.GasCosts.TxDataNonZeroMultiplier * Eip7976Spec.GasCosts.TotalCostFloorPerToken; + yield return new TestCaseData(Eip7976Spec, new byte[] { 0x00, 0x00, 0x11, 0x22 }, 100_000UL, null, $"{{\"jsonrpc\":\"2.0\",\"result\":\"{eip7976Floor4.ToHexString(true)}\",\"id\":67}}") .SetName("EIP-7976: mixed calldata returns floor"); // EIP-7981: access list with 1 address, no calldata — standard wins - long eip7981Standard = GasCostOf.Transaction + GasCostOf.AccessAccountListEntry - + 80 * Eip7981Spec.GasCosts.TotalCostFloorPerToken; - yield return new TestCaseData(Eip7981Spec, Array.Empty(), 100_000L, + ulong eip7981Standard = GasCostOf.Transaction + GasCostOf.AccessAccountListEntry + + 80UL * Eip7981Spec.GasCosts.TotalCostFloorPerToken; + yield return new TestCaseData(Eip7981Spec, Array.Empty(), 100_000UL, new AccessList.Builder().AddAddress(Address.Zero).Build(), $"{{\"jsonrpc\":\"2.0\",\"result\":\"{eip7981Standard.ToHexString(true)}\",\"id\":67}}") .SetName("EIP-7981: standard wins with access list"); // EIP-7981: 100 zero bytes + 1 address — floor wins - long eip7981Floor = GasCostOf.Transaction - + (100 * Eip7981Spec.GasCosts.TxDataNonZeroMultiplier + 80) * Eip7981Spec.GasCosts.TotalCostFloorPerToken; - yield return new TestCaseData(Eip7981Spec, new byte[100], 100_000L, + ulong eip7981Floor = GasCostOf.Transaction + + (100UL * Eip7981Spec.GasCosts.TxDataNonZeroMultiplier + 80UL) * Eip7981Spec.GasCosts.TotalCostFloorPerToken; + yield return new TestCaseData(Eip7981Spec, new byte[100], 100_000UL, new AccessList.Builder().AddAddress(Address.Zero).Build(), $"{{\"jsonrpc\":\"2.0\",\"result\":\"{eip7981Floor.ToHexString(true)}\",\"id\":67}}") .SetName("EIP-7981: floor wins with calldata and access list"); } [TestCaseSource(nameof(EstimateGasFloorCostCases))] - public async Task Eth_estimateGas_floor_cost(IReleaseSpec spec, byte[] data, long gasLimit, AccessList? accessList, string expectedJson) + public async Task Eth_estimateGas_floor_cost(IReleaseSpec spec, byte[] data, ulong gasLimit, AccessList? accessList, string expectedJson) { TestSpecProvider specProvider = new(spec); using Context ctx = await Context.Create(specProvider); @@ -609,7 +617,7 @@ public async Task Eth_estimateGas_floor_cost(IReleaseSpec spec, byte[] data, lon Assert.That(serialized, Is.EqualTo(expectedJson)); } - private static async Task TestEstimateGasOutOfGas(Context ctx, long? specifiedGasLimit, long expectedGasLimit, string message) + private static async Task TestEstimateGasOutOfGas(Context ctx, ulong? specifiedGasLimit, ulong expectedGasLimit, string message) { string gasParam = specifiedGasLimit.HasValue ? $", \"gas\": \"0x{specifiedGasLimit.Value:X}\"" : ""; TransactionForRpc transaction = ctx.Test.JsonSerializer.Deserialize( diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index a29d4be1fc04..f2f5f20b7f79 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -509,7 +509,7 @@ public async Task Eth_call_cannot_exceed_gas_cap() public async Task Eth_call_gas_available_is_capped_by_gas_cap() { using Context ctx = await Context.Create(); - long gasCap = 50_000; + ulong gasCap = 50_000; ctx.Test.RpcConfig.GasCap = gasCap; // Contract: GAS PUSH1 0 MSTORE PUSH1 32 PUSH1 0 RETURN @@ -524,12 +524,12 @@ public async Task Eth_call_gas_available_is_capped_by_gas_cap() string serialized = await ctx.Test.TestEthRpc("eth_call", transaction, "latest", stateOverride); string result = JToken.Parse(serialized).Value("result")!; - long gasAvailable = (long)Bytes.FromHexString(result).ToUInt256(); + ulong gasAvailable = (ulong)Bytes.FromHexString(result).ToUInt256(); // gas available = gasLimit - intrinsicGas; if gas cap works, gasLimit ≤ 50K so gas available < 50K // Without gas cap, gas available would be ~79K (100K - 21K intrinsic) Assert.That(gasAvailable, Is.LessThan(gasCap)); - Assert.That(gasAvailable, Is.GreaterThan(0)); + Assert.That(gasAvailable, Is.GreaterThan(0UL)); } /// @@ -545,9 +545,9 @@ public async Task Eth_call_without_gas_defaults_to_gas_cap_not_block_gas_limit() string blockNumberResponse = await ctx.Test.TestEthRpc("eth_blockNumber"); string blockNumber = JToken.Parse(blockNumberResponse).Value("result")!; string blockResponse = await ctx.Test.TestEthRpc("eth_getBlockByNumber", blockNumber, false); - long blockGasLimit = Convert.ToInt64(JToken.Parse(blockResponse).SelectToken("result.gasLimit")!.Value(), 16); + ulong blockGasLimit = Convert.ToUInt64(JToken.Parse(blockResponse).SelectToken("result.gasLimit")!.Value(), 16); - long gasCap = blockGasLimit * 10; + ulong gasCap = blockGasLimit * 10; ctx.Test.RpcConfig.GasCap = gasCap; // Contract: GAS PUSH1 0 MSTORE PUSH1 32 PUSH1 0 RETURN @@ -798,7 +798,7 @@ public async Task Eth_call_non_existent_block_returns_not_found() Assert.That(JToken.Parse(serialized)["error"]!["message"]!.Value(), Is.EqualTo("header not found")); } - private static async Task TestEthCallOutOfGas(Context ctx, long? specifiedGasLimit) + private static async Task TestEthCallOutOfGas(Context ctx, ulong? specifiedGasLimit) { string gasParam = specifiedGasLimit.HasValue ? $", \"gas\": \"0x{specifiedGasLimit.Value:X}\"" : ""; TransactionForRpc transaction = ctx.Test.JsonSerializer.Deserialize( diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs index 360435929d5a..eed063444676 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs @@ -41,7 +41,7 @@ public async Task Eth_feeHistory(long blockCount, string blockParameter, string Block[] blocks = Enumerable.Range(0, excessBlobGas.Length) .Select((i) => Build.A.Block.WithHeader( Build.A.BlockHeader - .WithNumber(i) + .WithNumber((ulong)i) .WithParentHash(new Hash256(Math.Max(0, i - 1).ToString("X").PadLeft(64, '0'))) .WithExcessBlobGas(excessBlobGas[i]) .WithBlobGasUsed(blobGasUsed[i]) @@ -50,10 +50,10 @@ public async Task Eth_feeHistory(long blockCount, string blockParameter, string IBlockTree blockFinder = Substitute.For(); - blockFinder.Head.Returns(Build.A.Block.WithNumber(excessBlobGas.Length - 1).TestObject); + blockFinder.Head.Returns(Build.A.Block.WithNumber((ulong)(excessBlobGas.Length - 1)).TestObject); blockFinder.FindBlock(Arg.Any(), Arg.Any()) .Returns(ci => blocks[(int)(((BlockParameter)ci[0]).BlockNumber ?? 0)]); - blockFinder.FindBlock(Arg.Any(), Arg.Any(), Arg.Any()) + blockFinder.FindBlock(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(ci => blocks[((Hash256)ci[0]).Bytes[^1]]); IReceiptStorage receiptStorage = Substitute.For(); @@ -61,7 +61,7 @@ public async Task Eth_feeHistory(long blockCount, string blockParameter, string FeeHistoryOracle oracle = new(blockFinder, receiptStorage, specProvider); using ResultWrapper result = oracle - .GetFeeHistory(excessBlobGas.Length, new BlockParameter(blocks.Length - 1), [0.0, 1.0]); + .GetFeeHistory((ulong)excessBlobGas.Length, new BlockParameter((ulong)(blocks.Length - 1)), [0.0, 1.0]); Assert.That(result.ErrorCode, Is.Zero); return (result.Data.BaseFeePerBlobGas.ToArray(), result.Data.BlobGasUsedRatio.ToArray()); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.GasPrice.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.GasPrice.cs index 1ae01f097489..403ca812fb91 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.GasPrice.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.GasPrice.cs @@ -54,7 +54,7 @@ public async Task Eth_blobBaseFee_ShouldGiveCorrectResult(ulong? excessB } [TestCaseSource(nameof(GetBaseFeeTestCases))] - public async Task Eth_baseFee_ShouldGiveCorrectResult(UInt256 baseFeePerGas, long gasLimit, long gasUsed, ISpecProvider specProvider) + public async Task Eth_baseFee_ShouldGiveCorrectResult(UInt256 baseFeePerGas, ulong gasLimit, ulong gasUsed, ISpecProvider specProvider) { using Context ctx = await Context.Create(specProvider); Block[] blocks = [ @@ -73,22 +73,22 @@ public static IEnumerable GetBaseFeeTestCases static string Success(UInt256 result) => $"{{\"jsonrpc\":\"2.0\",\"result\":\"{result.ToHexString(true)}\",\"id\":67}}"; const string NullResult = "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}"; - yield return new TestCaseData(UInt256.Zero, 30_000_000L, 0L, GetSpecProviderWithEip1559EnabledAs(false)) + yield return new TestCaseData(UInt256.Zero, 30_000_000UL, 0UL, GetSpecProviderWithEip1559EnabledAs(false)) { TestName = "Pre-London block returns null", ExpectedResult = NullResult }; - yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000L, 15_000_000L, new TestSpecProvider(London.Instance)) + yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000UL, 15_000_000UL, new TestSpecProvider(London.Instance)) { TestName = "Block at gas target returns same base fee", ExpectedResult = Success(1_000_000_000) }; - yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000L, 30_000_000L, new TestSpecProvider(London.Instance)) + yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000UL, 30_000_000UL, new TestSpecProvider(London.Instance)) { TestName = "Block over gas target increases base fee by 12.5%", ExpectedResult = Success(1_125_000_000) }; - yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000L, 0L, new TestSpecProvider(London.Instance)) + yield return new TestCaseData((UInt256)1_000_000_000, 30_000_000UL, 0UL, new TestSpecProvider(London.Instance)) { TestName = "Block under gas target decreases base fee by 12.5%", ExpectedResult = Success(875_000_000) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.SignTransaction.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.SignTransaction.cs index e35bb07543bd..4602ab3ed7d1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.SignTransaction.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.SignTransaction.cs @@ -84,7 +84,7 @@ public async Task SignTransaction_WhenBlobTxMissingCommitments_ReturnsInvalidInp From = new Address(UnlockedTestAccount), To = new Address("0x2d44c0e097f6cd0f514edac633d82e01280b4a5c"), Gas = 0x76c0, - Nonce = (UInt256)0, + Nonce = 0UL, MaxFeePerGas = (UInt256)0x9184e72a000, MaxPriorityFeePerGas = (UInt256)0x3b9aca00, MaxFeePerBlobGas = (UInt256)1_000_000, @@ -142,8 +142,8 @@ public async Task SignTransaction_WhenValid_RawRoundTripsAndTxEcho(TxType type, RlpBehaviors.AllowUnsigned | RlpBehaviors.SkipTypedWrapping | RlpBehaviors.InMempoolForm); Assert.That(decoded.Type, Is.EqualTo(type), "type must round-trip through RLP encode/decode"); - Assert.That(decoded.GasLimit, Is.EqualTo(0x76c0L), "gas must round-trip exactly - caller provided it explicitly"); - Assert.That(decoded.Nonce, Is.EqualTo((UInt256)0), "nonce must round-trip - caller provided it explicitly"); + Assert.That(decoded.GasLimit, Is.EqualTo(0x76c0UL), "gas must round-trip exactly - caller provided it explicitly"); + Assert.That(decoded.Nonce, Is.EqualTo(0UL), "nonce must round-trip - caller provided it explicitly"); Address recovered = new EthereumEcdsa(decoded.ChainId ?? 1).RecoverAddress(decoded)!; Assert.That(recovered, Is.EqualTo(new Address(UnlockedTestAccount)), @@ -218,8 +218,8 @@ private static TransactionForRpc BuildTx(TxType type, string? omitField = null, Address to = new("0x2d44c0e097f6cd0f514edac633d82e01280b4a5c"); UInt256 value = 0x9184e72a; - long gas = 0x76c0; - UInt256 nonce = 0; + ulong gas = 0x76c0; + ulong nonce = 0; UInt256 gasPrice = 0x9184e72a000; return type switch diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index d73946786244..6355849558f8 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -1314,10 +1314,10 @@ public async Task Eth_tx_count_by_number(string blockParameter, string expectedR Assert.That(serialized, Is.EqualTo($"{{\"jsonrpc\":\"2.0\",\"result\":{expectedResult},\"id\":67}}")); } - [TestCase(false, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x16af125b31ba6f33725bffd77d8778121c8b24c3c29a9821d2fc15049a5bdcb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(false, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x16af125b31ba6f33725bffd77d8778121c8b24c3c29a9821d2fc15049a5bdcb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xfe8fcd8ff04b74f0c044d2cd424bea426591ea069e839eae3f4e7743c92fa389\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xfe8fcd8ff04b74f0c044d2cd424bea426591ea069e839eae3f4e7743c92fa389\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] public async Task Eth_get_block_by_hash(bool aura, bool eip1559, string expected) { using Context ctx = eip1559 ? await Context.CreateWithLondonEnabled() : await Context.Create(); @@ -1343,13 +1343,13 @@ public async Task Eth_get_block_by_hash_with_tx(string blockParameter, bool with Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expectedResult)).Using(JToken.EqualityComparer)); } - [TestCase(false, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[{\"hash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"nonce\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x0\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"},{\"hash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"nonce\":\"0x2\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"}],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "pending", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":null,\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":null,\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[{\"hash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"nonce\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x0\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"},{\"hash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"nonce\":\"0x2\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"}],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] - [TestCase(false, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x7a1200\",\"gasUsed\":\"0x0\",\"hash\":\"0x16b111d85efa64c1c8e27f1e59c8ccd6bb6643b1999628ac37294c31158e2245\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x761cfe357802c8a2a68e37ad8325607920e72ce19b5b0d3e1ba01840f7e905ec\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x20b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"baseFeePerGas\":\"0x2da282a8\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x7a1200\",\"gasUsed\":\"0x0\",\"hash\":\"0x16b111d85efa64c1c8e27f1e59c8ccd6bb6643b1999628ac37294c31158e2245\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x761cfe357802c8a2a68e37ad8325607920e72ce19b5b0d3e1ba01840f7e905ec\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x20b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"baseFeePerGas\":\"0x2da282a8\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "0x20", "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}")] public async Task Eth_get_block_by_number(bool eip1559, string blockParameter, string expectedResult) { @@ -1358,10 +1358,10 @@ public async Task Eth_get_block_by_number(bool eip1559, string blockParameter, s Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expectedResult)).Using(JToken.EqualityComparer)); } - [TestCase("earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase("earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase("latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\"],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] [TestCase("pending", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":null,\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":null,\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\"],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] - [TestCase("0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase("0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase("0x20", "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}")] public async Task Eth_get_block_by_number_no_details(string blockParameter, string expectedResult) { @@ -1476,7 +1476,7 @@ public async Task EthGetHeaderByNumber_WhenEarliest_MatchesExpectedJson() string serialized = await ctx.Test.TestEthRpc("eth_getHeaderByNumber", "earliest"); // Same value set as the genesis row in Eth_get_block_by_number "earliest", minus // size/totalDifficulty/transactions/uncles (header endpoint excludes body-level fields). - const string expected = "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"timestamp\":\"0xf4240\",\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\"},\"id\":67}"; + const string expected = "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"timestamp\":\"0xf4240\",\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\"},\"id\":67}"; Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expected)).Using(JToken.EqualityComparer)); } @@ -1647,7 +1647,7 @@ public async Task Eth_get_block_by_number_with_recovering_sender_from_receipts() IReceiptFinder receiptFinder = Substitute.For(); Block block = Build.A.Block.WithNumber(1) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .WithTransactions(Build.A.Transaction.TestObject) .TestObject; @@ -1667,7 +1667,7 @@ public async Task Eth_get_block_by_number_with_recovering_sender_from_receipts() ctx.Test = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).WithBlockFinder(blockFinder).WithReceiptFinder(receiptFinder).Build(); string serialized = await ctx.Test.TestEthRpc("eth_getBlockByNumber", TestItem.KeccakA.ToString(), "true"); - Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse("""{"jsonrpc":"2.0","result":{"difficulty":"0xf4240","extraData":"0x010203","gasLimit":"0x3d0900","gasUsed":"0x0","hash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2","nonce":"0x00000000000003e8","number":"0x1","parentHash":"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x221","stateRoot":"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f","timestamp":"0xf4240","transactions":[{"nonce":"0x0","blockHash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","blockNumber":"0x1","blockTimestamp":"0xf4240","transactionIndex":"0x0","from":"0x2d36e6c27c34ea22620e7b7c45de774599406cf3","to":"0x0000000000000000000000000000000000000000","value":"0x1","gasPrice":"0x1","gas":"0x5208","input":"0x","type":"0x0","v":"0x0","r":"0x0","s":"0x0","hash":null}],"transactionsRoot":"0x29cc403075ed3d1d6af940d577125cc378ee5a26f7746cbaf87f1cf4a38258b5","uncles":[]},"id":67}""")).Using(JToken.EqualityComparer)); + Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse("""{"jsonrpc":"2.0","result":{"difficulty":"0xf4240","extraData":"0x010203","gasLimit":"0x3d0900","gasUsed":"0x0","hash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2","nonce":"0x00000000000003e8","number":"0x1","parentHash":"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x221","stateRoot":"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f","timestamp":"0xf4240","transactions":[{"nonce":"0x0","blockHash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","blockNumber":"0x1","blockTimestamp":"0xf4240","transactionIndex":"0x0","from":"0x2d36e6c27c34ea22620e7b7c45de774599406cf3","to":"0x0000000000000000000000000000000000000000","value":"0x1","gasPrice":"0x1","gas":"0x5208","input":"0x","type":"0x0","v":"0x0","r":"0x0","s":"0x0","hash":null}],"transactionsRoot":"0x29cc403075ed3d1d6af940d577125cc378ee5a26f7746cbaf87f1cf4a38258b5","uncles":[]},"id":67}""")).Using(JToken.EqualityComparer)); } [TestCase(false)] @@ -1681,7 +1681,7 @@ public async Task Eth_get_transaction_receipt(bool postEip4844) Block block = Build.A.Block.WithNumber(1) .WithTimestamp(10) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .TestObject; LogEntry[] entries = new[] @@ -1719,14 +1719,14 @@ public async Task Eth_get_transaction_receipt_when_block_has_few_receipts() IBlockFinder blockFinder = Substitute.For(); IReceiptFinder receiptFinder = Substitute.For(); - int blockNumber = 1; + ulong blockNumber = 1; ulong timestamp = 10; Block genesis = Build.A.Block.Genesis - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .TestObject; Block previousBlock = genesis; Block block = Build.A.Block.WithNumber(blockNumber).WithParent(previousBlock).WithTimestamp(timestamp) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .TestObject; LogEntry[] logEntries = new[] { Build.A.LogEntry.TestObject, Build.A.LogEntry.TestObject }; @@ -1793,7 +1793,7 @@ public async Task Eth_getTransactionReceipt_return_info_about_mined_tx() ulong timestamp = 10; Block block = Build.A.Block.WithNumber(1).WithTimestamp(timestamp) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .WithTransactions(tx) .TestObject; @@ -2072,7 +2072,7 @@ public async Task Eth_create_access_list_sample(AccessListProvided accessListPro public async Task Eth_createAccessList_cannot_exceed_gas_cap() { TestRpcBlockchain test = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(new TestSpecProvider(Berlin.Instance)); - long gasCap = 60_000; + ulong gasCap = 60_000; test.RpcConfig.GasCap = gasCap; // Contract creation with infinite loop; gas 200K should be capped to 60K @@ -2081,7 +2081,7 @@ public async Task Eth_createAccessList_cannot_exceed_gas_cap() string serialized = await test.TestEthRpc("eth_createAccessList", transaction, "latest", null, true); - long gasUsed = Convert.ToInt64(JToken.Parse(serialized).SelectToken("result.gasUsed")!.Value(), 16); + ulong gasUsed = Convert.ToUInt64(JToken.Parse(serialized).SelectToken("result.gasUsed")!.Value(), 16); Assert.That(gasUsed, Is.LessThanOrEqualTo(gasCap)); } @@ -2090,8 +2090,8 @@ public async Task Eth_createAccessList_without_gas_defaults_to_gas_cap_not_block { using Context ctx = await Context.Create(); - long blockGasLimit = ctx.Test.BlockTree.FindHeadBlock()!.Header.GasLimit; - long gasCap = blockGasLimit + 500_000; + ulong blockGasLimit = ctx.Test.BlockTree.FindHeadBlock()!.Header.GasLimit; + ulong gasCap = blockGasLimit + 500_000; ctx.Test.RpcConfig.GasCap = gasCap; // Inject infinite-loop contract — with no gas field it should consume all of gasCap, not blockGasLimit @@ -2104,7 +2104,7 @@ public async Task Eth_createAccessList_without_gas_defaults_to_gas_cap_not_block string serialized = await ctx.Test.TestEthRpc("eth_createAccessList", transaction, "latest", stateOverride, false); - long gasUsed = Convert.ToInt64(JToken.Parse(serialized).SelectToken("result.gasUsed")!.Value(), 16); + ulong gasUsed = Convert.ToUInt64(JToken.Parse(serialized).SelectToken("result.gasUsed")!.Value(), 16); Assert.That(gasUsed, Is.GreaterThan(blockGasLimit), $"gas used ({gasUsed}) should reflect gasCap ({gasCap}), not block gas limit ({blockGasLimit})"); } @@ -2231,14 +2231,14 @@ public async Task Eth_createAccessList_optimize_false_includes_sender_in_access_ } [TestCase(null)] - [TestCase(0L)] - public static void ToTransaction_uses_long_max_when_gasCap_is_null_or_zero(long? gasCap) + [TestCase(0UL)] + public static void ToTransaction_uses_ulong_max_when_gasCap_is_null_or_zero(ulong? gasCap) { LegacyTransactionForRpc rpcTx = new(); Transaction tx = (Transaction)rpcTx.ToTransaction(gasCap: gasCap); - Assert.That(tx.GasLimit, Is.EqualTo(long.MaxValue), "GasLimit must default to long.MaxValue when gasCap is null or 0"); + Assert.That(tx.GasLimit, Is.EqualTo(ulong.MaxValue), "GasLimit must default to ulong.MaxValue when gasCap is null or 0"); } [Test] @@ -2251,22 +2251,22 @@ public static void ToTransaction_defaults_sender_to_zero_when_from_is_null() Assert.That(tx.SenderAddress, Is.EqualTo(Address.Zero), "SenderAddress must default to Address.Zero when From is null"); } - [TestCase(null, null, long.MaxValue)] - [TestCase(null, 0L, long.MaxValue)] - [TestCase(null, 1_000_000L, 1_000_000L)] - [TestCase(0L, null, 0L)] - [TestCase(0L, 1_000_000L, 0L)] - [TestCase(50_000L, null, 50_000L)] - [TestCase(50_000L, 0L, 50_000L)] - [TestCase(50_000L, 100_000L, 50_000L)] - [TestCase(200_000L, 100_000L, 100_000L)] - public static void ToTransaction_caps_and_defaults_gas(long? gas, long? gasCap, long expectedGasLimit) + [TestCase(null, null, ulong.MaxValue)] + [TestCase(null, 0UL, ulong.MaxValue)] + [TestCase(null, 1_000_000UL, 1_000_000UL)] + [TestCase(0UL, null, 0UL)] + [TestCase(0UL, 1_000_000UL, 0UL)] + [TestCase(50_000UL, null, 50_000UL)] + [TestCase(50_000UL, 0UL, 50_000UL)] + [TestCase(50_000UL, 100_000UL, 50_000UL)] + [TestCase(200_000UL, 100_000UL, 100_000UL)] + public static void ToTransaction_caps_and_defaults_gas(ulong? gas, ulong? gasCap, object expectedGasLimit) { LegacyTransactionForRpc rpcTx = new() { Gas = gas }; Transaction tx = (Transaction)rpcTx.ToTransaction(gasCap: gasCap); - Assert.That(tx.GasLimit, Is.EqualTo(expectedGasLimit)); + Assert.That(tx.GasLimit, Is.EqualTo(Convert.ToUInt64(expectedGasLimit))); } [Test] @@ -2277,7 +2277,7 @@ public async Task eth_getBlockByNumber_should_return_withdrawals_correctly() IReceiptFinder receiptFinder = Substitute.For(); Block block = Build.A.Block.WithNumber(1) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .WithTransactions(new[] { Build.A.Transaction.TestObject }) .WithWithdrawals(new[] { Build.A.Withdrawal.WithAmount(1_000).TestObject }) .TestObject; @@ -2346,7 +2346,7 @@ public async Task eth_sendRawTransaction_sender_with_delegated_code_is_accepted( .WithMaxFeePerGas(9.GWei) .WithMaxPriorityFeePerGas(9.GWei) .WithGasLimit(GasCostOf.Transaction + GasCostOf.NewAccount) - .WithAuthorizationCode(test.EthereumEcdsa.Sign(TestItem.PrivateKeyB, 0, TestItem.AddressC, (ulong)test.ReadOnlyState.GetNonce(TestItem.AddressB) + 1)) + .WithAuthorizationCode(test.EthereumEcdsa.Sign(TestItem.PrivateKeyB, 0, TestItem.AddressC, test.ReadOnlyState.GetNonce(TestItem.AddressB) + 1)) .WithTo(TestItem.AddressA) .SignedAndResolved(TestItem.PrivateKeyB).TestObject; @@ -2693,11 +2693,11 @@ public static async Task CreateWithAmsterdamEnabled() return await Create(specProvider); } - public static async Task CreateWithAncientBarriers(long blockNumber) => await Create(configurer: builder => + public static async Task CreateWithAncientBarriers(ulong blockNumber) => await Create(configurer: builder => { builder.AddDecorator((_, config) => { - long cutBlock = blockNumber; + ulong cutBlock = blockNumber; config.AncientBodiesBarrier = cutBlock; config.AncientReceiptsBarrier = cutBlock; config.PivotNumber = cutBlock; @@ -2720,7 +2720,7 @@ public static Task Create(ISpecProvider? specProvider = null, { TestFactory = () => TestRpcBlockchain.ForTest(SealEngineType.NethDev) .WithBlockchainBridge(blockchainBridge!) - .WithConfig(new JsonRpcConfig { EstimateErrorMargin = 0 }) + .WithConfig(new JsonRpcConfig { EstimateErrorMargin = 0, Timeout = -1 }) .WithBlocksConfig(new BlocksConfig() { ParallelExecution = false }) .Build(wrappedConfigurer).Result, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index 766d0c8a07ec..62e611ca9149 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -91,8 +91,8 @@ public static async Task
DeployECRecoverContract(TestRpcBlockchain chai byte[] bytecode = Bytes.FromHexString(contractBytecode); Transaction tx = new() { - Value = UInt256.Zero, - Nonce = 0, + Value = 0UL, + Nonce = 0UL, Data = bytecode, GasLimit = 3_000_000, SenderAddress = privateKey.Address, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index a591d8ed98a0..d9bd97de2efa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -30,9 +30,9 @@ public class EthSimulateTestsBlocksAndTransactions { public static SimulatePayload CreateSerializationPayload(TestRpcBlockchain chain) { - UInt256 nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction txToFail = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 10_000_000); - UInt256 nextNonceA = ++nonceA; + ulong nextNonceA = ++nonceA; Transaction tx = GetTransferTxData(nextNonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 4_000_000); return new() @@ -54,7 +54,7 @@ public static SimulatePayload CreateSerializationPayload(Test }; } - public static SimulatePayload CreateEthMovedPayload(TestRpcBlockchain chain, UInt256 nonceA) + public static SimulatePayload CreateEthMovedPayload(TestRpcBlockchain chain, ulong nonceA) { Transaction txAtoB1 = GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); @@ -70,7 +70,7 @@ public static SimulatePayload CreateEthMovedPayload(TestRpcBl BlockOverrides = new BlockOverride { - Number = (ulong)chain.BlockFinder.Head!.Number+2, + Number = chain.BlockFinder.Head!.Number + 2, GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -82,7 +82,7 @@ public static SimulatePayload CreateEthMovedPayload(TestRpcBl BlockOverrides = new BlockOverride { - Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10), + Number = checked(chain.Bridge.HeadBlock.Number + 10), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -103,7 +103,7 @@ private static TransactionForRpc ToRpcForInput(Transaction tx) return rpc; } - public static SimulatePayload CreateTransactionsForcedFail(TestRpcBlockchain chain, UInt256 nonceA) + public static SimulatePayload CreateTransactionsForcedFail(TestRpcBlockchain chain, ulong nonceA) { //shall be Ok Transaction txAtoB1 = @@ -127,7 +127,7 @@ public static SimulatePayload CreateTransactionsForcedFail(Te BlockOverrides = new BlockOverride { - Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10), + Number = checked(chain.Bridge.HeadBlock.Number + 10), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -152,18 +152,18 @@ public static SimulatePayload CreateTransactionsForcedFail(Te }; } - public static Transaction GetTransferTxData(UInt256 nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey from, Address to, UInt256 amount, TxType type = TxType.EIP1559) + public static Transaction GetTransferTxData(ulong nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey from, Address to, UInt256 amount, TxType type = TxType.EIP1559) { Transaction tx = new() { Type = type, - Value = amount, + Value = amount > ulong.MaxValue ? ulong.MaxValue : (ulong)amount, Nonce = nonce, GasLimit = 50_000, SenderAddress = from.Address, To = to, GasPrice = 20.GWei, - DecodedMaxFeePerGas = type >= TxType.EIP1559 ? 20.GWei : 0 + DecodedMaxFeePerGas = type >= TxType.EIP1559 ? (ulong)20.GWei : 0UL }; ethereumEcdsa.Sign(from, tx); @@ -206,7 +206,7 @@ public async Task Test_eth_simulate_eth_moved() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - UInt256 nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1, type: TxType.Legacy); SimulatePayload payload = CreateEthMovedPayload(chain, nonceA); @@ -245,7 +245,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - UInt256 nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1, type: TxType.Legacy); @@ -315,7 +315,7 @@ public static SimulatePayload CreateTransferLogsAddressPayloa public async Task Test_eth_simulate_caps_gas_to_gas_cap() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - long gasCap = 50_000; + ulong gasCap = 50_000; chain.RpcConfig.GasCap = gasCap; // Contract: GAS PUSH1 0 MSTORE PUSH1 32 PUSH1 0 RETURN — returns remaining gas @@ -656,7 +656,7 @@ public async Task Test_eth_simulateV1_block_override_time_is_seen_by_timestamp_o Validation = true }; - private static SimulatePayload NoncePayload(UInt256 accountNonce, UInt256 txNonce) => new() + private static SimulatePayload NoncePayload(ulong accountNonce, ulong txNonce) => new() { BlockStateCalls = [ diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index fd857c8506b3..1c8ae8317bb5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -105,7 +105,7 @@ public async Task TestsimulateHive(string name, bool shouldSucceed, string data) [Combinatorial] public async Task TestSimulate_TimestampIsComputedCorrectly_WhenNoTimestampOverride( [Values(2, 12)] int secondsPerSlot, - [Values(0, 1, 2, 5)] int blockNumber) + [Values(0u, 1u, 2u, 5u)] uint blockNumber) { string data = $$""" { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs index 17de947c9a89..466cbeba7641 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs @@ -48,19 +48,19 @@ public void GetFeeHistory_HashParameter_ReturnsFailingWrapper() public void GetFeeHistory_NewestBlockIsNull_ReturnsFailingWrapper() { IBlockTree blockTree = Substitute.For(); - blockTree.FindBlock(Arg.Any()).Returns((Block?)null); + blockTree.FindBlock(Arg.Any()).Returns((Block?)null); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree); ResultWrapper expected = ResultWrapper.Fail("upstream does not have the requested block yet", ErrorCodes.InternalError); - using ResultWrapper resultWrapper = feeHistoryOracle.GetFeeHistory(1, new BlockParameter((long)0), []); + using ResultWrapper resultWrapper = feeHistoryOracle.GetFeeHistory(1, new BlockParameter(0UL), []); Assert.That(resultWrapper, Is.EqualTo(expected).UsingPropertiesComparer()); } - [TestCase(3, 5)] - [TestCase(4, 10)] - [TestCase(0, 1)] - public void GetFeeHistory_IfPendingBlockDoesNotExistAndLastBlockNumberGreaterThanHeadNumber_ReturnsError(long pendingBlockNumber, long lastBlockNumber) + [TestCase(3UL, 5UL)] + [TestCase(4UL, 10UL)] + [TestCase(0UL, 1UL)] + public void GetFeeHistory_IfPendingBlockDoesNotExistAndLastBlockNumberGreaterThanHeadNumber_ReturnsError(ulong pendingBlockNumber, ulong lastBlockNumber) { IBlockTree blockTree = Substitute.For(); blockTree.FindPendingBlock().Returns(Build.A.Block.WithNumber(pendingBlockNumber).TestObject); @@ -75,7 +75,7 @@ public void GetFeeHistory_IfPendingBlockDoesNotExistAndLastBlockNumberGreaterTha [Test] public void GetFeeHistory_IfRewardPercentilesNotInAscendingOrder_ResultsInFailure() { - int blockCount = 10; + ulong blockCount = 10; double[] rewardPercentiles = [0, 2, 3, 5, 1]; IBlockTree blockTree = Substitute.For(); blockTree.FindBlock(BlockParameter.Latest).Returns(Build.A.Block.TestObject); @@ -90,7 +90,7 @@ public void GetFeeHistory_IfRewardPercentilesNotInAscendingOrder_ResultsInFailur [Test] public void GetFeeHistory_IfTooManyRewardPercentiles_ResultsInFailure() { - int blockCount = 10; + ulong blockCount = 10; IBlockTree blockTree = Substitute.For(); blockTree.FindBlock(BlockParameter.Latest).Returns(Build.A.Block.TestObject); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree); @@ -106,7 +106,7 @@ public void GetFeeHistory_IfTooManyRewardPercentiles_ResultsInFailure() [TestCase(new[] { 1, 2.2, 101, 102 }, TestName = "PercentileOver100")] public void GetFeeHistory_IfRewardPercentilesContainInvalidNumber_ResultsInFailure(double[] rewardPercentiles) { - int blockCount = 10; + ulong blockCount = 10; IBlockTree blockTree = Substitute.For(); blockTree.FindBlock(BlockParameter.Latest).Returns(Build.A.Block.TestObject); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree); @@ -117,17 +117,17 @@ public void GetFeeHistory_IfRewardPercentilesContainInvalidNumber_ResultsInFailu Assert.That(resultWrapper.Result.ResultType, Is.EqualTo(ResultType.Failure)); } - [TestCase(3, 3, 5, 6)] //Target gas used: 3/2 = 1.5 | Actual Gas used = 3 | Base Fee Delta = Max((((3-1.5)/1.5 * 5) / 8, 1) = 1 | Next Base Fee = 5 + 1 = 6 - [TestCase(3, 3, 11, 13)] //Target gas used: 3/2 = 1.5 | Actual Gas used = 3 | Base Fee Delta = Max((((3-1.5)/1.5) * 11) / 8, 1) = 2 | Next Base Fee = 11 + 2 = 13 - [TestCase(100, 95, 20, 22)] //Target gas used: 100/2 = 50 | Actual Gas used = 95 | Base Fee Delta = Max((((95-50)/50) * 20) / 8, 1) = 2 | Next Base Fee = 20 + 2 = 22 - [TestCase(100, 40, 20, 20)] //Target gas used: 100/2 = 50 | Actual Gas used = 40 | Base Fee Delta = (((50-40)/50) * 20) / 8 = 0 | Next Base Fee = 20 - 0 = 20 - [TestCase(100, 40, 50, 49)] //Target gas used: 100/2 = 50 | Actual Gas used = 40 | Base Fee Delta = (((50-40)/50) * 50) / 8 = 1 | Next Base Fee = 50 - 1 = 49 - public void GetFeeHistory_IfLondonEnabled_NextBaseFeePerGasCalculatedCorrectly(long gasLimit, long gasUsed, long baseFee, long expectedNextBaseFee) + [TestCase(3UL, 3UL, 5, 6)] //Target gas used: 3/2 = 1.5 | Actual Gas used = 3 | Base Fee Delta = Max((((3-1.5)/1.5 * 5) / 8, 1) = 1 | Next Base Fee = 5 + 1 = 6 + [TestCase(3UL, 3UL, 11, 13)] //Target gas used: 3/2 = 1.5 | Actual Gas used = 3 | Base Fee Delta = Max((((3-1.5)/1.5) * 11) / 8, 1) = 2 | Next Base Fee = 11 + 2 = 13 + [TestCase(100UL, 95UL, 20, 22)] //Target gas used: 100/2 = 50 | Actual Gas used = 95 | Base Fee Delta = Max((((95-50)/50) * 20) / 8, 1) = 2 | Next Base Fee = 20 + 2 = 22 + [TestCase(100UL, 40UL, 20, 20)] //Target gas used: 100/2 = 50 | Actual Gas used = 40 | Base Fee Delta = (((50-40)/50) * 20) / 8 = 0 | Next Base Fee = 20 - 0 = 20 + [TestCase(100UL, 40UL, 50, 49)] //Target gas used: 100/2 = 50 | Actual Gas used = 40 | Base Fee Delta = (((50-40)/50) * 50) / 8 = 1 | Next Base Fee = 50 - 1 = 49 + public void GetFeeHistory_IfLondonEnabled_NextBaseFeePerGasCalculatedCorrectly(ulong gasLimit, ulong gasUsed, long baseFee, long expectedNextBaseFee) { - int blockCount = 1; + ulong blockCount = 1; IBlockTree blockTree = Substitute.For(); BlockHeader blockHeader = Build.A.BlockHeader.WithBaseFee((UInt256)baseFee).WithGasLimit(gasLimit).WithGasUsed(gasUsed).TestObject; - BlockParameter newestBlock = new((long)0); + BlockParameter newestBlock = new(0UL); Block headBlock = Build.A.Block.Genesis.WithHeader(blockHeader).TestObject; blockTree.FindBlock(newestBlock).Returns(headBlock); ISpecProvider specProvider = GetSpecProviderWithEip1559EnabledAs(true); @@ -144,17 +144,18 @@ public void GetFeeHistory_IfLondonEnabled_NextBaseFeePerGasCalculatedCorrectly(l } - [TestCase(3, 3, 1)] - [TestCase(100, 95, 0.95)] - [TestCase(12, 3, 0.25)] - [TestCase(100, 40, 0.4)] - [TestCase(3, 1, 0.3333333333333333)] - public void GetFeeHistory_GasUsedRatioCalculatedCorrectly(long gasLimit, long gasUsed, double expectedGasUsedRatio) + [TestCase(3UL, 3UL, 1)] + [TestCase(100UL, 95UL, 0.95)] + [TestCase(12UL, 3UL, 0.25)] + [TestCase(100UL, 40UL, 0.4)] + [TestCase(3UL, 1UL, 0.3333333333333333)] + public void GetFeeHistory_GasUsedRatioCalculatedCorrectly(ulong gasLimit, ulong gasUsed, double expectedGasUsedRatio) { IBlockTree blockTree = Substitute.For(); BlockHeader blockHeader = Build.A.BlockHeader.WithGasLimit(gasLimit).WithGasUsed(gasUsed).TestObject; + Block headBlock = Build.A.Block.Genesis.WithHeader(blockHeader).TestObject; - BlockParameter newestBlock = new((long)0); + BlockParameter newestBlock = new(0UL); blockTree.Head.Returns(headBlock); blockTree.FindBlock(newestBlock).Returns(headBlock); ISpecProvider specProvider = GetSpecProviderWithEip1559EnabledAs(true); @@ -172,7 +173,7 @@ public void GetFeeHistory_IfLondonNotEnabled_NextBaseFeeIsParentBaseFee(long bas ISpecProvider specProvider = GetSpecProviderWithEip1559EnabledAs(false); BlockHeader blockHeader = Build.A.BlockHeader.WithBaseFee((UInt256)baseFee).TestObject; Block headBlock = Build.A.Block.Genesis.WithHeader(blockHeader).TestObject; - BlockParameter newestBlock = new((long)0); + BlockParameter newestBlock = new(0UL); IBlockTree blockTree = Substitute.For(); blockTree.FindBlock(newestBlock).Returns(headBlock); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree, specProvider: specProvider); @@ -201,7 +202,7 @@ public void GetFeeHistory_NoTxsInBlock_ReturnsArrayOfZerosAsBigAsRewardPercentil { IBlockTree blockTree = Substitute.For(); Block noTxBlock = Build.A.Block.TestObject; - BlockParameter newestBlock = new((long)0); + BlockParameter newestBlock = new(0UL); blockTree.FindBlock(newestBlock).Returns(noTxBlock); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree); double[] rewardPercentiles = Enumerable.Range(1, sizeOfRewardPercentiles).Select(static x => (double)x).ToArray(); @@ -213,9 +214,9 @@ public void GetFeeHistory_NoTxsInBlock_ReturnsArrayOfZerosAsBigAsRewardPercentil } - [TestCase(5, 10, 6)] - [TestCase(5, 3, 0)] - public void GetFeeHistory_GivenValidInputs_FirstBlockNumberCalculatedCorrectly(int blockCount, long newestBlockNumber, long expectedOldestBlockNumber) + [TestCase(5UL, 10UL, 6UL)] + [TestCase(5UL, 3UL, 0UL)] + public void GetFeeHistory_GivenValidInputs_FirstBlockNumberCalculatedCorrectly(ulong blockCount, ulong newestBlockNumber, ulong expectedOldestBlockNumber) { IBlockTree blockTree = Substitute.For(); const BlockTreeLookupOptions options = BlockTreeLookupOptions.ExcludeTxHashes | @@ -224,7 +225,7 @@ public void GetFeeHistory_GivenValidInputs_FirstBlockNumberCalculatedCorrectly(i Block? parent = null; Block? latestBlock = null; - long latestBlockNumber = 0; + ulong latestBlockNumber = 0; // build a full chain while (latestBlockNumber <= newestBlockNumber) { @@ -248,10 +249,10 @@ public void GetFeeHistory_GivenValidInputs_FirstBlockNumberCalculatedCorrectly(i Assert.That(resultWrapper.Data.OldestBlock, Is.EqualTo(expectedOldestBlockNumber)); } - [TestCase(2, 2)] - [TestCase(7, 7)] - [TestCase(32, 32)] - public void GetFeeHistory_IfLastBlockIsPendingBlock_LastBlockNumberSetToPendingBlockNumber(long blockNumber, long lastBlockNumberExpected) + [TestCase(2UL, 2UL)] + [TestCase(7UL, 7UL)] + [TestCase(32UL, 32UL)] + public void GetFeeHistory_IfLastBlockIsPendingBlock_LastBlockNumberSetToPendingBlockNumber(ulong blockNumber, ulong lastBlockNumberExpected) { IBlockTree blockTree = Substitute.For(); Block pendingBlock = Build.A.Block.WithNumber(blockNumber).TestObject; @@ -264,10 +265,10 @@ public void GetFeeHistory_IfLastBlockIsPendingBlock_LastBlockNumberSetToPendingB Assert.That(resultWrapper.Data.OldestBlock, Is.EqualTo(lastBlockNumberExpected)); } - [TestCase(2, 2)] - [TestCase(7, 7)] - [TestCase(32, 32)] - public void GetFeeHistory_IfLastBlockIsLatestBlock_LastBlockNumberSetToHeadBlockNumber(long blockNumber, long lastBlockNumberExpected) + [TestCase(2UL, 2UL)] + [TestCase(7UL, 7UL)] + [TestCase(32UL, 32UL)] + public void GetFeeHistory_IfLastBlockIsLatestBlock_LastBlockNumberSetToHeadBlockNumber(ulong blockNumber, ulong lastBlockNumberExpected) { IBlockTree blockTree = Substitute.For(); Block headBlock = Build.A.Block.WithNumber(blockNumber).TestObject; @@ -300,7 +301,7 @@ public void GetFeeHistory_GivenValidInputs_CalculatesPercentilesCorrectly(double Transaction[] transactions = GetTestTransactions(); Block headBlock = Build.A.Block.Genesis.WithBaseFeePerGas(3).WithGasUsed(100).WithTransactions(transactions).TestObject; IBlockTree blockTree = Substitute.For(); - BlockParameter newestBlockParameter = new((long)0); + BlockParameter newestBlockParameter = new(0UL); blockTree.FindBlock(newestBlockParameter).Returns(headBlock); IReceiptStorage? receiptStorage = GetTestReceiptStorageForBlockWithGasUsed(headBlock, [10, 20, 30, 40]); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree, receiptStorage: receiptStorage); @@ -335,9 +336,9 @@ public void GetFeeHistory_GivenValidInputs_CalculatesPercentilesCorrectlyOnMulti Transaction[] transactions = GetTestTransactions(); Block headBlock = Build.A.Block.Genesis.WithBaseFeePerGas(3).WithGasUsed(100).WithTransactions(transactions).TestObject; IBlockTree blockTree = Substitute.For(); - BlockParameter newestBlockParameter = new((long)0); + BlockParameter newestBlockParameter = new(0UL); blockTree.FindBlock(newestBlockParameter).Returns(headBlock); - IReceiptStorage? receiptStorage = GetTestReceiptStorageForBlockWithGasUsed(headBlock, new long[] { 10, 20, 30, 40 }); + IReceiptStorage? receiptStorage = GetTestReceiptStorageForBlockWithGasUsed(headBlock, new ulong[] { 10, 20, 30, 40 }); FeeHistoryOracle feeHistoryOracle = GetSubstitutedFeeHistoryOracle(blockTree: blockTree, receiptStorage: receiptStorage); while (repetitions-- > 0) { @@ -354,7 +355,7 @@ public void GetFeeHistory_GivenValidInputs_CalculatesPercentilesCorrectlyOnMulti } } - private static IReceiptStorage GetTestReceiptStorageForBlockWithGasUsed(Block block, long[] gasUsedArray) + private static IReceiptStorage GetTestReceiptStorageForBlockWithGasUsed(Block block, ulong[] gasUsedArray) { IReceiptStorage receiptStorage = Substitute.For(); @@ -404,7 +405,7 @@ public static IEnumerable AscendingBlockNumberTestCases() [TestCaseSource(nameof(AscendingBlockNumberTestCases))] public void GetFeeHistory_ResultsSortedInOrderOfAscendingBlockNumber(IReleaseSpec spec, IEnumerable blobGasUsedRatio) { - BlockParameter newestBlockParameter = new(1); + BlockParameter newestBlockParameter = new(1UL); FeeHistoryOracle feeHistoryOracle = SetUpFeeHistoryManager(newestBlockParameter, spec); double[] rewardPercentiles = { 0 }; using FeeHistoryResults expected = new(0, @@ -483,7 +484,7 @@ public void GetFeeHistory_BaseFeePerBlobGasNewestPlusOne_UsesNextBlockEstimate() specProvider.GetSpec(Arg.Any()).BaseFeeCalculator.Returns(new DefaultBaseFeeCalculator()); FeeHistoryOracle oracle = new(blockTree, Substitute.For(), specProvider); - using ResultWrapper result = oracle.GetFeeHistory(1, new BlockParameter(0L), []); + using ResultWrapper result = oracle.GetFeeHistory(1, new BlockParameter(0UL), []); ArrayPoolList fees = result.Data.BaseFeePerBlobGas; Assert.That(fees.Count, Is.EqualTo(2), "blockCount + 1 entries"); @@ -523,7 +524,7 @@ private static FeeHistoryOracle GetSubstitutedFeeHistoryOracle( blockTree ?? Substitute.For(), receiptStorage ?? Substitute.For(), provider, - maxDistFromHead); + (ulong?)maxDistFromHead); } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs index 91931808b5c7..690bebd509ef 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs @@ -135,7 +135,7 @@ public async ValueTask GasPriceEstimate_EmptyChain_BaseFeeIncluded(ulong? gasPri UInt256 baseFeePerGas = 10.GWei; Block headBlock = Build.A.Block.WithBaseFeePerGas(baseFeePerGas).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(headBlock); + blockFinder.FindBlock(0UL).Returns(headBlock); blockFinder.Head.Returns(headBlock); ISpecProvider specProvider = Substitute.For(); GasPriceOracle testGasPriceOracle = new(blockFinder, specProvider, LimboLogs.Instance, gasPrice); @@ -150,7 +150,7 @@ public async ValueTask GasPriceEstimate_IfCalculatedGasPriceGreaterThanMax_MaxGa Transaction tx = Build.A.Transaction.WithGasPrice(501.GWei).TestObject; Block headBlock = Build.A.Block.WithTransactions(tx).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(headBlock); + blockFinder.FindBlock(0UL).Returns(headBlock); blockFinder.Head.Returns(headBlock); ISpecProvider specProvider = Substitute.For(); GasPriceOracle testGasPriceOracle = new(blockFinder, specProvider, LimboLogs.Instance); @@ -170,9 +170,9 @@ public void GetGasPricesFromRecentBlocks_IfEightBlocksWithTwoTransactions_CheckE testGasPriceOracle.GetGasPriceEstimate(); - foreach (long receivedBlockNumber in Enumerable.Range(0, blockNumber + 1)) + foreach (ulong receivedBlockNumber in Enumerable.Range(0, blockNumber + 1).Select(i => (ulong)i)) { - blockFinder.Received(1).FindBlock(Arg.Is(l => l == receivedBlockNumber)); + blockFinder.Received(1).FindBlock(Arg.Is(l => l == receivedBlockNumber)); } } @@ -183,10 +183,10 @@ private IBlockFinder BuildTree(int maxBlock) Block blockWithTwoTx = Build.A.Block.WithTransactions(tx, tx).TestObject; for (int i = 0; i <= maxBlock; i++) { - blockFinder.FindBlock(i).Returns(blockWithTwoTx); + blockFinder.FindBlock((ulong)i).Returns(blockWithTwoTx); } - blockFinder.Head.Returns(Build.A.Block.WithNumber(maxBlock).TestObject); + blockFinder.Head.Returns(Build.A.Block.WithNumber((ulong)maxBlock).TestObject); return blockFinder; } @@ -203,12 +203,12 @@ public void GetGasPricesFromRecentBlocks_IfLastFiveBlocksWithThreeTxAndFirstFour testGasPriceOracle.GetGasPriceEstimate(); - foreach (long receivedBlockNumber in Enumerable.Range(3, 5)) + foreach (ulong receivedBlockNumber in Enumerable.Range(3, 5).Select(i => (ulong)i)) { - blockFinder.Received(1).FindBlock(Arg.Is(l => l == receivedBlockNumber)); + blockFinder.Received(1).FindBlock(Arg.Is(l => l == receivedBlockNumber)); } - blockFinder.DidNotReceive().FindBlock(Arg.Is(l => l <= 2)); + blockFinder.DidNotReceive().FindBlock(Arg.Is(l => l <= 2)); } private IBlockFinder GetBlockFinderForLastFiveBlocksWithThreeTxAndFirstFourWithOne() @@ -219,11 +219,11 @@ private IBlockFinder GetBlockFinderForLastFiveBlocksWithThreeTxAndFirstFourWithO Block blockWithThreeTx = Build.A.Block.WithTransactions(Enumerable.Repeat(tx, 3).ToArray()).TestObject; for (int i = 0; i < 4; i++) { - blockFinder.FindBlock(i).Returns(blockWithOneTx); + blockFinder.FindBlock((ulong)i).Returns(blockWithOneTx); } for (int i = 4; i <= 8; i++) { - blockFinder.FindBlock(i).Returns(blockWithThreeTx); + blockFinder.FindBlock((ulong)i).Returns(blockWithThreeTx); } blockFinder.Head.Returns(Build.A.Block.WithNumber(8).TestObject); @@ -248,7 +248,7 @@ public void GetGasPricesFromRecentBlocks_IfBlockHasMoreThanThreeValidTx_AddOnlyT Transaction tx = Build.A.Transaction.WithGasPrice(2).TestObject; Block headBlock = Build.A.Block.Genesis.WithTransactions(tx, tx, tx, tx, tx).TestObject; blockFinder.FindHeadBlock().Returns(headBlock); - blockFinder.FindBlock(0).Returns(headBlock); + blockFinder.FindBlock(0UL).Returns(headBlock); GasPriceOracle testGasPriceOracle = new(blockFinder, Substitute.For(), LimboLogs.Instance); IEnumerable results = testGasPriceOracle.GetGasPricesFromRecentBlocks(0); @@ -261,7 +261,7 @@ public void GetGasPricesFromRecentBlocks_IfBlockHasMoreThanThreeValidTxs_OnlyAdd { Block testBlock = Build.A.Block.WithTransactions(GetFiveTransactionsWithDifferentGasPrices()).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(testBlock); + blockFinder.FindBlock(0UL).Returns(testBlock); GasPriceOracle testGasPriceOracle = new(blockFinder, Substitute.For(), LimboLogs.Instance); List expected = [2, 3, 4]; @@ -295,7 +295,7 @@ public void GetGasPricesFromRecentBlocks_TxsSentByMiner_ShouldNotHaveGasPriceInT }; Block block = Build.A.Block.Genesis.WithBeneficiary(minerAddress).WithTransactions(transactions).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(block); + blockFinder.FindBlock(0UL).Returns(block); GasPriceOracle gasPriceOracle = new(blockFinder, Substitute.For(), LimboLogs.Instance); List expected = [8, 9]; @@ -314,7 +314,7 @@ public void AddValidTxAndReturnCount_GivenEip1559Txs_EffectiveGasPriceProperlyCa }; Block eip1559Block = Build.A.Block.Genesis.WithTransactions(eip1559TxGroup).WithBaseFeePerGas(1).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(eip1559Block); + blockFinder.FindBlock(0UL).Returns(eip1559Block); GasPriceOracle gasPriceOracle = new(blockFinder, GetSpecProviderWithEip1559EnabledAs(eip1559Enabled), LimboLogs.Instance); IEnumerable results = gasPriceOracle.GetGasPricesFromRecentBlocks(0); @@ -334,7 +334,7 @@ public void AddValidTxAndReturnCount_GivenNonEip1559Txs_EffectiveGasPriceProperl }; Block nonEip1559Block = Build.A.Block.Genesis.WithTransactions(nonEip1559TxGroup).WithBaseFeePerGas(1).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(nonEip1559Block); + blockFinder.FindBlock(0UL).Returns(nonEip1559Block); GasPriceOracle gasPriceOracle = new(blockFinder, GetSpecProviderWithEip1559EnabledAs(eip1559Enabled), LimboLogs.Instance); IEnumerable results = gasPriceOracle.GetGasPricesFromRecentBlocks(0); @@ -357,7 +357,7 @@ public void GetGasPricesFromRecentBlocks_IfNoValidTxsInABlock_DefaultPriceAddedT }; Block block = Build.A.Block.Genesis.WithTransactions(transactions).WithBeneficiary(TestItem.PrivateKeyA.Address).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(block); + blockFinder.FindBlock(0UL).Returns(block); GasPriceOracle gasPriceOracle = new(blockFinder, Substitute.For(), LimboLogs.Instance) { _gasPriceEstimation = new(null, 7) }; List expected = [7]; @@ -372,7 +372,7 @@ public void AddValidTxAndReturnCount_IfNoTxsInABlock_DefaultPriceAddedToListInst Transaction[] transactions = []; Block block = Build.A.Block.Genesis.WithTransactions(transactions).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(block); + blockFinder.FindBlock(0UL).Returns(block); GasPriceOracle gasPriceOracle = new(blockFinder, Substitute.For(), LimboLogs.Instance) { _gasPriceEstimation = new(null, 7) }; List expected = [7]; @@ -392,7 +392,7 @@ public void AddValidTxAndReturnCount_Eip1559NotEnabled_EffectiveGasPricesShouldB }; Block testBlock = Build.A.Block.Genesis.WithBaseFeePerGas(1).WithTransactions(transactions).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(testBlock); + blockFinder.FindBlock(0UL).Returns(testBlock); GasPriceOracle gasPriceOracle = new(blockFinder, GetSpecProviderWithEip1559EnabledAs(false), LimboLogs.Instance); List expected = [2, 3]; @@ -412,7 +412,7 @@ public void AddValidTxAndReturnCount_Eip1559Enabled_EffectiveGasPricesShouldBeMo }; Block testBlock = Build.A.Block.Genesis.WithBaseFeePerGas(1).WithTransactions(transactions).TestObject; IBlockFinder blockFinder = Substitute.For(); - blockFinder.FindBlock(0).Returns(testBlock); + blockFinder.FindBlock(0UL).Returns(testBlock); GasPriceOracle gasPriceOracle = new(blockFinder, GetSpecProviderWithEip1559EnabledAs(true), LimboLogs.Instance); List expected = [3, 4]; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs index 30044ffafc8e..278df67488f6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs @@ -86,11 +86,11 @@ public void Initialize() _signerStore = new Signer(specProvider.ChainId, TestItem.PrivateKeyB, logger); _parityRpcModule = CreateParityRpcModule(peerManager); - int blockNumber = 2; + ulong blockNumber = 2; Transaction pendingTransaction = Build.A.Transaction.Signed(_ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)).TestObject; pendingTransaction.Signature!.V = 37; - stateProvider.CreateAccount(pendingTransaction.SenderAddress!, UInt256.UInt128MaxValue); + stateProvider.CreateAccount(pendingTransaction.SenderAddress!, ulong.MaxValue); _txPool.SubmitTx(pendingTransaction, TxHandlingOptions.None); blockNumber = 1; @@ -98,7 +98,7 @@ public void Initialize() .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(100).TestObject; transaction1.Signature!.V = 37; - stateProvider.CreateAccount(transaction1.SenderAddress!, UInt256.UInt128MaxValue); + stateProvider.CreateAccount(transaction1.SenderAddress!, ulong.MaxValue); Transaction transaction2 = Build.A.Transaction.Signed(_ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) @@ -111,7 +111,7 @@ public void Initialize() transaction2.Signature.V = 37; Block genesis = Build.A.Block.Genesis - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .TestObject; _blockTree.SuggestBlock(genesis); @@ -119,7 +119,7 @@ public void Initialize() Block previousBlock = genesis; Block block = Build.A.Block.WithNumber(blockNumber).WithParent(previousBlock) - .WithStateRoot(new Hash256("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) + .WithStateRoot(new Hash256("0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f")) .WithTransactions(transaction1, transaction2, transaction3) .TestObject; @@ -297,7 +297,7 @@ public async Task parity_pendingTransactions_With_Address_Empty_Result() public async Task parity_getBlockReceipts() { string serialized = await RpcTest.TestSerializedRequest(_parityRpcModule, "parity_getBlockReceipts", "latest"); - string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x026217c3c4eb1f0e9e899553759b6e909b965a789c6136d256674718617c8142\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x0\",\"transactionHash\":\"0x026217c3c4eb1f0e9e899553759b6e909b965a789c6136d256674718617c8142\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"},{\"transactionHash\":\"0xd0183bfd42ccd8fccb7722b108e052d12d2cf5a32a144b6a6f3a975c4d7d14a1\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x1\",\"transactionHash\":\"0xd0183bfd42ccd8fccb7722b108e052d12d2cf5a32a144b6a6f3a975c4d7d14a1\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"},{\"transactionHash\":\"0xf8ab484b10dc0398f03957d1062bbe3526048b74d429f8a8c9c57fa7ac5fa436\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x2\",\"transactionIndex\":\"0x2\",\"transactionHash\":\"0xf8ab484b10dc0398f03957d1062bbe3526048b74d429f8a8c9c57fa7ac5fa436\",\"blockHash\":\"0x5077d73d2e82d0b7799392db86827826f181df13e3f50fed89cbb5aa03f5230f\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"}],\"id\":67}"; + string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x026217c3c4eb1f0e9e899553759b6e909b965a789c6136d256674718617c8142\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x0\",\"transactionHash\":\"0x026217c3c4eb1f0e9e899553759b6e909b965a789c6136d256674718617c8142\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"},{\"transactionHash\":\"0xd0183bfd42ccd8fccb7722b108e052d12d2cf5a32a144b6a6f3a975c4d7d14a1\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x1\",\"transactionHash\":\"0xd0183bfd42ccd8fccb7722b108e052d12d2cf5a32a144b6a6f3a975c4d7d14a1\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"},{\"transactionHash\":\"0xf8ab484b10dc0398f03957d1062bbe3526048b74d429f8a8c9c57fa7ac5fa436\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"cumulativeGasUsed\":\"0x7d0\",\"gasUsed\":\"0x3e8\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"contractAddress\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"logs\":[{\"removed\":false,\"logIndex\":\"0x2\",\"transactionIndex\":\"0x2\",\"transactionHash\":\"0xf8ab484b10dc0398f03957d1062bbe3526048b74d429f8a8c9c57fa7ac5fa436\",\"blockHash\":\"0xf7b57f94244d8d0527bbfa456fa58cf1809829ce40f50c4179429f87e7660cad\",\"blockNumber\":\"0x1\",\"blockTimestamp\":\"0xf4241\",\"address\":\"0x0000000000000000000000000000000000000000\",\"data\":\"0x\",\"topics\":[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]}],\"logsBloom\":\"0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x0\",\"type\":\"0x0\"}],\"id\":67}"; Assert.That(serialized, Is.EqualTo(expectedResult)); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/AccessListTransactionForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/AccessListTransactionForRpcTests.cs index 98ed0aafa63b..58c97ca2f279 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/AccessListTransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/AccessListTransactionForRpcTests.cs @@ -17,9 +17,9 @@ public static class AccessListTransactionForRpcTests [ Build.TestObject, - Build.WithNonce(UInt256.Zero).TestObject, - Build.WithNonce((UInt256)123).TestObject, - Build.WithNonce(UInt256.MaxValue).TestObject, + Build.WithNonce(0UL).TestObject, + Build.WithNonce(123UL).TestObject, + Build.WithNonce(ulong.MaxValue).TestObject, Build.WithTo(null).TestObject, Build.WithTo(TestItem.AddressA).TestObject, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/BlobTransactionForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/BlobTransactionForRpcTests.cs index f067202e6c07..04e23f9106fb 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/BlobTransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/BlobTransactionForRpcTests.cs @@ -22,9 +22,9 @@ public static class BlobTransactionForRpcTests [ Build.TestObject, - Build.WithNonce(UInt256.Zero).TestObject, - Build.WithNonce(123).TestObject, - Build.WithNonce(UInt256.MaxValue).TestObject, + Build.WithNonce(0UL).TestObject, + Build.WithNonce(123UL).TestObject, + Build.WithNonce(ulong.MaxValue).TestObject, Build.WithTo(null).TestObject, Build.WithTo(TestItem.AddressA).TestObject, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/EIP1559TransactionForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/EIP1559TransactionForRpcTests.cs index 13e33b5a3a19..f6b564b92ff5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/EIP1559TransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/EIP1559TransactionForRpcTests.cs @@ -17,9 +17,9 @@ public static class EIP1559TransactionForRpcTests [ Build.TestObject, - Build.WithNonce(UInt256.Zero).TestObject, - Build.WithNonce(123).TestObject, - Build.WithNonce(UInt256.MaxValue).TestObject, + Build.WithNonce(0UL).TestObject, + Build.WithNonce(123UL).TestObject, + Build.WithNonce(ulong.MaxValue).TestObject, Build.WithTo(null).TestObject, Build.WithTo(TestItem.AddressA).TestObject, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/LegacyTransactionForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/LegacyTransactionForRpcTests.cs index a7abcb7f21bd..ee30f37cecec 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/LegacyTransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/LegacyTransactionForRpcTests.cs @@ -16,9 +16,9 @@ public static class LegacyTransactionForRpcTests [ BuildALegacyTransaction.TestObject, - BuildALegacyTransaction.WithNonce(UInt256.Zero).TestObject, - BuildALegacyTransaction.WithNonce((UInt256)123).TestObject, - BuildALegacyTransaction.WithNonce(UInt256.MaxValue).TestObject, + BuildALegacyTransaction.WithNonce(0UL).TestObject, + BuildALegacyTransaction.WithNonce(123UL).TestObject, + BuildALegacyTransaction.WithNonce(ulong.MaxValue).TestObject, BuildALegacyTransaction.WithTo(null).TestObject, BuildALegacyTransaction.WithTo(TestItem.AddressA).TestObject, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/SetCodeTransactionForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/SetCodeTransactionForRpcTests.cs index c4ee0b902013..be9327830777 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/SetCodeTransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/RpcTransaction/SetCodeTransactionForRpcTests.cs @@ -20,9 +20,9 @@ public static class SetCodeTransactionForRpcTests [ Build.TestObject, - Build.WithNonce(UInt256.Zero).TestObject, - Build.WithNonce((UInt256)123).TestObject, - Build.WithNonce(UInt256.MaxValue).TestObject, + Build.WithNonce(0UL).TestObject, + Build.WithNonce(123UL).TestObject, + Build.WithNonce(ulong.MaxValue).TestObject, Build.WithTo(null).TestObject, Build.WithTo(TestItem.AddressA).TestObject, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Simulate/TracedSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Simulate/TracedSimulateTestsBase.cs index efa8a4e196b0..0932877976b6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Simulate/TracedSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Simulate/TracedSimulateTestsBase.cs @@ -59,7 +59,7 @@ public async Task Test_simulate_eth_moved() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - UInt256 nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = EthSimulateTestsBlocksAndTransactions.GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1, type: TxType.Legacy); SimulatePayload payload = EthSimulateTestsBlocksAndTransactions.CreateEthMovedPayload(chain, nonceA); @@ -92,7 +92,7 @@ public async Task Test_simulate_transactions_forced_fail() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - UInt256 nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong nonceA = chain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = EthSimulateTestsBlocksAndTransactions.GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1, type: TxType.Legacy); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Subscribe/TransactionReceiptsSubscriptionTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Subscribe/TransactionReceiptsSubscriptionTests.cs index a85e0c3a7ff5..735cb398921e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Subscribe/TransactionReceiptsSubscriptionTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Subscribe/TransactionReceiptsSubscriptionTests.cs @@ -130,7 +130,7 @@ public void TransactionReceiptsSubscription_hash_count_limit(int hashCount, bool [Test] public void TransactionReceiptsSubscription_on_receipts_inserted_no_filter_returns_all_receipts() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; Transaction tx1 = Build.A.Transaction.WithHash(TestItem.KeccakA).TestObject; @@ -158,7 +158,7 @@ public void TransactionReceiptsSubscription_on_receipts_inserted_no_filter_retur [Test] public void TransactionReceiptsSubscription_on_receipts_inserted_single_hash_filter() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TransactionHashesFilter filter = new() @@ -184,7 +184,7 @@ public void TransactionReceiptsSubscription_on_receipts_inserted_single_hash_fil [Test] public void TransactionReceiptsSubscription_on_receipts_inserted_multiple_hashes_filter() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TransactionHashesFilter filter = new() @@ -213,7 +213,7 @@ public void TransactionReceiptsSubscription_on_receipts_inserted_multiple_hashes [Test] public void TransactionReceiptsSubscription_on_receipts_inserted_non_matching_hashes() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TransactionHashesFilter filter = new() @@ -235,7 +235,7 @@ public void TransactionReceiptsSubscription_on_receipts_inserted_non_matching_ha [Test] public void TransactionReceiptsSubscription_on_receipts_inserted_partial_match() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TransactionHashesFilter filter = new() @@ -262,7 +262,7 @@ public void TransactionReceiptsSubscription_on_receipts_inserted_partial_match() [Test] public void TransactionReceiptsSubscription_receipt_includes_all_fields() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).WithHash(TestItem.KeccakF).WithTimestamp(1000000).TestObject; LogEntry logEntry = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).TestObject; @@ -301,7 +301,7 @@ public void TransactionReceiptsSubscription_receipt_includes_all_fields() [Test] public void TransactionReceiptsSubscription_logs_have_correct_indices() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; LogEntry log1 = Build.A.LogEntry.WithAddress(TestItem.AddressA).TestObject; @@ -331,7 +331,7 @@ public void TransactionReceiptsSubscription_logs_have_correct_indices() [Test] public void TransactionReceiptsSubscription_empty_block_no_notification() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TxReceipt[] receipts = []; @@ -345,7 +345,7 @@ public void TransactionReceiptsSubscription_empty_block_no_notification() [Test] public void TransactionReceiptsSubscription_failed_tx_still_delivered() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TxReceipt receipt = Build.A.Receipt @@ -370,7 +370,7 @@ public void TransactionReceiptsSubscription_failed_tx_still_delivered() [Test] public void TransactionReceiptsSubscription_reorg_skipped() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TxReceipt receipt = Build.A.Receipt.WithBlockNumber(blockNumber).WithTransactionHash(TestItem.KeccakA).WithIndex(0).TestObject; @@ -386,7 +386,7 @@ public void TransactionReceiptsSubscription_reorg_skipped() [Test] public void TransactionReceiptsSubscription_dispose_stops_delivery() { - int blockNumber = 55555; + ulong blockNumber = 55555; BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; TransactionReceiptsSubscription subscription = new( diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs index 92613e485b0a..e7b6a00fb0b8 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SubscribeModuleTests.cs @@ -183,7 +183,7 @@ private JsonRpcResult GetDroppedPendingTransactionsResult(TxEventArgs txEventArg return jsonRpcResult; } - private SyncingSubscription GetSyncingSubscription(int bestSuggested, int head) + private SyncingSubscription GetSyncingSubscription(ulong bestSuggested, ulong head) { BlockHeader blockHeader = Build.A.BlockHeader.WithNumber(bestSuggested).TestObject; _blockTree.FindBestSuggestedHeader().Returns(blockHeader); @@ -480,7 +480,7 @@ public async Task LogsSubscription_with_too_long_string_arguments_returns_invali [Retry(3)] public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = Substitute.For(); LogEntry logEntry = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -501,7 +501,7 @@ public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event() [Test] public void LogsSubscription_with_not_matching_block_on_NewHeadBlock_event() { - int blockNumber = 22222; + ulong blockNumber = 22222; Filter filter = Substitute.For(); LogEntry logEntry = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -519,7 +519,7 @@ public void LogsSubscription_with_not_matching_block_on_NewHeadBlock_event() [Test] public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event_with_one_TxReceipt_with_few_logs() { - int blockNumber = 77777; + ulong blockNumber = 77777; Filter filter = Substitute.For(); LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -551,7 +551,7 @@ public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event_with_one_ [Test] public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event_with_few_TxReceipts_with_few_logs() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = Substitute.For(); LogEntry logEntryA = Build.A.LogEntry.WithAddress(TestItem.AddressA).WithTopics(TestItem.KeccakA).WithData(TestItem.RandomDataA).TestObject; @@ -597,7 +597,7 @@ public void LogsSubscription_with_null_arguments_on_NewHeadBlock_event_with_few_ [Test] public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_logs_with_some_address_mismatches() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = new() { FromBlock = BlockParameter.Latest, @@ -644,7 +644,7 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ [Test] public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_logs_with_some_topic_mismatches() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = new() { @@ -691,7 +691,7 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ [Test] public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_logs_with_few_topics_and_some_address_and_topic_mismatches() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = new() { @@ -744,7 +744,7 @@ public void LogsSubscription_on_NewHeadBlock_event_with_few_TxReceipts_with_few_ [Test] public void LogsSubscription_should_not_send_logs_of_new_txs_on_ReceiptsInserted_event_but_on_NewHeadBlock_event() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = Substitute.For(); LogsSubscription logsSubscription = new(_jsonRpcDuplexClient, _receiptCanonicalityMonitor, _filterStore, _blockTree, _logManager, filter); @@ -1188,7 +1188,7 @@ public async Task Subscriptions_remove_after_closing_websockets_client() [Test] public void LogsSubscription_can_send_logs_with_removed_txs_when_inserted() { - int blockNumber = 55555; + ulong blockNumber = 55555; Filter filter = Substitute.For(); LogsSubscription logsSubscription = new(_jsonRpcDuplexClient, _receiptCanonicalityMonitor, _filterStore, _blockTree, _logManager, filter); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 9d1f39987b33..ac45a0566bdf 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -50,7 +50,7 @@ public class TestRpcBlockchain : TestBlockchain { private bool? _previousStrictHexFormat; - public IJsonRpcConfig RpcConfig { get; private set; } = new JsonRpcConfig(); + public IJsonRpcConfig RpcConfig { get; private set; } = new JsonRpcConfig() { Timeout = -1 }; public IEthRpcModule EthRpcModule { get; private set; } = null!; public IDebugRpcModule DebugRpcModule => Container.Resolve>().Create(); public ITraceRpcModule TraceRpcModule => Container.Resolve>().Create(); @@ -196,6 +196,7 @@ protected override async Task Build(Action? co await base.Build(builder => { builder.AddSingleton(new TestSpecProvider(Berlin.Instance)); + builder.AddSingleton(RpcConfig); configurer?.Invoke(builder); }); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityTxTraceFromReplayConverterTest.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityTxTraceFromReplayConverterTest.cs index 6183f1ec7152..3614605c650c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityTxTraceFromReplayConverterTest.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityTxTraceFromReplayConverterTest.cs @@ -92,7 +92,7 @@ public void Can_serialize(bool includeTransactionHash, string expectedResult) [Todo(Improve.Refactor, "Different action serializers")] public void Can_serialize_reward() { - Block block = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; + Block block = Build.A.Block.WithNumber(ulong.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); blockTracer.StartNewBlockTrace(block); ITxTracer txTracer = blockTracer.StartNewTxTrace(null); @@ -157,7 +157,7 @@ public void Can_serialize_creation_method() [Test, Ignore("Reenable it after running compare on PoW chains")] public void Can_serialize_reward_state_only() { - Block block = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; + Block block = Build.A.Block.WithNumber(ulong.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.StateDiff); blockTracer.StartNewBlockTrace(block); ITxTracer txTracer = blockTracer.StartNewTxTrace(null); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/TraceSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/TraceSimulateTestsBlocksAndTransactions.cs index 492264eab01f..8bdfd22c8c56 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/TraceSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/TraceSimulateTestsBlocksAndTransactions.cs @@ -35,7 +35,7 @@ protected override void AssertSerializationBlockResult(SimulateBlockResult().GasCap = gasCap; // Contract: GAS PUSH1 0 MSTORE PUSH1 32 PUSH1 0 RETURN — returns remaining gas diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 789202efa345..39d6c0f9a9aa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -62,7 +62,7 @@ public async Task Build(ISpecProvider? specProvider = null, bool isAura = false) { transactions.Add(Core.Test.Builders.Build.A.Transaction .WithTo(Address.Zero) - .WithNonce(Blockchain.StateReader.GetNonce(Blockchain.BlockTree.Head.Header, TestItem.AddressB) + (UInt256)j) + .WithNonce(Blockchain.StateReader.GetNonce(Blockchain.BlockTree.Head.Header, TestItem.AddressB) + (ulong)j) .SignedAndResolved(Blockchain.EthereumEcdsa, TestItem.PrivateKeyB).TestObject); } await Blockchain.AddBlockMayMissTx(transactions.ToArray()); @@ -180,14 +180,14 @@ public async Task Trace_filter_with_filtering_by_receiver_address() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transaction = Build.A.Transaction.WithNonce(currentNonceAddressA) .WithTo(TestItem.AddressA) .SignedAndResolved(blockchain.EthereumEcdsa, TestItem.PrivateKeyA).TestObject; await context.Blockchain.AddBlock(transaction); TraceFilterForRpc traceFilterRequest = new(); - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber); traceFilterRequest.ToBlock = new BlockParameter(lastBLockNumber); traceFilterRequest.ToAddress = new[] { TestItem.AddressA }; @@ -200,13 +200,13 @@ public async Task Trace_filter_with_filtering_by_sender() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transaction = Build.A.Transaction.WithNonce(currentNonceAddressA) .WithTo(TestItem.AddressA) .SignedAndResolved(blockchain.EthereumEcdsa, TestItem.PrivateKeyA).TestObject; await context.Blockchain.AddBlock(transaction); await context.Blockchain.AddBlock(); - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; TraceFilterForRpc traceFilterRequest = new(); traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber - 1); traceFilterRequest.ToBlock = BlockParameter.Latest; @@ -222,8 +222,8 @@ public async Task Trace_filter_with_filtering_by_internal_transaction_receiver() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); byte[] deployedCode = new byte[3]; byte[] initCode = Prepare.EvmCode @@ -252,7 +252,7 @@ public async Task Trace_filter_with_filtering_by_internal_transaction_receiver() .WithGasLimit(93548).TestObject; await blockchain.AddBlock(transaction2); await blockchain.AddBlock(); - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; TraceFilterForRpc traceFilterRequest = new(); traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber - 1); @@ -268,13 +268,13 @@ public async Task Trace_filter_with_filtering_by_sender_and_receiver() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); await context.Blockchain.AddBlockMayMissTx( new[] { - Build.A.Transaction.WithNonce(currentNonceAddressA + 1).WithTo(TestItem.AddressD) + Build.A.Transaction.WithNonce(currentNonceAddressA + 1UL).WithTo(TestItem.AddressD) .SignedAndResolved(TestItem.PrivateKeyA).TestObject, - Build.A.Transaction.WithNonce(blockchain.ReadOnlyState.GetNonce(TestItem.AddressB) + 1).WithTo(TestItem.AddressC) + Build.A.Transaction.WithNonce(blockchain.ReadOnlyState.GetNonce(TestItem.AddressB) + 1UL).WithTo(TestItem.AddressC) .SignedAndResolved(TestItem.PrivateKeyB).TestObject, Build.A.Transaction.WithNonce(currentNonceAddressA).WithTo(TestItem.AddressC) .SignedAndResolved(TestItem.PrivateKeyA).TestObject @@ -282,7 +282,7 @@ await context.Blockchain.AddBlockMayMissTx( ); await context.Blockchain.AddBlock(); TraceFilterForRpc traceFilterRequest = new(); - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber - 1); traceFilterRequest.ToBlock = BlockParameter.Latest; traceFilterRequest.FromAddress = new[] { TestItem.PrivateKeyA.Address }; @@ -297,16 +297,16 @@ public async Task Trace_filter_complex_scenario() await context.Build(); TraceFilterForRpc traceFilterRequest = new(); TestRpcBlockchain blockchain = context.Blockchain; - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; traceFilterRequest.After = 3; traceFilterRequest.Count = 4; traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber + 1); traceFilterRequest.ToBlock = BlockParameter.Latest; traceFilterRequest.FromAddress = new[] { TestItem.PrivateKeyA.Address, TestItem.PrivateKeyD.Address }; traceFilterRequest.ToAddress = new[] { TestItem.AddressC, TestItem.AddressA, TestItem.AddressB }; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); - UInt256 currentNonceAddressD = blockchain.ReadOnlyState.GetNonce(TestItem.AddressD); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); + ulong currentNonceAddressD = blockchain.ReadOnlyState.GetNonce(TestItem.AddressD); // first block skipped: After 3 -> 1 await blockchain.AddBlock( new[] @@ -379,14 +379,14 @@ public async Task Trace_filter_complex_scenario_openethereum() await context.Build(); TraceFilterForRpc traceFilterRequest = new(); TestRpcBlockchain blockchain = context.Blockchain; - long lastBLockNumber = blockchain.BlockTree.Head!.Number; + ulong lastBLockNumber = blockchain.BlockTree.Head!.Number; // traceFilterRequest.After = 3; // traceFilterRequest.Count = 4; traceFilterRequest.FromBlock = new BlockParameter(lastBLockNumber + 1); traceFilterRequest.ToBlock = BlockParameter.Latest; // traceFilterRequest.FromAddress = new[] {TestItem.PrivateKeyA.Address, TestItem.PrivateKeyD.Address}; // traceFilterRequest.ToAddress = new[] {TestItem.AddressC, TestItem.AddressA, TestItem.AddressB}; - UInt256 currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); + ulong currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); await blockchain.AddBlock(); await blockchain.AddBlock(); await blockchain.AddBlock( @@ -406,7 +406,7 @@ public async Task trace_transaction_and_get_simple_tx() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transaction = Build.A.Transaction.WithNonce(currentNonceAddressA++).WithTo(TestItem.AddressC) .SignedAndResolved(TestItem.PrivateKeyA).TestObject; await blockchain.AddBlock(transaction); @@ -424,7 +424,7 @@ public async Task Trace_get_can_trace_simple_tx() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transaction = Build.A.Transaction.WithNonce(currentNonceAddressA++).WithTo(TestItem.AddressC) .SignedAndResolved(TestItem.PrivateKeyA).TestObject; @@ -441,8 +441,8 @@ public async Task trace_transaction_and_get_internal_tx() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); byte[] deployedCode = new byte[3]; byte[] initCode = Prepare.EvmCode @@ -488,8 +488,8 @@ public async Task Trace_transaction_with_error_reverted() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); byte[] deployedCode = new byte[3]; byte[] initCode = Prepare.EvmCode @@ -544,8 +544,8 @@ public async Task Trace_replayTransaction_test() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); byte[] deployedCode = new byte[3]; _ = Prepare.EvmCode @@ -578,8 +578,8 @@ public async Task Trace_replayTransaction_reward_test() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); Address? contractAddress = ContractAddress.From(TestItem.AddressA, currentNonceAddressA); byte[] code = Prepare.EvmCode @@ -610,7 +610,7 @@ public async Task trace_replayBlockTransactions_zeroGasUsed_test() await context.Build(specProvider, isAura: true); TestRpcBlockchain blockchain = context.Blockchain; await blockchain.AddFunds(TestItem.AddressC, 10.Ether); - UInt256 currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); + ulong currentNonceAddressC = blockchain.ReadOnlyState.GetNonce(TestItem.AddressC); Transaction serviceTransaction = Build.A.Transaction.WithNonce(currentNonceAddressC++) .WithTo(TestItem.AddressE) @@ -630,8 +630,8 @@ public async Task Trace_call_without_blockParameter_provided_test() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); - UInt256 currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressB = blockchain.ReadOnlyState.GetNonce(TestItem.AddressB); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); Address? contractAddress = ContractAddress.From(TestItem.AddressA, currentNonceAddressA); @@ -815,7 +815,7 @@ public async Task Trace_callMany_internal_transactions_test() await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); Transaction transaction1 = Build.A.Transaction.WithNonce(currentNonceAddressA++).WithTo(TestItem.AddressC) .SignedAndResolved(TestItem.PrivateKeyA).TestObject; @@ -884,7 +884,7 @@ public async Task Trace_replayBlockTransactions_transactions_deploying_contract( Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); Address? contractAddress = ContractAddress.From(TestItem.AddressA, currentNonceAddressA); @@ -921,7 +921,7 @@ public async Task Trace_replayBlockTransactions_stateDiff() Context context = new(); await context.Build(); TestRpcBlockchain blockchain = context.Blockchain; - UInt256 currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); + ulong currentNonceAddressA = blockchain.ReadOnlyState.GetNonce(TestItem.AddressA); await blockchain.AddFunds(TestItem.AddressA, 10000.Ether); Transaction tx = Build.A.Transaction.WithNonce(currentNonceAddressA++) @@ -943,12 +943,12 @@ public async Task Trace_replayBlockTransactions_stateDiff() Dictionary state = traces.Data.ElementAt(0).StateChanges!; Assert.That(state.Count, Is.EqualTo(3)); - Assert.That(state[TestItem.AddressA].Nonce!.Before, Is.EqualTo(accountA.Nonce)); + Assert.That(state[TestItem.AddressA].Nonce!.Before, Is.EqualTo((UInt256)accountA.Nonce)); Assert.That(state[TestItem.AddressD].Balance!.Before, Is.EqualTo(accountD.Balance)); Assert.That(state[TestItem.AddressA].Balance!.Before, Is.EqualTo(accountA.Balance)); Assert.That(state[TestItem.AddressF].Balance!.Before, Is.EqualTo(null)); - Assert.That(state[TestItem.AddressA].Nonce!.After, Is.EqualTo(accountA.Nonce + 1)); + Assert.That(state[TestItem.AddressA].Nonce!.After, Is.EqualTo((UInt256)(accountA.Nonce + 1))); Assert.That(state[TestItem.AddressD].Balance!.After, Is.EqualTo(accountD.Balance + 21000 * tx.GasPrice)); Assert.That(state[TestItem.AddressA].Balance!.After, Is.EqualTo(accountA.Balance - 21000 * tx.GasPrice - tx.Value)); Assert.That(state[TestItem.AddressF].Balance!.After, Is.EqualTo(accountF.Balance + tx.Value)); @@ -1044,7 +1044,7 @@ public async Task Trace_call_caps_gas_to_gas_cap() { Context context = new(); await context.Build(); - long gasCap = 50_000; + ulong gasCap = 50_000; IJsonRpcConfig config = context.Blockchain.Container.Resolve(); config.GasCap = gasCap; @@ -1065,7 +1065,7 @@ public async Task Trace_callMany_caps_gas_to_gas_cap() { Context context = new(); await context.Build(); - long gasCap = 50_000; + ulong gasCap = 50_000; IJsonRpcConfig config = context.Blockchain.Container.Resolve(); config.GasCap = gasCap; @@ -1117,7 +1117,7 @@ public async Task Trace_rawTransaction_caps_gas_to_gas_cap() { Context context = new(); await context.Build(); - long gasCap = 50_000; + ulong gasCap = 50_000; IJsonRpcConfig config = context.Blockchain.Container.Resolve(); config.GasCap = gasCap; @@ -1318,7 +1318,7 @@ private static TraceRpcModule BuildModuleWithNonCanonicalReceipt(Hash256 txHash, IBlockFinder blockFinder = Substitute.For(); blockFinder.HeadHash.Returns(TestItem.KeccakC); - blockFinder.FindBlock(nonCanonicalBlockHash, BlockTreeLookupOptions.RequireCanonical, Arg.Any()) + blockFinder.FindBlock(nonCanonicalBlockHash, BlockTreeLookupOptions.RequireCanonical, Arg.Any()) .Returns((Block?)null); if (!traceNonCanonical) blockFinder.FindHeader(nonCanonicalBlockHash).Returns(Build.A.BlockHeader.TestObject); @@ -1422,7 +1422,7 @@ private static byte[] BuildModExpInput() Context context = new(); await context.Build(new ForkAwareTestSpecProvider(Byzantium.Instance, MainnetSpecProvider.Instance)); - UInt256 nonce = context.Blockchain.StateReader.GetNonce( + ulong nonce = context.Blockchain.StateReader.GetNonce( context.Blockchain.BlockTree.Head!.Header, TestItem.AddressB); Transaction tx = Build.A.Transaction @@ -1439,7 +1439,7 @@ private static byte[] BuildModExpInput() private static long ModExpGasUsed( Context context, BlockParameter block, string forkName) => - context.TraceRpcModule + (long)context.TraceRpcModule .trace_block(block, forkName) .Data.First(t => t.Type == "call").Result!.GasUsed; diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/DbPersistingBlockTracer.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/DbPersistingBlockTracer.cs index 722422246cb6..d8d30f119d25 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/DbPersistingBlockTracer.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/DbPersistingBlockTracer.cs @@ -23,7 +23,7 @@ public class DbPersistingBlockTracer : BlockTracer where TTrace private readonly IBlockTracer _blockTracer; private readonly BlockTracerBase _tracerWithResults; private Hash256 _currentBlockHash = null!; - private long _currentBlockNumber; + private ulong _currentBlockNumber; private readonly ILogger _logger; /// @@ -65,7 +65,7 @@ public override void EndBlockTrace() _blockTracer.EndBlockTrace(); IReadOnlyCollection result = _tracerWithResults.BuildResult(); Hash256 currentBlockHash = _currentBlockHash; - long currentBlockNumber = _currentBlockNumber; + ulong currentBlockNumber = _currentBlockNumber; try { byte[] tracesSerialized = _traceSerializer.Serialize(result); diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/ITraceStoreConfig.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/ITraceStoreConfig.cs index 1803e688c304..1a50c284587f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/ITraceStoreConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/ITraceStoreConfig.cs @@ -12,7 +12,7 @@ public interface ITraceStoreConfig : IConfig public bool Enabled { get; set; } [ConfigItem(Description = "The number of blocks to store, counting from the head. If `0`, all traces of the processed blocks are stored.", DefaultValue = "10000")] - public int BlocksToKeep { get; set; } + public ulong BlocksToKeep { get; set; } [ConfigItem(Description = "The type of traces to store.", DefaultValue = "Trace, Rewards")] public ParityTraceTypes TraceTypes { get; set; } diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreConfig.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreConfig.cs index 552b48a4a7c5..343505d34600 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreConfig.cs @@ -8,7 +8,7 @@ namespace Nethermind.JsonRpc.TraceStore; public class TraceStoreConfig : ITraceStoreConfig { public bool Enabled { get; set; } - public int BlocksToKeep { get; set; } = 10000; + public ulong BlocksToKeep { get; set; } = 10000; public ParityTraceTypes TraceTypes { get; set; } = ParityTraceTypes.Trace | ParityTraceTypes.Rewards; public bool VerifySerialized { get; set; } = false; public int MaxDepth { get; set; } = ParityLikeTraceSerializer.DefaultDepth; diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs index ad8b1525054c..099b4eb16f59 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs @@ -17,7 +17,7 @@ public class TraceStorePruner : IDisposable { private readonly IBlockTree _blockTree; private readonly IDb _db; - private readonly int _blockToKeep; + private readonly ulong _blockToKeep; private readonly ILogger _logger; public TraceStorePruner(IBlockTree blockTree, [KeyFilter(TraceStorePlugin.DbName)] IDb db, ITraceStoreConfig traceStoreConfig, ILogManager logManager) @@ -26,7 +26,7 @@ public TraceStorePruner(IBlockTree blockTree, [KeyFilter(TraceStorePlugin.DbName } [ConstructorWithSideEffect] - public TraceStorePruner(IBlockTree blockTree, IDb db, int blockToKeep, ILogManager logManager) + public TraceStorePruner(IBlockTree blockTree, IDb db, ulong blockToKeep, ILogManager logManager) { _blockTree = blockTree; _db = db; @@ -38,7 +38,7 @@ public TraceStorePruner(IBlockTree blockTree, IDb db, int blockToKeep, ILogManag private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e) => Task.Run((() => { - long levelToDelete = e.Block.Number - _blockToKeep; + ulong levelToDelete = e.Block.Number - _blockToKeep; if (levelToDelete > 0) { ChainLevelInfo? level = _blockTree.FindLevel(levelToDelete); diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/LogEntryForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/LogEntryForRpc.cs index 38f9d37d8f44..2840ff73b3b8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/LogEntryForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/LogEntryForRpc.cs @@ -31,7 +31,7 @@ public LogEntryForRpc(TxReceipt receipt, LogEntry logEntry, ulong blockTimestamp public long? TransactionIndex { get; set; } public Hash256 TransactionHash { get; set; } public Hash256 BlockHash { get; set; } - public long? BlockNumber { get; set; } + public ulong? BlockNumber { get; set; } public ulong? BlockTimestamp { get; set; } public Address Address { get; set; } public byte[] Data { get; set; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/ReceiptForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/ReceiptForRpc.cs index 570e5de44ba8..7797c817e55e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/ReceiptForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/ReceiptForRpc.cs @@ -40,9 +40,9 @@ public ReceiptForRpc(Hash256 txHash, TxReceipt receipt, ulong blockTimestamp, Tx public Hash256 TransactionHash { get; set; } public long TransactionIndex { get; set; } public Hash256? BlockHash { get; set; } - public long BlockNumber { get; set; } - public long CumulativeGasUsed { get; set; } - public long GasUsed { get; set; } + public ulong BlockNumber { get; set; } + public ulong CumulativeGasUsed { get; set; } + public ulong GasUsed { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ulong? BlobGasUsed { get; set; } diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index d3106f5cbe56..42ac328dc807 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -95,7 +95,7 @@ effectively never approach this limit. `0` to lift the limit. string[] AdditionalRpcUrls { get; set; } [ConfigItem(Description = "The maximum gas limit for `eth_call` and `eth_estimateGas`.", DefaultValue = "100000000")] - long? GasCap { get; set; } + ulong? GasCap { get; set; } [ConfigItem( Description = "The interval, in seconds, between the JSON-RPC stats report log.", diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs index 6a2a23cd0cf7..3fb3e8b0de60 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs @@ -42,7 +42,7 @@ public string[] EnabledModules } public string[] AdditionalRpcUrls { get; set; } = []; - public long? GasCap { get; set; } = 100000000; + public ulong? GasCap { get; set; } = 100000000; public int ReportIntervalSeconds { get; set; } = 300; public bool BufferResponses { get; set; } public string CallsFilterFilePath { get; set; } = "Data/jsonrpc.filter"; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs index 43197c5afd8c..759ffb930c80 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs @@ -14,7 +14,7 @@ public static class BlockFinderExtensions public static bool IsBlockPruned(this IBlockFinder blockFinder, BlockParameter blockParameter) { - long? requestedBlock = blockParameter.BlockNumber; + ulong? requestedBlock = blockParameter.BlockNumber; if (requestedBlock is null) { SearchResult headerResult = blockFinder.SearchForHeader(blockParameter); @@ -109,14 +109,14 @@ public static IEnumerable> SearchForBlocksOnMainChain(this I else { yield return startingBlock; - long startingBlockNumber = startingBlock.Object.Number; - long finalBlockNumber = finalBlockHeader.Object.Number; + ulong startingBlockNumber = startingBlock.Object.Number; + ulong finalBlockNumber = finalBlockHeader.Object.Number; if (startingBlockNumber > finalBlockNumber) { yield return new SearchResult($"From block number: {startingBlockNumber} is greater than to block number {finalBlockNumber}", ErrorCodes.InvalidInput); } - for (long i = startingBlock.Object.Number + 1; i <= finalBlockHeader.Object.Number; ++i) + for (ulong i = startingBlock.Object.Number + 1; i <= finalBlockHeader.Object.Number; ++i) { yield return SearchForBlock(blockFinder, new BlockParameter(i)); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs index b0a6b24ce114..5929d7a63414 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs @@ -89,13 +89,13 @@ public DebugBridge( public byte[] GetDbValue(string dbName, byte[] key) => _dbMappings[dbName][key]; - public ChainLevelInfo GetLevelInfo(long number) => _blockTree.FindLevel(number); + public ChainLevelInfo GetLevelInfo(ulong number) => _blockTree.FindLevel(number); - public int DeleteChainSlice(long startNumber, bool force = false) => _blockTree.DeleteChainSlice(startNumber, force: force); + public int DeleteChainSlice(ulong startNumber, bool force = false) => _blockTree.DeleteChainSlice(startNumber, force: force); public void UpdateHeadBlock(Hash256 blockHash) => _blockTree.UpdateHeadBlock(blockHash); - public Task MigrateReceipts(long from, long to) => _receiptsMigration.Run(from, to); + public Task MigrateReceipts(ulong from, ulong to) => _receiptsMigration.Run(from, to); public void InsertReceipts(BlockParameter blockParameter, TxReceipt[] txReceipts) { @@ -144,7 +144,7 @@ public void InsertReceipts(BlockParameter blockParameter, TxReceipt[] txReceipts return block?.Transactions[txReceipt.Index]; } - public GethLikeTxTrace? GetTransactionTrace(long blockNumber, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null) => + public GethLikeTxTrace? GetTransactionTrace(ulong blockNumber, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null) => _tracer.Trace(blockNumber, index, gethTraceOptions ?? GethTraceOptions.Default, cancellationToken, writer, pipeWriter); public GethLikeTxTrace? GetTransactionTrace(Hash256 blockHash, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null) => @@ -173,7 +173,7 @@ public IReadOnlyCollection GetBlockIntermediateRoots(Hash256 blockHash, public byte[]? GetBlockRlp(BlockParameter parameter) { - if (parameter.BlockNumber is long number) + if (parameter.BlockNumber is ulong number) { Hash256? hash = _blockTree.FindHash(number); if (hash is null) return null; @@ -213,7 +213,7 @@ public IEnumerable TraceBadBlockToFile( public Hash256? GetTransactionBlockHash(Hash256 transactionHash) => _receiptStorage.FindBlockHash(transactionHash); - public IEnumerable> GetBundleTraces(TransactionBundle[] bundles, BlockParameter blockParameter, long? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null) + public IEnumerable> GetBundleTraces(TransactionBundle[] bundles, BlockParameter blockParameter, ulong? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null) { foreach (TransactionBundle bundle in bundles) { @@ -221,7 +221,7 @@ public IEnumerable> GetBundleTraces(TransactionBund } } - private IEnumerable GetBundleTrace(TransactionBundle bundle, BlockParameter blockParameter, long? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions) + private IEnumerable GetBundleTrace(TransactionBundle bundle, BlockParameter blockParameter, ulong? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions) { foreach (TransactionForRpc txForRpc in bundle.Transactions) { @@ -255,6 +255,8 @@ private IEnumerable GetBundleTrace(TransactionBundle bundle, Bl } } - static GethLikeTxTrace? CreateFailTrace(long? gasLimit) => new() { Failed = true, Gas = gasLimit ?? 0, ReturnValue = [] }; + // NOTE: gasLimit is ulong? since Transaction.GasLimit and TransactionForRpc.Gas are ulong. + // GethLikeTxTrace.Gas is also ulong. No overflow risk here. + static GethLikeTxTrace? CreateFailTrace(ulong? gasLimit) => new() { Failed = true, Gas = gasLimit ?? 0UL, ReturnValue = [] }; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index 605df954c50c..cf059110ef93 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -51,13 +51,13 @@ public class DebugRpcModule( public ResultWrapper debug_getChainLevel(in long number) { - ChainLevelInfo? levelInfo = debugBridge.GetLevelInfo(number); + ChainLevelInfo? levelInfo = debugBridge.GetLevelInfo(number >= 0 ? (ulong)number : 0UL); return levelInfo is null ? ResultWrapper.Fail($"Chain level {number} does not exist", ErrorCodes.ResourceNotFound) : ResultWrapper.Success(new ChainLevelForRpc(levelInfo)); } - public ResultWrapper debug_deleteChainSlice(in long startNumber, bool force = false) => ResultWrapper.Success(debugBridge.DeleteChainSlice(startNumber, force)); + public ResultWrapper debug_deleteChainSlice(in long startNumber, bool force = false) => ResultWrapper.Success(debugBridge.DeleteChainSlice(startNumber >= 0 ? (ulong)startNumber : 0UL, force)); public ResultWrapper debug_traceTransaction(Hash256 transactionHash, GethTraceOptions? options = null) { @@ -211,7 +211,7 @@ public ResultWrapper debug_traceTransactionByBlockAndIndex(Bloc return headerError; } - long? blockNo = blockParameter.BlockNumber; + ulong? blockNo = blockParameter.BlockNumber; if (!blockNo.HasValue) { throw new InvalidDataException("Block number value incorrect"); @@ -220,7 +220,7 @@ public ResultWrapper debug_traceTransactionByBlockAndIndex(Bloc if (CanStreamStructLogs(options)) { GethTraceOptions effective = options ?? GethTraceOptions.Default; - long resolvedBlockNo = blockNo.Value; + ulong resolvedBlockNo = blockNo.Value; return ResultWrapper.Success(BuildStreamingResult( (writer, pipeWriter, token) => debugBridge.GetTransactionTrace(resolvedBlockNo, index, token, effective, writer, pipeWriter))); @@ -300,7 +300,7 @@ public ResultWrapper debug_traceTransactionInBlockByIndex(byte[ return ResultWrapper.Success(transactionTrace); } - public async Task> debug_migrateReceipts(long from, long to) => + public async Task> debug_migrateReceipts(ulong from, ulong to) => ResultWrapper.Success(await debugBridge.MigrateReceipts(from, to)); public Task> debug_insertReceipts(BlockParameter blockParameter, ReceiptForRpc[] receiptForRpc) @@ -464,8 +464,8 @@ public ResultWrapper> debug_intermediateRoots(Hash2 public ResultWrapper debug_gcStats() => throw new NotImplementedException(); - public ResultWrapper debug_getBlockRlp(long blockNumber) => - GetBlockRlpOrFail(new BlockParameter(blockNumber)); + public ResultWrapper debug_getBlockRlp(ulong blockNumber) => + GetBlockRlpOrFail(new BlockParameter(blockNumber >= 0 ? blockNumber : 0UL)); public ResultWrapper debug_getBlockRlpByHash(Hash256 hash) => GetBlockRlpOrFail(new BlockParameter(hash)); @@ -734,11 +734,11 @@ private ResultWrapper>> TraceCallManyWi // SimulateTxExecutor inserts filler blocks between bundles when BlockOverride.Number has gaps. // Pre-compute the block number each bundle targets so we can drop fillers from the result and // keep a 1:1 mapping to the input bundles. - HashSet bundleBlockNumbers = new(bundles.Length); - long lastBlockNumber = header.Number; + HashSet bundleBlockNumbers = new(bundles.Length); + ulong lastBlockNumber = header.Number; foreach (TransactionBundle bundle in bundles) { - long number = (long)bundle.BlockOverride.GetBlockNumber(lastBlockNumber); + ulong number = bundle.BlockOverride.GetBlockNumber(lastBlockNumber); bundleBlockNumbers.Add(number); lastBlockNumber = number; } @@ -765,7 +765,7 @@ private ResultWrapper>> TraceCallManyWi } IEnumerable> bundleTraces = simulationResult.Data - .Where(blockResult => blockResult.Number is long n && bundleBlockNumbers.Contains(n)) + .Where(blockResult => blockResult.Number is ulong n && bundleBlockNumbers.Contains(n)) .Select(blockResult => blockResult.Traces); return ResultWrapper>>.Success(bundleTraces); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/GethLikeTxTraceStreamingBundleResult.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/GethLikeTxTraceStreamingBundleResult.cs index 6c2c7fda5d00..cc718e2dc75b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/GethLikeTxTraceStreamingBundleResult.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/GethLikeTxTraceStreamingBundleResult.cs @@ -34,14 +34,14 @@ public sealed class GethLikeTxTraceStreamingBundleResult : JsonStreamingResultBa private readonly IDebugBridge _bridge; private readonly TransactionBundle[] _bundles; private readonly BlockParameter _blockParameter; - private readonly long? _gasCap; + private readonly ulong? _gasCap; private readonly GethTraceOptions _options; public GethLikeTxTraceStreamingBundleResult( IDebugBridge bridge, TransactionBundle[] bundles, BlockParameter blockParameter, - long? gasCap, + ulong? gasCap, GethTraceOptions options, CancellationTokenSource timeoutCts, ILogger logger) @@ -102,7 +102,7 @@ private void EmitTraceForTx(Utf8JsonWriter writer, PipeWriter? pipeWriter, Cance Result txResult = txForRpc.ToTransaction(validateUserInput: true, gasCap: _gasCap); if (!txResult.Success(out Transaction? tx, out string? validationError)) { - StructLogEnvelopeWriter.EmitFailedTrace(writer, txForRpc.Gas ?? 0L, validationError); + StructLogEnvelopeWriter.EmitFailedTrace(writer, txForRpc.Gas ?? 0UL, validationError); return; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs index d2da45ad2f30..6c2b69c33e63 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs @@ -18,7 +18,7 @@ namespace Nethermind.JsonRpc.Modules.DebugModule; public interface IDebugBridge { GethLikeTxTrace? GetTransactionTrace(Hash256 transactionHash, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); - GethLikeTxTrace? GetTransactionTrace(long blockNumber, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); + GethLikeTxTrace? GetTransactionTrace(ulong blockNumber, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? GetTransactionTrace(Hash256 blockHash, int index, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? GetTransactionTrace(Rlp blockRlp, Hash256 transactionHash, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); GethLikeTxTrace? GetTransactionTrace(Block block, Hash256 txHash, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null, Utf8JsonWriter? writer = null, PipeWriter? pipeWriter = null); @@ -31,10 +31,10 @@ public interface IDebugBridge byte[] GetBlockRlp(BlockParameter param); byte[] GetDbValue(string dbName, byte[] key); object GetConfigValue(string category, string name); - ChainLevelInfo GetLevelInfo(long number); - int DeleteChainSlice(long startNumber, bool force = false); + ChainLevelInfo GetLevelInfo(ulong number); + int DeleteChainSlice(ulong startNumber, bool force = false); void UpdateHeadBlock(Hash256 blockHash); - Task MigrateReceipts(long from, long to); + Task MigrateReceipts(ulong from, ulong to); void InsertReceipts(BlockParameter blockParameter, TxReceipt[] receipts); SyncReportSummary GetCurrentSyncStage(); bool HaveNotSyncedHeadersYet(); @@ -44,5 +44,5 @@ public interface IDebugBridge TxReceipt[]? GetReceiptsForBlock(BlockParameter param); Transaction? GetTransactionFromHash(Hash256 hash); Hash256? GetTransactionBlockHash(Hash256 transactionHash); - IEnumerable> GetBundleTraces(TransactionBundle[] bundles, BlockParameter blockParameter, long? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null); + IEnumerable> GetBundleTraces(TransactionBundle[] bundles, BlockParameter blockParameter, ulong? gasCap, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs index a51dafbdfcd6..d611d6d9ce5b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs @@ -84,7 +84,7 @@ public interface IDebugRpcModule : IRpcModule ResultWrapper debug_traceTransactionInBlockByIndex(byte[] blockRlp, int txIndex, GethTraceOptions options = null); [JsonRpcMethod(Description = "Sets the block number up to which receipts will be migrated to (Nethermind specific).")] - Task> debug_migrateReceipts(long from, long to); + Task> debug_migrateReceipts(ulong from, ulong to); [JsonRpcMethod(Description = "Insert receipts for the block after verifying receipts root correctness.")] Task> debug_insertReceipts(BlockParameter blockParameter, ReceiptForRpc[] receiptForRpc); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs index 4b5e71bdc1ff..2b55494f2ee2 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs @@ -29,7 +29,7 @@ public static void EmitTraceObject( CancellationToken cancellationToken, Func runTrace, ILogger logger, - long fallbackGas = 0L) + ulong fallbackGas = 0UL) { GethLikeTxTrace? trace = null; Exception? failure = null; @@ -76,7 +76,7 @@ public static void EmitTraceObject( /// Writes a failure trace envelope for the case where the trace was never invoked /// (e.g. tx couldn't even be constructed from RPC input). No structLogs are emitted. /// - public static void EmitFailedTrace(Utf8JsonWriter writer, long gasLimit, string? errorMessage = null) + public static void EmitFailedTrace(Utf8JsonWriter writer, ulong gasLimit, string? errorMessage = null) { writer.WriteStartObject(); writer.WritePropertyName("structLogs"u8); @@ -123,9 +123,9 @@ private static string FormatErrorDescription(TransactionResult result) private static string ReplacePrefix(string s, string oldPrefix, string newPrefix) => s.StartsWith(oldPrefix, StringComparison.Ordinal) ? newPrefix + s[oldPrefix.Length..] : s; - private static void WriteFooter(Utf8JsonWriter writer, GethLikeTxTrace? trace, string? errorMessage, int errorCode, long fallbackGas) + private static void WriteFooter(Utf8JsonWriter writer, GethLikeTxTrace? trace, string? errorMessage, int errorCode, ulong fallbackGas) { - long gas = trace?.Gas ?? fallbackGas; + ulong gas = trace?.Gas ?? fallbackGas; bool failed = errorMessage is not null || trace is null || trace.Failed; byte[] returnValue = trace?.ReturnValue ?? []; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ErrorWrapper.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ErrorWrapper.cs index f0d23a623c44..48c4803a3757 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ErrorWrapper.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ErrorWrapper.cs @@ -13,10 +13,10 @@ namespace Nethermind.JsonRpc.Modules.Eth; ///
internal static class ErrorWrapper { - public static string EthCall(string inner, long gasLimit) => + public static string EthCall(string inner, ulong gasLimit) => $"err: {inner} (supplied gas {gasLimit})"; - public static string EstimateGasBinarySearch(string inner, long gas) => + public static string EstimateGasBinarySearch(string inner, ulong gas) => $"failed with {gas} gas: {inner}"; public static string CreateAccessList(string inner, Hash256 txHash) => diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index e27b81c4c820..23ca286e1fb7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -85,7 +85,7 @@ public override ResultWrapper Execute( public ResultWrapper ExecuteTx(TransactionForRpc transactionCall, BlockParameter? blockParameter, Dictionary? stateOverride = null, BlockOverride? blockOverride = null) { - if (blockOverride?.GasLimit > (ulong)_rpcConfig.GasCap!.Value) + if (blockOverride?.GasLimit > _rpcConfig.GasCap!.Value) return ResultWrapper.Fail($"GasLimit value is too large, max value {_rpcConfig.GasCap.Value}", ErrorCodes.InvalidInput); _blockOverride = blockOverride; return Execute(transactionCall, blockParameter, stateOverride); @@ -165,7 +165,7 @@ private class EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFi { if (BlockOverride?.GasLimit is not null) { - transactionCall.Gas = (long)BlockOverride.GasLimit.Value; + transactionCall.Gas = BlockOverride.GasLimit.Value; } else { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index ab2055c5d1d0..12c67f55e831 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -153,7 +153,7 @@ public ResultWrapper eth_protocolVersion() return ResultWrapper.Success(gasPriceWithBaseFee); } - public ResultWrapper eth_feeHistory(int blockCount, BlockParameter newestBlock, double[] rewardPercentiles) => _feeHistoryOracle.GetFeeHistory(blockCount, newestBlock, rewardPercentiles); + public ResultWrapper eth_feeHistory(ulong blockCount, BlockParameter newestBlock, double[] rewardPercentiles) => _feeHistoryOracle.GetFeeHistory(blockCount, newestBlock, rewardPercentiles); public ResultWrapper> eth_accounts() { @@ -167,10 +167,10 @@ public ResultWrapper> eth_accounts() } } - public Task> eth_blockNumber() + public Task> eth_blockNumber() { - long number = _blockchainBridge.HeadBlock?.Number ?? 0; - return Task.FromResult(ResultWrapper.Success(number)); + ulong number = _blockchainBridge.HeadBlock?.Number ?? 0; + return Task.FromResult(ResultWrapper.Success(number)); } public Task> eth_getBalance(Address address, BlockParameter? blockParameter = null) @@ -860,7 +860,7 @@ ResultWrapper> FailWithNoHeadersSyncedYet(SearchResult>.Fail("requested block range is in the future", ErrorCodes.InvalidParams); @@ -1142,11 +1142,11 @@ public ResultWrapper eth_config() public ResultWrapper eth_getBlockAccessListByHash(Hash256 blockHash) => GetBlockAccessList(blockHash, null); - public ResultWrapper eth_getBlockAccessListByNumber(long blockNumber) - => GetBlockAccessList(null, blockNumber); - private ResultWrapper GetBlockAccessList(Hash256? blockHash, long? blockNumber) + public ResultWrapper eth_getBlockAccessListByNumber(ulong blockNumber) + => GetBlockAccessList(null, blockNumber >= 0 ? blockNumber : null); + private ResultWrapper GetBlockAccessList(Hash256? blockHash, ulong? blockNumber) { - Block block = blockHash is null ? _blockFinder.FindBlock(blockNumber.Value) : _blockFinder.FindBlock(blockHash); + Block block = blockHash is null ? _blockFinder.FindBlock(blockNumber!.Value) : _blockFinder.FindBlock(blockHash); if (block is null) { return ResultWrapper.Fail("Resource not found", ErrorCodes.BlockAccessListResourceNotFound); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs index e9de24252722..65ab8e8f27ad 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs @@ -27,15 +27,15 @@ public class FeeHistoryOracle : IFeeHistoryOracle, IDisposable private static readonly ResultWrapper _validationPassed = ResultWrapper.Success(null); private const int MaxBlockCount = 1024; private const int RewardPercentilesLengthLimit = 100; - private readonly int _oldestBlockDistanceFromHeadAllowedInCache; - private long _lastCleanupHeadBlockNumber = 0; + private readonly ulong _oldestBlockDistanceFromHeadAllowedInCache; + private ulong _lastCleanupHeadBlockNumber = 0; private Task? _cleanupTask = null; private readonly ConcurrentDictionary _feeHistoryCache = new(); private readonly IBlockTree _blockTree; private readonly IReceiptStorage _receiptStorage; private readonly ISpecProvider _specProvider; - public FeeHistoryOracle(IBlockTree blockTree, IReceiptStorage receiptStorage, ISpecProvider specProvider, int? maxDistanceFromHead = null) + public FeeHistoryOracle(IBlockTree blockTree, IReceiptStorage receiptStorage, ISpecProvider specProvider, ulong? maxDistanceFromHead = null) { _blockTree = blockTree; _receiptStorage = receiptStorage; @@ -58,7 +58,7 @@ private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e) => } }); - private readonly record struct RewardInfo(long GasUsed, UInt256 PremiumPerGas); + private readonly record struct RewardInfo(ulong GasUsed, UInt256 PremiumPerGas); private readonly struct RewardInfoByPremiumAscendingComparer : IComparer { @@ -67,7 +67,7 @@ private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e) => } private readonly record struct BlockFeeHistorySearchInfo( - long BlockNumber, + ulong BlockNumber, UInt256 BlockBaseFeePerGas, UInt256 BaseFeePerGasEst, UInt256 BaseFeePerBlobGas, @@ -75,7 +75,7 @@ private readonly record struct BlockFeeHistorySearchInfo( double GasUsedRatio, double BlobGasUsedRatio, Hash256? ParentHash, - long GasUsed, + ulong GasUsed, int BlockTransactionsLength, List RewardsInBlocks); @@ -95,7 +95,7 @@ private readonly record struct BlockFeeHistorySearchInfo( : SaveHistorySearchInfo(block); } - private BlockFeeHistorySearchInfo? GetHistorySearchInfo(Hash256 blockHash, long blockNumber) + private BlockFeeHistorySearchInfo? GetHistorySearchInfo(Hash256 blockHash, ulong blockNumber) { if (!_feeHistoryCache.TryGetValue(blockHash, out BlockFeeHistorySearchInfo info)) { @@ -157,7 +157,7 @@ private bool ShouldCache(Block block) => _blockTree.Head is null || block.Number >= _blockTree.Head.Number - _oldestBlockDistanceFromHeadAllowedInCache; public ResultWrapper GetFeeHistory( - int blockCount, + ulong blockCount, BlockParameter newestBlock, double[] rewardPercentiles) { @@ -182,7 +182,7 @@ public ResultWrapper GetFeeHistory( BlockFeeHistorySearchInfo info = historyInfo.Value; // Assumes if blockCount is ever greater than the BlockNumber then BlockNumber must fall within integer size limits - int effectiveBlockCount = info.BlockNumber < blockCount - 1 ? (int)info.BlockNumber + 1 : blockCount; + int effectiveBlockCount = info.BlockNumber < blockCount - 1 ? (int)info.BlockNumber + 1 : (int)blockCount; int tempBlockCount = effectiveBlockCount + 1; ArrayPoolList baseFeePerGas = new(tempBlockCount, tempBlockCount); ArrayPoolList baseFeePerBlobGas = new(tempBlockCount, tempBlockCount); @@ -192,7 +192,7 @@ public ResultWrapper GetFeeHistory( ? new ArrayPoolList>(effectiveBlockCount, effectiveBlockCount) : null; - long oldestBlockNumber = info.BlockNumber; + ulong oldestBlockNumber = info.BlockNumber; baseFeePerGas[effectiveBlockCount] = info.BaseFeePerGasEst; baseFeePerBlobGas[effectiveBlockCount] = info.BaseFeePerBlobGasEst; @@ -222,8 +222,8 @@ public ResultWrapper GetFeeHistory( private void TryRunCleanup() { - long headNumber = _blockTree.Head?.Number ?? 0; - long lastCleanupHeadBlockNumber = _lastCleanupHeadBlockNumber; + ulong headNumber = _blockTree.Head?.Number ?? 0; + ulong lastCleanupHeadBlockNumber = _lastCleanupHeadBlockNumber; if (lastCleanupHeadBlockNumber != headNumber && _feeHistoryCache.Count > 2 * MaxBlockCount // let's let the cache grow a bit and do less cleanup && _cleanupTask is null @@ -254,12 +254,12 @@ private void CleanupCache() private List GetRewardsInBlock(Block block) { - static IEnumerable CalculateGasUsed(TxReceipt[] txReceipts) + static IEnumerable CalculateGasUsed(TxReceipt[] txReceipts) { - long previousGasUsedTotal = 0; + ulong previousGasUsedTotal = 0; foreach (TxReceipt receipt in txReceipts) { - long gasUsedTotal = receipt.GasUsedTotal; + ulong gasUsedTotal = receipt.GasUsedTotal; yield return gasUsedTotal - previousGasUsedTotal; previousGasUsedTotal = gasUsedTotal; } @@ -267,14 +267,14 @@ static IEnumerable CalculateGasUsed(TxReceipt[] txReceipts) TxReceipt[] receipts = _receiptStorage.Get(block, false); Transaction[] txs = block.Transactions; - using ArrayPoolListRef gasUsed = new(txs.Length, receipts.Length == block.Transactions.Length + using ArrayPoolListRef gasUsed = new(txs.Length, receipts.Length == block.Transactions.Length ? CalculateGasUsed(receipts) // If no receipts available, approximate on GasLimit // We could just go with null here too and just don't return percentiles : txs.Select(static tx => tx.GasLimit)); List rewardInfos = new(txs.Length); - Span gasUsedSpan = gasUsed.AsSpan(); + Span gasUsedSpan = gasUsed.AsSpan(); for (int i = 0; i < txs.Length; i++) { txs[i].TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas); @@ -291,13 +291,13 @@ private static ArrayPoolList CalculatePercentileValues( double[] rewardPercentiles, List rewardsInBlock) { - long sumGasUsed = rewardsInBlock[0].GasUsed; + ulong sumGasUsed = rewardsInBlock[0].GasUsed; int txIndex = 0; ArrayPoolList percentileValues = new(rewardPercentiles.Length); foreach (double percentile in rewardPercentiles) { - double thresholdGasUsed = (ulong)(blockInfo.GasUsed * percentile / 100); + double thresholdGasUsed = blockInfo.GasUsed * percentile / 100; while (txIndex + 1 < rewardsInBlock.Count && sumGasUsed < thresholdGasUsed) { txIndex++; @@ -310,7 +310,7 @@ private static ArrayPoolList CalculatePercentileValues( return percentileValues; } - private static ResultWrapper Validate(int blockCount, BlockParameter newestBlock, double[] rewardPercentiles) + private static ResultWrapper Validate(ulong blockCount, BlockParameter newestBlock, double[] rewardPercentiles) { if (newestBlock.Type == BlockParameterType.BlockHash) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/IFeeHistoryOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/IFeeHistoryOracle.cs index e032e66896bf..733e4e17b41a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/IFeeHistoryOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/IFeeHistoryOracle.cs @@ -7,6 +7,6 @@ namespace Nethermind.JsonRpc.Modules.Eth.FeeHistory { public interface IFeeHistoryOracle { - ResultWrapper GetFeeHistory(int blockCount, BlockParameter newestBlock, double[] rewardPercentiles); + ResultWrapper GetFeeHistory(ulong blockCount, BlockParameter newestBlock, double[] rewardPercentiles); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistoryResults.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistoryResults.cs index 3f44d830d223..4b8d6d3c46eb 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistoryResults.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistoryResults.cs @@ -9,7 +9,7 @@ namespace Nethermind.JsonRpc.Modules.Eth; public class FeeHistoryResults( - long oldestBlock, + ulong oldestBlock, ArrayPoolList baseFeePerGas, ArrayPoolList gasUsedRatio, ArrayPoolList baseFeePerBlobGas, @@ -27,7 +27,7 @@ public class FeeHistoryResults( [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ArrayPoolList BlobGasUsedRatio { get; } = blobGasUsedRatio; - public long OldestBlock { get; } = oldestBlock; + public ulong OldestBlock { get; } = oldestBlock; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ArrayPoolList>? Reward { get; } = reward; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs index f2455fc5ea3d..9a38c18e6d95 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs @@ -54,7 +54,7 @@ public virtual ValueTask GetGasPriceEstimate() return ValueTask.FromResult(gasPriceEstimate!); } - internal IEnumerable GetGasPricesFromRecentBlocks(long blockNumber) => + internal IEnumerable GetGasPricesFromRecentBlocks(ulong blockNumber) => GetGasPricesFromRecentBlocks(blockNumber, BlockLimit, static (transaction, eip1559Enabled, baseFee) => transaction.CalculateEffectiveGasPrice(eip1559Enabled, baseFee)); @@ -86,14 +86,18 @@ public virtual UInt256 GetMaxPriorityGasFeeEstimate() private delegate UInt256 CalculateGas(Transaction transaction, bool eip1559, UInt256 baseFee); - private IEnumerable GetGasPricesFromRecentBlocks(long blockNumber, int numberOfBlocks, CalculateGas calculateGasFromTransaction) + private IEnumerable GetGasPricesFromRecentBlocks(ulong blockNumber, int numberOfBlocks, CalculateGas calculateGasFromTransaction) { - IEnumerable GetBlocks(long currentBlockNumber) + IEnumerable GetBlocks(ulong currentBlockNumber) { - while (currentBlockNumber >= 0) + while (true) { if (_logger.IsTrace) _logger.Trace($"GasPriceOracle - searching for block number {currentBlockNumber}"); yield return _blockFinder.FindBlock(currentBlockNumber)!; + if (currentBlockNumber == 0) + { + break; + } currentBlockNumber--; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 68d8cc9b1826..97abc99913ac 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -50,7 +50,7 @@ public interface IEthRpcModule : IRpcModule Description = "Returns block fee history.", IsSharable = true, ExampleResponse = "{\"baseFeePerGas\": [\"0x116c1cbb03\", \"0x10c3714c06\"], \"gasUsedRatio\": [0.3487305666666667, 0.3], \"oldestBlock\": \"0xc7e5ff\", \"reward\": [[\"0x3b9aca00\",\"0x3b9aca00\"], [\"0x0\",\"0x3bb24dfa\"]]}")] - ResultWrapper eth_feeHistory(int blockCount, BlockParameter newestBlock, double[] rewardPercentiles); + ResultWrapper eth_feeHistory(ulong blockCount, BlockParameter newestBlock, double[] rewardPercentiles); [JsonRpcMethod(IsImplemented = false, Description = "Returns full state snapshot", IsSharable = true)] ResultWrapper eth_snapshot(); @@ -86,7 +86,7 @@ public interface IEthRpcModule : IRpcModule Description = "Returns current block number", IsSharable = true, ExampleResponse = "0x885480")] - Task> eth_blockNumber(); + Task> eth_blockNumber(); [JsonRpcMethod(IsImplemented = true, Description = "Returns account balance", @@ -356,6 +356,6 @@ ResultWrapper eth_getProof( ResultWrapper eth_getBlockAccessListByHash(Hash256 blockHash); [JsonRpcMethod(Description = "Retrieves block access list for a block by number.")] - ResultWrapper eth_getBlockAccessListByNumber(long number); + ResultWrapper eth_getBlockAccessListByNumber(ulong number); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index afb45febb6f2..ea00ffcc6880 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -120,7 +120,7 @@ public override ResultWrapper>> Execut if (call.BlockStateCalls is not null) { - long lastBlockNumber = header.Number; + ulong lastBlockNumber = header.Number; ulong lastBlockTime = header.Timestamp; using ArrayPoolListRef> completeBlockStateCalls = new(call.BlockStateCalls.Count); @@ -133,14 +133,14 @@ public override ResultWrapper>> Execut if (givenNumber > long.MaxValue) return ResultWrapper>>.Fail($"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); - if (givenNumber <= (ulong)lastBlockNumber) + if (givenNumber <= lastBlockNumber) return ResultWrapper>>.Fail(SimulateErrorMessages.BlockNumberNotIncreasing, ErrorCodes.InvalidInputBlocksOutOfOrder); // if the no. of filler blocks are greater than maximum simulate blocks cap - if (givenNumber - (ulong)lastBlockNumber > (ulong)_blocksLimit) + if (givenNumber - lastBlockNumber > (ulong)_blocksLimit) return ResultWrapper>>.Fail($"too many blocks", ErrorCodes.ClientLimitExceededError); - for (ulong fillBlockNumber = (ulong)lastBlockNumber + 1; fillBlockNumber < givenNumber; fillBlockNumber++) + for (ulong fillBlockNumber = lastBlockNumber + 1; fillBlockNumber < givenNumber; fillBlockNumber++) { ulong fillBlockTime = lastBlockTime + _secondsPerSlot; completeBlockStateCalls.Add(new BlockStateCall @@ -167,11 +167,11 @@ public override ResultWrapper>> Execut blockToSimulate.BlockOverrides.Time = lastBlockTime + _secondsPerSlot; lastBlockTime = (ulong)blockToSimulate.BlockOverrides.Time; } - lastBlockNumber = (long)givenNumber; + lastBlockNumber = givenNumber; if (blockToSimulate.StateOverrides is not null) { - IReleaseSpec spec = specProvider.GetSpec((long)givenNumber, blockToSimulate.BlockOverrides.Time); + IReleaseSpec spec = specProvider.GetSpec(givenNumber, blockToSimulate.BlockOverrides.Time); foreach ((Address address, AccountOverride accountOverride) in blockToSimulate.StateOverrides) { if (accountOverride.MovePrecompileToAddress is null) continue; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs index 91ae801f3f89..0ed137dc3df5 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs @@ -31,8 +31,8 @@ public ResultWrapper logIndex_status() => ResultWrapper logIndex_status() => ResultWrapper - parameter.BlockNumber ?? blockFinder.FindBlock(parameter)?.Number; + (long?)(parameter.BlockNumber ?? blockFinder.FindBlock(parameter)?.Number); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs index 47a7d1b10180..387ddc371e80 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexStatus.cs @@ -7,7 +7,7 @@ namespace Nethermind.JsonRpc.Modules.LogIndex; public class LogIndexStatus { - public readonly record struct Range(int? FromBlock, int? ToBlock); + public readonly record struct Range(ulong? FromBlock, ulong? ToBlock); public required Range Current { get; init; } public required Range Target { get; init; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs index 5d31454d1938..8d01aaec42a7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs @@ -27,7 +27,7 @@ public class ParityTransaction public Address To { get; set; } public UInt256? Value { get; set; } public UInt256? GasPrice { get; set; } - public long? Gas { get; set; } + public ulong? Gas { get; set; } public byte[] Input { get; set; } public byte[] Raw { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SyncingSubscription.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SyncingSubscription.cs index fb3ceb4d8a95..96b5ca357170 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SyncingSubscription.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SyncingSubscription.cs @@ -38,9 +38,9 @@ public SyncingSubscription( internal sealed class SubscriptionSyncingResult { - public long? StartingBlock { get; set; } - public long? CurrentBlock { get; set; } - public long? HighestBlock { get; set; } + public ulong? StartingBlock { get; set; } + public ulong? CurrentBlock { get; set; } + public ulong? HighestBlock { get; set; } } private void OnConditionsChange(object? sender, BlockEventArgs e) => ScheduleAction(async () => diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ParityTxTraceFromStore.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ParityTxTraceFromStore.cs index ca86ee532292..01aa88b80ae7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ParityTxTraceFromStore.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ParityTxTraceFromStore.cs @@ -65,8 +65,8 @@ private ParityTxTraceFromStore() public Hash256 BlockHash { get; set; } - [JsonConverter(typeof(LongRawJsonConverter))] - public long BlockNumber { get; set; } + [JsonConverter(typeof(ULongRawJsonConverter))] + public ulong BlockNumber { get; set; } public ParityTraceResult Result { get; set; } diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeFinalizationManagerTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeFinalizationManagerTests.cs index ad173404fc31..dd6da82aad7f 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeFinalizationManagerTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeFinalizationManagerTests.cs @@ -39,7 +39,7 @@ public void TearDown() private void SetHead(bool postMerge) { - Block head = Build.A.Block.WithNumber(postMerge ? 30_000_000 : 1_000).TestObject; + Block head = Build.A.Block.WithNumber(postMerge ? 30_000_000UL : 1_000UL).TestObject; _blockTree.Head.Returns(head); _poSSwitcher.IsPostMerge(head.Header).Returns(postMerge); } diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeFinalizationManager.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeFinalizationManager.cs index 923bf0c7ccbe..4aece9eb87ec 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeFinalizationManager.cs @@ -44,9 +44,9 @@ private void OnTerminalBlock(object? sender, EventArgs e) _auRaBlockFinalizationManager.Dispose(); } - public long GetLastLevelFinalizedBy(Hash256 blockHash) => _auRaBlockFinalizationManager.GetLastLevelFinalizedBy(blockHash); + public ulong GetLastLevelFinalizedBy(Hash256 blockHash) => _auRaBlockFinalizationManager.GetLastLevelFinalizedBy(blockHash); - public long? GetFinalizationLevel(long level) => _auRaBlockFinalizationManager.GetFinalizationLevel(level); + public ulong? GetFinalizationLevel(ulong level) => _auRaBlockFinalizationManager.GetFinalizationLevel(level); public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor) { @@ -54,7 +54,7 @@ public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor) _auRaBlockFinalizationManager.SetMainBlockBranchProcessor(branchProcessor); } - public override long LastFinalizedBlockLevel => IsPostMerge + public override ulong LastFinalizedBlockLevel => IsPostMerge ? _manualBlockFinalizationManager.LastFinalizedBlockLevel : _auRaBlockFinalizationManager.LastFinalizedBlockLevel; diff --git a/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs b/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs index 65fa0f48f50b..eb3913752ad1 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/Contracts/WithdrawalContract.cs @@ -21,7 +21,7 @@ public class WithdrawalContract( IAbiEncoder abiEncoder, Address contractAddress) : CallableContract(transactionProcessor, abiEncoder, contractAddress), IWithdrawalContract { - private const long GasLimit = SystemTransactionGasLimit; + private const ulong GasLimit = SystemTransactionGasLimit; public void ExecuteWithdrawals(BlockHeader blockHeader, UInt256 failedMaxCount, IList amounts, IList
addresses) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Benchmark/GetPayloadV3SerializationBenchmarks.cs b/src/Nethermind/Nethermind.Merge.Plugin.Benchmark/GetPayloadV3SerializationBenchmarks.cs index 7f16b94be537..4fca5bf8b335 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Benchmark/GetPayloadV3SerializationBenchmarks.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Benchmark/GetPayloadV3SerializationBenchmarks.cs @@ -166,7 +166,7 @@ private static Block BuildBlock(int txCount) txs[i] = Build.A.Transaction .WithType(TxType.EIP1559) .WithChainId(1) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasLimit(21_000) .WithMaxFeePerGas(20_000_000_000) .WithMaxPriorityFeePerGas(1_000_000_000) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs index 22d1985b280a..4226e840ce8b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs @@ -175,7 +175,7 @@ public void Can_insert_beacon_headers() Block? beaconBlock = syncedTree.FindBlock(14, BlockTreeLookupOptions.None); BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.BeaconBlockInsert; AddBlockResult insertResult = notSyncedTree.Insert(beaconBlock!, BlockTreeInsertBlockOptions.SaveHeader, headerOptions); - for (int i = 13; i > 9; --i) + for (uint i = 13; i > 9; --i) { BlockHeader? beaconHeader = syncedTree.FindHeader(i, BlockTreeLookupOptions.None); AddBlockResult insertOutcome = notSyncedTree.Insert(beaconHeader!, headerOptions); @@ -192,14 +192,14 @@ public void Can_fill_beacon_headers_gap() BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.BeaconBlockInsert; _ = notSyncedTree.Insert(beaconBlock, BlockTreeInsertBlockOptions.SaveHeader, headerOptions); - for (int i = 13; i > 9; --i) + for (uint i = 13; i > 9; --i) { BlockHeader? beaconHeader = syncedTree.FindHeader(i, BlockTreeLookupOptions.None); AddBlockResult insertOutcome = notSyncedTree.Insert(beaconHeader!, headerOptions); Assert.That(insertOutcome, Is.EqualTo(AddBlockResult.Added)); } - for (int i = 10; i < 14; ++i) + for (uint i = 10; i < 14; ++i) { Block? block = syncedTree.FindBlock(i, BlockTreeLookupOptions.None); AddBlockResult insertOutcome = notSyncedTree.SuggestBlock(block!); @@ -304,7 +304,7 @@ public ScenarioBuilder WithBlockTrees( private void OnNewBestSuggestedBlock(object? sender, BlockEventArgs e) => NotSyncedTree.UpdateMainChain(new[] { e.Block! }, true); - public ScenarioBuilder InsertBeaconPivot(long num) + public ScenarioBuilder InsertBeaconPivot(ulong num) { Block? beaconBlock = SyncedTree.FindBlock(num, BlockTreeLookupOptions.None); AddBlockResult insertResult = NotSyncedTree.Insert(beaconBlock!, BlockTreeInsertBlockOptions.SaveHeader, @@ -315,7 +315,7 @@ public ScenarioBuilder InsertBeaconPivot(long num) return this; } - public ScenarioBuilder SetProcessDestination(long num) + public ScenarioBuilder SetProcessDestination(ulong num) { _beaconPivot!.ProcessDestination = SyncedTree.FindHeader(num, BlockTreeLookupOptions.None); return this; @@ -328,9 +328,9 @@ public ScenarioBuilder ClearBeaconPivot() return this; } - public ScenarioBuilder SuggestBlocks(long low, long high) + public ScenarioBuilder SuggestBlocks(ulong low, ulong high) { - for (long i = low; i <= high; i++) + for (ulong i = low; i <= high; i++) { Block? beaconBlock = SyncedTree!.FindBlock(i, BlockTreeLookupOptions.None); AddBlockResult insertResult = NotSyncedTree!.SuggestBlock(beaconBlock!); @@ -367,12 +367,12 @@ public enum TotalDifficultyMode TheSameAsSyncedTree } - public ScenarioBuilder InsertBeaconHeaders(long low, long high, TotalDifficultyMode tdMode = TotalDifficultyMode.TheSameAsSyncedTree) + public ScenarioBuilder InsertBeaconHeaders(ulong low, ulong high, TotalDifficultyMode tdMode = TotalDifficultyMode.TheSameAsSyncedTree) { BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.BeaconHeaderInsert; if (tdMode == TotalDifficultyMode.Null) headerOptions |= BlockTreeInsertHeaderOptions.TotalDifficultyNotNeeded; - for (long i = high; i >= low; --i) + for (ulong i = high; i >= low; --i) { BlockHeader? beaconHeader = SyncedTree!.FindHeader(i, BlockTreeLookupOptions.None)!; @@ -387,10 +387,10 @@ public ScenarioBuilder InsertBeaconHeaders(long low, long high, TotalDifficultyM return this; } - public ScenarioBuilder InsertBeaconBlocks(long low, long high, TotalDifficultyMode tdMode = TotalDifficultyMode.TheSameAsSyncedTree) + public ScenarioBuilder InsertBeaconBlocks(ulong low, ulong high, TotalDifficultyMode tdMode = TotalDifficultyMode.TheSameAsSyncedTree) { BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.BeaconBlockInsert | BlockTreeInsertHeaderOptions.MoveToBeaconMainChain; - for (long i = high; i >= low; --i) + for (ulong i = high; i >= low; --i) { Block? beaconBlock = SyncedTree!.FindBlock(i, BlockTreeLookupOptions.None); if (tdMode == TotalDifficultyMode.Null) @@ -405,12 +405,12 @@ public ScenarioBuilder InsertBeaconBlocks(long low, long high, TotalDifficultyMo return this; } - public ScenarioBuilder InsertFork(long low, long high, bool moveToBeaconMainChain = false, bool moveSyncedTree = true, ulong nonce = 0) + public ScenarioBuilder InsertFork(ulong low, ulong high, bool moveToBeaconMainChain = false, bool moveSyncedTree = true, ulong nonce = 0) { List blockInfos = []; List blocks = []; Block? parent = null; - for (long i = low; i <= high; i++) + for (ulong i = low; i <= high; i++) { parent ??= SyncedTree.FindBlock(i - 1, BlockTreeLookupOptions.None)!; Block blockToInsert = Build.A.Block.WithNumber(i).WithParent(parent).WithNonce(nonce).TestObject; @@ -433,11 +433,11 @@ public ScenarioBuilder InsertFork(long low, long high, bool moveToBeaconMainChai return this; } - public ScenarioBuilder InsertOtherChainToMain(BlockTree blockTree, long low, long high) + public ScenarioBuilder InsertOtherChainToMain(BlockTree blockTree, ulong low, ulong high) { Block? parent = null; List newBlocks = []; - for (long i = low; i <= high; i++) + for (ulong i = low; i <= high; i++) { parent ??= blockTree.FindBlock(i - 1, BlockTreeLookupOptions.None)!; Block blockToInsert = Build.A.Block.WithNumber(i).WithParent(parent).WithNonce(0).TestObject; @@ -485,9 +485,9 @@ public ScenarioBuilder AssertBestSuggestedBody(long expected, UInt256? expectedT return this; } - public ScenarioBuilder AssertMetadata(int startNumber, int finalNumber, BlockMetadata? metadata) + public ScenarioBuilder AssertMetadata(uint startNumber, uint finalNumber, BlockMetadata? metadata) { - for (int i = startNumber; i < finalNumber; ++i) + for (uint i = startNumber; i < finalNumber; ++i) { ChainLevelInfo? level = NotSyncedTree.FindLevel(i); Assert.That(level?.BeaconMainChainBlock?.Metadata ?? BlockMetadata.None, Is.EqualTo(metadata), $"Block number {i}"); @@ -548,9 +548,9 @@ public ScenarioBuilder AssertChainLevelHelperLength(int count) return this; } - public ScenarioBuilder AssertChainLevel(int startNumber, int finalNumber) + public ScenarioBuilder AssertChainLevel(uint startNumber, int finalNumber) { - for (int i = startNumber; i < finalNumber; ++i) + for (uint i = startNumber; i < finalNumber; ++i) { ChainLevelInfo? level = NotSyncedTree.FindLevel(i)!; BlockInfo? blockInfo = level.MainChainBlock; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/ChainSpecBasedSpecProviderTestsTheMerge.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/ChainSpecBasedSpecProviderTestsTheMerge.cs index 4e3cd6622131..dbc03e58ca6d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/ChainSpecBasedSpecProviderTestsTheMerge.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/ChainSpecBasedSpecProviderTestsTheMerge.cs @@ -17,7 +17,7 @@ public class ChainSpecBasedSpecProviderTestsTheMerge [Test] public void Correctly_read_merge_block_number() { - long terminalBlockNumber = 100; + ulong terminalBlockNumber = 100; ChainSpec chainSpec = new() { Parameters = new ChainParameters @@ -67,7 +67,7 @@ public void Merge_block_number_should_be_null_when_not_set() public void Changing_spec_provider_in_dynamic_merge_transition() { long expectedTerminalPoWBlock = 100; - long newMergeBlock = 50; + ulong newMergeBlock = 50; ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); string path = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Specs/test_spec.json"); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.PayloadProduction.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.PayloadProduction.cs index f6496fe67828..d2fb44581bf5 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.PayloadProduction.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.PayloadProduction.cs @@ -164,7 +164,7 @@ private class TxDelayedSource( { public bool SupportsBlobs { get; } - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) { Hash256 startingHead = blockTree.HeadHash; uint count = 50; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.RelayBuilder.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.RelayBuilder.cs index 71caf9c8de98..9f95836042f7 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.RelayBuilder.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.RelayBuilder.cs @@ -113,9 +113,9 @@ public virtual async Task forkchoiceUpdatedV1_should_communicate_with_boost_rela string expected_receiptsRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"; string expected_logsBloom = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; string expected_prevRandao = "0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760"; - int expected_blockNumber = 1; - long expected_gasLimit = 0x3d0900L; - int expected_gasUsed = 0; + uint expected_blockNumber = 1; + ulong expected_gasLimit = 0x3d0900L; + uint expected_gasUsed = 0; ulong expected_timestamp = 0x3e9UL; string expected_extraData = "0x4e65746865726d696e64"; // Nethermind UInt256 expected_baseFeePerGas = (UInt256)0; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs index b3510985835f..81276f8b0061 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs @@ -1073,7 +1073,7 @@ private class BlockTreePointers public long BestKnownNumber; public BlockHeader? BestSuggestedHeader; public Block? BestSuggestedBody; - public long BestKnownBeaconBlock; + public ulong BestKnownBeaconBlock; public BlockHeader? LowestInsertedBeaconHeader; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs index 032603fcd06b..32f9341ce733 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs @@ -362,7 +362,7 @@ public static IEnumerable WrongInputTestsV1 ]); yield return GetNewBlockRequestBadDataTestCase(static r => r.LogsBloom, bloom); yield return GetNewBlockRequestBadDataTestCase(static r => r.Transactions, [[1]]); - yield return GetNewBlockRequestBadDataTestCase(static r => r.GasUsed, 1); + yield return GetNewBlockRequestBadDataTestCase(static r => r.GasUsed, 1UL); } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs index c4b94321028c..b62eb08c1b78 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs @@ -484,7 +484,7 @@ public async Task getPayloadBodiesByRangeV1_should_trim_trailing_null_bodies( IBlockTree? blockTree = Substitute.For(); blockTree.Head.Returns(Build.A.Block.WithNumber(5).TestObject); - blockTree.FindBlock(Arg.Any()).Returns(input.Impl); + blockTree.FindBlock(Arg.Any()).Returns(input.Impl); using MergeTestBlockchain chain = await CreateBlockchain(Shanghai.Instance, configurer: (builder) => builder @@ -506,8 +506,8 @@ public async Task getPayloadBodiesByRangeV1_should_return_up_to_best_body_number { IBlockTree? blockTree = Substitute.For(); - blockTree.FindBlock(Arg.Any()) - .Returns(static i => Build.A.Block.WithNumber(i.ArgAt(0)).TestObject); + blockTree.FindBlock(Arg.Any()) + .Returns(static i => Build.A.Block.WithNumber(i.ArgAt(0)).TestObject); blockTree.Head.Returns(Build.A.Block.WithNumber(5).TestObject); using MergeTestBlockchain chain = await CreateBlockchain(Shanghai.Instance, configurer: (builder) => builder diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs index 7f7ca3fb8220..c17dceed70a5 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs @@ -522,7 +522,7 @@ public async Task ForkChoiceUpdated_should_return_unsupported_fork_but_change_la [Test] public async Task ForkChoiceUpdated_should_return_valid_for_previous_blocks_without_state_synced() { - static void MarkAsUnprocessed(MergeTestBlockchain chain, int blockNumber) + static void MarkAsUnprocessed(MergeTestBlockchain chain, uint blockNumber) { ChainLevelInfo lvl = chain.ChainLevelInfoRepository.LoadLevel(blockNumber)!; foreach (BlockInfo info in lvl.BlockInfos) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V5.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V5.cs index c7a847801072..ad65c829f70a 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V5.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V5.cs @@ -89,7 +89,7 @@ public async Task Testing_commitBlockV1_advances_chain_head() ITestingRpcModule testingRpcModule = chain.Container.Resolve(); Block head = chain.BlockTree.Head!; - long initialHeadNumber = head.Number; + ulong initialHeadNumber = head.Number; PayloadAttributes payloadAttributes = new() { diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs index b2c74c8407a3..ce15424a7741 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs @@ -763,7 +763,7 @@ private async Task NewPayloadV5_via_engine_built( } } - private static (Transaction tx, Transaction tx2, Transaction tx3, Withdrawal withdrawal) BuildTestTransactionsAndWithdrawal(ulong gasPrice, long gasLimit) + private static (Transaction tx, Transaction tx2, Transaction tx3, Withdrawal withdrawal) BuildTestTransactionsAndWithdrawal(ulong gasPrice, ulong gasLimit) { Transaction tx = Build.A.Transaction .WithTo(TestItem.AddressB) @@ -921,7 +921,7 @@ ReadOnlyBlockAccessList CreateBlockAccessList() UInt256[] extraReads = new UInt256[100]; for (int i = 0; i < extraReads.Length; i++) { - extraReads[i] = new UInt256((ulong)(1_000_000 + i)); + extraReads[i] = 1_000_000UL + (ulong)i; } modifiedAccounts[senderAddress] = CloneAccountChanges(entry, storageReadsOverride: [.. entry.StorageReads, .. extraReads]); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs index e8b1ab4c9da7..28c3220b084d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs @@ -26,8 +26,8 @@ class BlockForRpcForTest : BlockForRpc public async Task CanonicalTreeIsConsistent() { IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); - int destinationBlockNumber = 5000; - long? currentBlockNumber = null; + uint destinationBlockNumber = 5000; + ulong? currentBlockNumber = null; Hash256? currentHash = null; BasicJsonRpcClient client = new(new Uri("http://127.0.0.1:8545"), jsonSerializer, LimboLogs.Instance); do @@ -51,8 +51,8 @@ public async Task CanonicalTreeIsConsistent() public async Task ParentTimestampIsAlwaysLowerThanChildTimestamp() { IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); - int destinationBlockNumber = 5000; - long? currentBlockNumber = null; + uint destinationBlockNumber = 5000; + ulong? currentBlockNumber = null; UInt256? childTimestamp = null; BasicJsonRpcClient client = new(new Uri("http://127.0.0.1:8545"), jsonSerializer, LimboLogs.Instance); do diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs index ff22d384f07b..e3b6c662c103 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs @@ -349,9 +349,10 @@ private static Block CreateBlock( BalKind balKind, ulong? slotNumber) { + // ERROR FIX (line 365): WithNumber now takes ulong; changed int literal 12 to ulong literal 12UL. Block block = Build.A.Block .WithPostMergeRules() - .WithNumber(12) + .WithNumber(12UL) .WithTimestamp(1234) .WithParentHash(TestItem.KeccakA) .WithBeneficiary(TestItem.AddressB) @@ -362,7 +363,7 @@ private static Block CreateBlock( .WithExtraData([1, 2, 3]) .WithBaseFeePerGas(7) .WithGasLimit(30_000_000) - .WithGasUsed(transactions.Length * Transaction.BaseTxGasCost) + .WithGasUsed((ulong)transactions.Length * Transaction.BaseTxGasCost) .WithParentBeaconBlockRoot(TestItem.KeccakE) .WithBlobGasUsed(0) .WithExcessBlobGas(0) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeBetterPeerStrategyTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeBetterPeerStrategyTests.cs index 195409ed524a..f29894306526 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeBetterPeerStrategyTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeBetterPeerStrategyTests.cs @@ -16,13 +16,13 @@ namespace Nethermind.Merge.Plugin.Test; public class MergeBetterPeerStrategyTests { - [TestCase(7, 2, 6, 4, -1)] - [TestCase(7, 4, 6, 4, 0)] - [TestCase(6, 4, 7, 2, 1)] - [TestCase(3, 4, 6, 2, -1)] - [TestCase(3, 2, 3, 4, 0)] - [TestCase(6, 2, 3, 4, 1)] - public void Compare_with_header_and_peer_return_expected_results(long totalDifficulty, long number, long peerTotalDifficulty, long peerNumber, int expectedResult) + [TestCase(7, 2UL, 6, 4UL, -1)] + [TestCase(7, 4UL, 6, 4UL, 0)] + [TestCase(6, 4UL, 7, 2UL, 1)] + [TestCase(3, 4UL, 6, 2UL, -1)] + [TestCase(3, 2UL, 3, 4UL, 0)] + [TestCase(6, 2UL, 3, 4UL, 1)] + public void Compare_with_header_and_peer_return_expected_results(long totalDifficulty, ulong number, long peerTotalDifficulty, ulong peerNumber, int expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); @@ -34,13 +34,13 @@ public void Compare_with_header_and_peer_return_expected_results(long totalDiffi Assert.That(betterPeerStrategy.Compare(header, syncPeer), Is.EqualTo(expectedResult)); } - [TestCase(7, 2, 6, 4, -1)] - [TestCase(7, 4, 6, 4, 0)] - [TestCase(6, 4, 7, 2, 1)] - [TestCase(3, 4, 6, 2, -1)] - [TestCase(3, 2, 3, 4, 0)] - [TestCase(6, 2, 3, 4, 1)] - public void Compare_with_value_and_peer_return_expected_results(long totalDifficulty, long number, long peerTotalDifficulty, long peerNumber, int expectedResult) + [TestCase(7, 2UL, 6, 4UL, -1)] + [TestCase(7, 4UL, 6, 4UL, 0)] + [TestCase(6, 4UL, 7, 2UL, 1)] + [TestCase(3, 4UL, 6, 2UL, -1)] + [TestCase(3, 2UL, 3, 4UL, 0)] + [TestCase(6, 2UL, 3, 4UL, 1)] + public void Compare_with_value_and_peer_return_expected_results(long totalDifficulty, ulong number, long peerTotalDifficulty, ulong peerNumber, int expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); @@ -50,25 +50,25 @@ public void Compare_with_value_and_peer_return_expected_results(long totalDiffic Assert.That(betterPeerStrategy.Compare(((UInt256)totalDifficulty, number), syncPeer), Is.EqualTo(expectedResult)); } - [TestCase(7, 2, 6, 4, -1)] - [TestCase(7, 4, 6, 4, 0)] - [TestCase(6, 4, 7, 2, 1)] - [TestCase(3, 4, 6, 2, -1)] - [TestCase(3, 2, 3, 4, 0)] - [TestCase(6, 2, 3, 4, 1)] - public void Compare_with_values_return_expected_results(long totalDifficulty, long number, long peerTotalDifficulty, long peerNumber, int expectedResult) + [TestCase(7, 2UL, 6, 4UL, -1)] + [TestCase(7, 4UL, 6, 4UL, 0)] + [TestCase(6, 4UL, 7, 2UL, 1)] + [TestCase(3, 4UL, 6, 2UL, -1)] + [TestCase(3, 2UL, 3, 4UL, 0)] + [TestCase(6, 2UL, 3, 4UL, 1)] + public void Compare_with_values_return_expected_results(long totalDifficulty, ulong number, long peerTotalDifficulty, ulong peerNumber, int expectedResult) { MergeBetterPeerStrategy betterPeerStrategy = CreateStrategy(); Assert.That(betterPeerStrategy.Compare(((UInt256)totalDifficulty, number), ((UInt256)peerTotalDifficulty, peerNumber)), Is.EqualTo(expectedResult)); } - [TestCase(6, 4, 7, 2, false)] - [TestCase(6, 2, 7, 2, false)] - [TestCase(7, 2, 7, 4, true)] - [TestCase(3, 4, 5, 2, true)] - [TestCase(3, 2, 3, 4, false)] - [TestCase(4, 2, 3, 4, false)] - public void IsBetterThanLocalChain_return_expected_results(long chainDifficulty, long bestFullBlock, long peerTotalDifficulty, long peerNumber, bool expectedResult) + [TestCase(6, 4UL, 7, 2UL, false)] + [TestCase(6, 2UL, 7, 2UL, false)] + [TestCase(7, 2UL, 7, 4UL, true)] + [TestCase(3, 4UL, 5, 2UL, true)] + [TestCase(3, 2UL, 3, 4UL, false)] + [TestCase(4, 2UL, 3, 4UL, false)] + public void IsBetterThanLocalChain_return_expected_results(long chainDifficulty, ulong bestFullBlock, long peerTotalDifficulty, ulong peerNumber, bool expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); @@ -78,13 +78,13 @@ public void IsBetterThanLocalChain_return_expected_results(long chainDifficulty, Assert.That(betterPeerStrategy.IsBetterThanLocalChain(((UInt256)peerTotalDifficulty, peerNumber), ((UInt256)chainDifficulty, bestFullBlock)), Is.EqualTo(expectedResult)); } - [TestCase(6, 4, 7, 2, false)] - [TestCase(6, 2, 7, 2, false)] - [TestCase(3, 4, 5, 2, true)] - [TestCase(3, 2, 3, 4, true)] - [TestCase(4, 2, 3, 4, false)] - [TestCase(3, 4, 3, 2, false)] - public void IsDesiredPeer_return_expected_results_pre_ttd(long chainDifficulty, long bestHeader, long peerTotalDifficulty, long peerNumber, bool expectedResult) + [TestCase(6, 4UL, 7, 2UL, false)] + [TestCase(6, 2UL, 7, 2UL, false)] + [TestCase(3, 4UL, 5, 2UL, true)] + [TestCase(3, 2UL, 3, 4UL, true)] + [TestCase(4, 2UL, 3, 4UL, false)] + [TestCase(3, 4UL, 3, 2UL, false)] + public void IsDesiredPeer_return_expected_results_pre_ttd(long chainDifficulty, ulong bestHeader, long peerTotalDifficulty, ulong peerNumber, bool expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); @@ -94,11 +94,11 @@ public void IsDesiredPeer_return_expected_results_pre_ttd(long chainDifficulty, Assert.That(betterPeerStrategy.IsDesiredPeer(((UInt256)peerTotalDifficulty, peerNumber), ((UInt256)chainDifficulty, bestHeader)), Is.EqualTo(expectedResult)); } - [TestCase(9, 7, 4, 7, 10, true)] - [TestCase(9, 8, 2, 7, 7, false)] - [TestCase(null, 9, 4, 5, 99, false)] - [TestCase(3, 5, 1, 3, 4, true)] - public void IsDesiredPeer_return_expected_results_post_ttd(long? pivotNumber, long chainDifficulty, long bestHeader, long peerTotalDifficulty, long peerNumber, bool expectedResult) + [TestCase(9UL, 7, 4UL, 7, 10UL, true)] + [TestCase(9UL, 8, 2UL, 7, 7UL, false)] + [TestCase(null, 9, 4UL, 5, 99UL, false)] + [TestCase(3UL, 5, 1UL, 3, 4UL, true)] + public void IsDesiredPeer_return_expected_results_post_ttd(ulong? pivotNumber, long chainDifficulty, ulong bestHeader, long peerTotalDifficulty, ulong peerNumber, bool expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); @@ -118,7 +118,7 @@ public void IsLowerThanTerminalTotalDifficulty_return_expected_results(long tota Assert.That(betterPeerStrategy.IsLowerThanTerminalTotalDifficulty((UInt256)totalDifficulty), Is.EqualTo(expectedResult)); } - private MergeBetterPeerStrategy CreateStrategy(long? beaconPivotNum = null) + private MergeBetterPeerStrategy CreateStrategy(ulong? beaconPivotNum = null) { const long ttd = 5; IPoSSwitcher poSSwitcher = Substitute.For(); @@ -128,7 +128,7 @@ private MergeBetterPeerStrategy CreateStrategy(long? beaconPivotNum = null) if (beaconPivotNum is not null) { beaconPivot.BeaconPivotExists().Returns(true); - beaconPivot.PivotNumber.Returns((long)beaconPivotNum); + beaconPivot.PivotNumber.Returns(beaconPivotNum.Value); } TotalDifficultyBetterPeerStrategy preMergeBetterPeerStrategy = new(LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizationManagerTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizationManagerTests.cs index c81fba8c80a0..67452fd89566 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizationManagerTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizationManagerTests.cs @@ -26,7 +26,7 @@ public void Setup() [Test] public void Dispose_unsubscribes_from_PoSSwitcher_TerminalBlockReached() { - _inner.LastFinalizedBlockLevel.Returns(999L); + _inner.LastFinalizedBlockLevel.Returns(999UL); _manager.Dispose(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizedStateProviderTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizedStateProviderTests.cs index e356edce806a..def70438081e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizedStateProviderTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeFinalizedStateProviderTests.cs @@ -38,12 +38,12 @@ public void Setup() public void FinalizedBlockNumber_BeforeTransition_DelegatesToBaseProvider() { // Arrange - long expectedBlockNumber = 100; + ulong expectedBlockNumber = 100; _poSSwitcher.TransitionFinished.Returns(false); _baseFinalizedStateProvider.FinalizedBlockNumber.Returns(expectedBlockNumber); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(expectedBlockNumber)); @@ -55,7 +55,7 @@ public void FinalizedBlockNumber_BeforeTransition_DelegatesToBaseProvider() public void FinalizedBlockNumber_AfterTransition_WithBlockTreeFinalizedHash_ReturnsHeaderNumber() { // Arrange - long expectedBlockNumber = 200; + ulong expectedBlockNumber = 200; Hash256 finalizedHash = TestItem.KeccakA; BlockHeader finalizedHeader = Build.A.BlockHeader.WithNumber(expectedBlockNumber).WithHash(finalizedHash).TestObject; _poSSwitcher.TransitionFinished.Returns(true); @@ -63,7 +63,7 @@ public void FinalizedBlockNumber_AfterTransition_WithBlockTreeFinalizedHash_Retu _blockTree.FindHeader(finalizedHash, BlockTreeLookupOptions.None).Returns(finalizedHeader); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(expectedBlockNumber)); @@ -74,7 +74,7 @@ public void FinalizedBlockNumber_AfterTransition_WithBlockTreeFinalizedHash_Retu public void FinalizedBlockNumber_AfterTransition_WithBlockCacheFinalizedHash_ReturnsHeaderNumber() { // Arrange - long expectedBlockNumber = 250; + ulong expectedBlockNumber = 250; Hash256 finalizedHash = TestItem.KeccakB; BlockHeader finalizedHeader = Build.A.BlockHeader.WithNumber(expectedBlockNumber).WithHash(finalizedHash).TestObject; _poSSwitcher.TransitionFinished.Returns(true); @@ -83,7 +83,7 @@ public void FinalizedBlockNumber_AfterTransition_WithBlockCacheFinalizedHash_Ret _blockTree.FindHeader(finalizedHash).Returns(finalizedHeader); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(expectedBlockNumber)); @@ -94,8 +94,8 @@ public void FinalizedBlockNumber_AfterTransition_WithBlockCacheFinalizedHash_Ret public void FinalizedBlockNumber_AfterTransition_BlockCacheHasHigherNumber_ReturnsBlockCacheNumber() { // Arrange - long blockTreeBlockNumber = 200; - long blockCacheBlockNumber = 250; + ulong blockTreeBlockNumber = 200; + ulong blockCacheBlockNumber = 250; Hash256 blockTreeHash = TestItem.KeccakA; Hash256 blockCacheHash = TestItem.KeccakB; BlockHeader blockTreeHeader = Build.A.BlockHeader.WithNumber(blockTreeBlockNumber).WithHash(blockTreeHash).TestObject; @@ -108,7 +108,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHasHigherNumber_Retur _blockTree.FindHeader(blockCacheHash).Returns(blockCacheHeader); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(blockCacheBlockNumber)); @@ -118,8 +118,8 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHasHigherNumber_Retur public void FinalizedBlockNumber_AfterTransition_BlockTreeHasHigherNumber_ReturnsBlockTreeNumber() { // Arrange - long blockTreeBlockNumber = 300; - long blockCacheBlockNumber = 250; + ulong blockTreeBlockNumber = 300; + ulong blockCacheBlockNumber = 250; Hash256 blockTreeHash = TestItem.KeccakA; Hash256 blockCacheHash = TestItem.KeccakB; BlockHeader blockTreeHeader = Build.A.BlockHeader.WithNumber(blockTreeBlockNumber).WithHash(blockTreeHash).TestObject; @@ -132,7 +132,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockTreeHasHigherNumber_Return _blockTree.FindHeader(blockCacheHash).Returns(blockCacheHeader); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(blockTreeBlockNumber)); @@ -142,7 +142,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockTreeHasHigherNumber_Return public void FinalizedBlockNumber_AfterTransition_BlockCacheHeaderNotFound_UsesOnlyBlockTree() { // Arrange - long expectedBlockNumber = 200; + ulong expectedBlockNumber = 200; Hash256 blockTreeHash = TestItem.KeccakA; Hash256 blockCacheHash = TestItem.KeccakB; BlockHeader blockTreeHeader = Build.A.BlockHeader.WithNumber(expectedBlockNumber).WithHash(blockTreeHash).TestObject; @@ -154,7 +154,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHeaderNotFound_UsesOn _blockTree.FindHeader(blockCacheHash).Returns((BlockHeader?)null); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(expectedBlockNumber)); @@ -164,14 +164,14 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHeaderNotFound_UsesOn public void FinalizedBlockNumber_AfterTransition_NoFinalizedHeaders_DelegatesToBaseProvider() { // Arrange - long expectedBlockNumber = 150; + ulong expectedBlockNumber = 150; _poSSwitcher.TransitionFinished.Returns(true); _blockTree.FinalizedHash.Returns((Hash256?)null); _blockCacheService.FinalizedHash.Returns((Hash256?)null); _baseFinalizedStateProvider.FinalizedBlockNumber.Returns(expectedBlockNumber); // Act - long result = _provider.FinalizedBlockNumber; + ulong result = _provider.FinalizedBlockNumber; // Assert Assert.That(result, Is.EqualTo(expectedBlockNumber)); @@ -182,8 +182,8 @@ public void FinalizedBlockNumber_AfterTransition_NoFinalizedHeaders_DelegatesToB public void GetFinalizedStateRootAt_ReturnsNull_WhenBlockNumberExceedsFinalizedBlock() { // Arrange - long finalizedBlockNumber = 100; - long blockNumber = 150; + ulong finalizedBlockNumber = 100; + ulong blockNumber = 150; _poSSwitcher.TransitionFinished.Returns(false); _baseFinalizedStateProvider.FinalizedBlockNumber.Returns(finalizedBlockNumber); @@ -192,15 +192,15 @@ public void GetFinalizedStateRootAt_ReturnsNull_WhenBlockNumberExceedsFinalizedB // Assert Assert.That(result, Is.Null); - _baseFinalizedStateProvider.DidNotReceive().GetFinalizedStateRootAt(Arg.Any()); + _baseFinalizedStateProvider.DidNotReceive().GetFinalizedStateRootAt(Arg.Any()); } [Test] public void GetFinalizedStateRootAt_DelegatesToBaseProvider_WhenBlockNumberIsFinalized() { // Arrange - long finalizedBlockNumber = 100; - long blockNumber = 50; + ulong finalizedBlockNumber = 100; + ulong blockNumber = 50; Hash256 expectedStateRoot = TestItem.KeccakA; _poSSwitcher.TransitionFinished.Returns(false); _baseFinalizedStateProvider.FinalizedBlockNumber.Returns(finalizedBlockNumber); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeRewardCalculatorTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeRewardCalculatorTests.cs index 791e5c4528be..294f0c5e761b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeRewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergeRewardCalculatorTests.cs @@ -85,7 +85,7 @@ public void No_uncles() [Test] public void Byzantium_reward_two_uncles() { - long blockNumber = MainnetSpecProvider.ByzantiumBlockNumber; + ulong blockNumber = MainnetSpecProvider.ByzantiumBlockNumber; Block uncle = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block uncle2 = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block block = Build.A.Block.WithNumber(blockNumber).WithUncles(uncle, uncle2).WithTotalDifficulty(1L).WithDifficulty(300).TestObject; @@ -110,7 +110,7 @@ public void Byzantium_reward_two_uncles() [Test] public void Constantinople_reward_two_uncles() { - long blockNumber = MainnetSpecProvider.ConstantinopleFixBlockNumber; + ulong blockNumber = MainnetSpecProvider.ConstantinopleFixBlockNumber; Block uncle = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block uncle2 = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block block = Build.A.Block.WithNumber(blockNumber).WithUncles(uncle, uncle2).WithTotalDifficulty(1L).WithDifficulty(300).TestObject; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs index e06205cd5459..7c259d2cf144 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs @@ -197,7 +197,9 @@ public void Switch_when_TTD_is_reached() public void Can_load_parameters_after_the_restart() { using MemDb metadataDb = new(); - int terminalBlock = 4; + // ERROR FIX (line 208): terminalBlock is used in assertions against MergeBlockNumber?.BlockNumber + // which is now ulong. Changed type from int to ulong so terminalBlock + 1 is unambiguously ulong. + ulong terminalBlock = 4; TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = 5000000; Block genesisBlock = Build.A.Block.WithNumber(0).TestObject; @@ -205,6 +207,7 @@ public void Can_load_parameters_after_the_restart() PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, metadataDb, specProvider); Assert.That(poSSwitcher.HasEverReachedTerminalBlock(), Is.EqualTo(false)); + // WithNumber and WithParent still take long; cast terminalBlock at the call site. Block block = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(terminalBlock).WithParent(blockTree.Head!).WithDifficulty(1000000L).TestObject; blockTree.SuggestBlock(block); blockTree.UpdateMainChain(block); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/ProcessedTransactionsDbCleanerTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/ProcessedTransactionsDbCleanerTests.cs index 135fcb0ede3e..22a6865c6c18 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/ProcessedTransactionsDbCleanerTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/ProcessedTransactionsDbCleanerTests.cs @@ -26,14 +26,14 @@ public class ProcessedTransactionsDbCleanerTests private readonly ISpecProvider _specProvider = MainnetSpecProvider.Instance; [Test] - public async Task should_remove_processed_txs_from_db_after_finalization([Values(0, 1, 42, 358)] long blockOfTxs, [Values(1, 42, 358)] long finalizedBlock) + public async Task should_remove_processed_txs_from_db_after_finalization([Values(0UL, 1UL, 42UL, 358UL)] ulong blockOfTxs, [Values(1UL, 42UL, 358UL)] ulong finalizedBlock) { Transaction GetTx(PrivateKey sender) => Build.A.Transaction .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(UInt256.One) .WithMaxPriorityFeePerGas(UInt256.One) - .WithNonce(UInt256.Zero) + .WithNonce(0UL) .SignedAndResolved(new EthereumEcdsa(_specProvider.ChainId), sender).TestObject; IColumnsDb columnsDb = new MemColumnsDb(BlobTxsColumns.ProcessedTxs); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs index 9f0f9358d6ca..b3de7dabc071 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs @@ -128,7 +128,7 @@ public void DecodeGetPayloadBodiesByRangeRequest_roundtrip() BitConverter.TryWriteBytes(request.AsSpan(0, 8), 10UL); BitConverter.TryWriteBytes(request.AsSpan(8, 8), 5UL); - (long start, long count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(Seq(request)); + (ulong start, ulong count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(Seq(request)); Assert.That(start, Is.EqualTo(10)); Assert.That(count, Is.EqualTo(5)); @@ -310,9 +310,9 @@ public void EncodeGetPayloadV1Response_all_static_fields_land_at_spec_defined_of ReceiptsRoot = TestItem.KeccakC, LogsBloom = Bloom.Empty, PrevRandao = TestItem.KeccakD, - BlockNumber = (long)0x0102030405060708UL, - GasLimit = (long)0x1112131415161718UL, - GasUsed = (long)0x2122232425262728UL, + BlockNumber = 0x0102030405060708UL, + GasLimit = 0x1112131415161718UL, + GasUsed = 0x2122232425262728UL, Timestamp = 0x3132333435363738UL, ExtraData = [0xEE, 0xEF], BaseFeePerGas = new UInt256(0xDEADBEEF), @@ -336,11 +336,11 @@ public void EncodeGetPayloadV1Response_all_static_fields_land_at_spec_defined_of Assert.That(buf.Slice(372, 32).ToArray(), Is.EqualTo(ep.PrevRandao!.Bytes.ToArray()), "prev_randao @ offset 372"); - Assert.That(BitConverter.ToUInt64(buf.Slice(404, 8)), Is.EqualTo((ulong)ep.BlockNumber), "block_number @ offset 404"); + Assert.That(BitConverter.ToUInt64(buf.Slice(404, 8)), Is.EqualTo(ep.BlockNumber), "block_number @ offset 404"); - Assert.That(BitConverter.ToUInt64(buf.Slice(412, 8)), Is.EqualTo((ulong)ep.GasLimit), "gas_limit @ offset 412"); + Assert.That(BitConverter.ToUInt64(buf.Slice(412, 8)), Is.EqualTo(ep.GasLimit), "gas_limit @ offset 412"); - Assert.That(BitConverter.ToUInt64(buf.Slice(420, 8)), Is.EqualTo((ulong)ep.GasUsed), "gas_used @ offset 420"); + Assert.That(BitConverter.ToUInt64(buf.Slice(420, 8)), Is.EqualTo(ep.GasUsed), "gas_used @ offset 420"); Assert.That(BitConverter.ToUInt64(buf.Slice(428, 8)), Is.EqualTo(ep.Timestamp), "timestamp @ offset 428"); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMiddlewareTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMiddlewareTests.cs index e9e23fec0d78..12288abbf1f2 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMiddlewareTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMiddlewareTests.cs @@ -290,28 +290,29 @@ public async Task GetPayloadBodiesByHash_routes_to_correct_engine_method(int ver [TestCase(2, "/engine/v2/payloads/bodies/by-range")] public async Task GetPayloadBodiesByRange_routes_to_correct_engine_method_with_correct_args(int version, string path) { - const long expectedStart = 7; - const long expectedCount = 3; + const ulong expectedStart = 7; + const ulong expectedCount = 3; + + ulong v1Start = ulong.MaxValue, v1Count = ulong.MaxValue; + ulong v2Start = ulong.MaxValue, v2Count = ulong.MaxValue; - long v1Start = -1, v1Count = -1; - long v2Start = -1, v2Count = -1; _engineModule - .engine_getPayloadBodiesByRangeV1(Arg.Do(s => v1Start = s), Arg.Do(c => v1Count = c)) + .engine_getPayloadBodiesByRangeV1(Arg.Do(s => v1Start = s), Arg.Do(c => v1Count = c)) .Returns(ResultWrapper>.Success([])); _engineModule - .engine_getPayloadBodiesByRangeV2(Arg.Do(s => v2Start = s), Arg.Do(c => v2Count = c)) + .engine_getPayloadBodiesByRangeV2(Arg.Do(s => v2Start = s), Arg.Do(c => v2Count = c)) .Returns(ResultWrapper>.Success([])); - byte[] body = BuildPayloadBodiesByRangeRequest((ulong)expectedStart, (ulong)expectedCount); + byte[] body = BuildPayloadBodiesByRangeRequest(expectedStart, expectedCount); DefaultHttpContext ctx = MakePostContext(path, body); await _middleware.InvokeAsync(ctx); - await _engineModule.Received(version == 1 ? 1 : 0).engine_getPayloadBodiesByRangeV1(Arg.Any(), Arg.Any()); - await _engineModule.Received(version == 2 ? 1 : 0).engine_getPayloadBodiesByRangeV2(Arg.Any(), Arg.Any()); + await _engineModule.Received(version == 1 ? 1 : 0).engine_getPayloadBodiesByRangeV1(Arg.Any(), Arg.Any()); + await _engineModule.Received(version == 2 ? 1 : 0).engine_getPayloadBodiesByRangeV2(Arg.Any(), Arg.Any()); - long capturedStart = version == 1 ? v1Start : v2Start; - long capturedCount = version == 1 ? v1Count : v2Count; + ulong capturedStart = version == 1 ? v1Start : v2Start; + ulong capturedCount = version == 1 ? v1Count : v2Count; Assert.That(capturedStart, Is.EqualTo(expectedStart)); Assert.That(capturedCount, Is.EqualTo(expectedCount)); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMultiSegmentDecodeTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMultiSegmentDecodeTests.cs index 2d7c44eb64e8..40fdea2713e8 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMultiSegmentDecodeTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszMultiSegmentDecodeTests.cs @@ -109,7 +109,7 @@ public void GetPayloadBodiesByRange_decodes_correctly_across_segments(int segSiz BitConverter.TryWriteBytes(encoded.AsSpan(0, 8), startVal); BitConverter.TryWriteBytes(encoded.AsSpan(8, 8), countVal); - (long start, long count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(Multi(encoded, segSize)); + (ulong start, ulong count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(Multi(encoded, segSize)); Assert.That(start, Is.EqualTo((long)startVal)); Assert.That(count, Is.EqualTo((long)countVal)); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs index eb5d3d3bce43..d8b3c05819f0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs @@ -27,6 +27,7 @@ using Nethermind.Synchronization.Reporting; using NSubstitute; using NUnit.Framework; +using System.Collections.Generic; namespace Nethermind.Merge.Plugin.Test.Synchronization; @@ -178,7 +179,7 @@ public async Task Finishes_when_all_downloaded() { IBlockTree blockTree = Substitute.For(); blockTree.LowestInsertedBeaconHeader.Returns(Build.A.BlockHeader.WithNumber(2000).TestObject); - blockTree.SyncPivot.Returns((1000, Keccak.Zero)); + blockTree.SyncPivot.Returns((1000UL, Keccak.Zero)); ISyncReport report = Substitute.For(); ProgressLogger progressLogger = new("", LimboLogs.Instance); report.BeaconHeaders.Returns(progressLogger); @@ -230,19 +231,19 @@ public void Feed_able_to_sync_when_new_pivot_is_set() Context ctx = new() { BlockTree = blockTree, SyncConfig = syncConfig, BeaconPivot = pivot }; - BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 0, 501); + BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 0UL, 501UL); // move best pointers forward as proxy for chain merge Block highestBlock = syncedBlockTree.FindBlock(700, BlockTreeLookupOptions.None)!; blockTree.Insert(highestBlock, BlockTreeInsertBlockOptions.SaveHeader); pivot.EnsurePivot(syncedBlockTree.FindHeader(900, BlockTreeLookupOptions.None)); - BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 700, 701); + BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 700UL, 701UL); highestBlock = syncedBlockTree.FindBlock(900, BlockTreeLookupOptions.None)!; blockTree.Insert(highestBlock, BlockTreeInsertBlockOptions.SaveHeader); pivot.EnsurePivot(syncedBlockTree.FindHeader(999, BlockTreeLookupOptions.None)); - BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 900, 901); + BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 900UL, 901UL); } [Test] @@ -307,14 +308,14 @@ public async Task Does_not_request_headers_when_destination_advances_past_lowest // PivotDestinationNumber rising above _lowestRequestedHeaderNumber mid-sync must not produce // a batch with negative RequestSize. IBlockTree blockTree = Substitute.For(); - blockTree.SyncPivot.Returns((1000, Keccak.Zero)); + blockTree.SyncPivot.Returns((1000UL, Keccak.Zero)); blockTree.LowestInsertedBeaconHeader.Returns((BlockHeader?)null); IBeaconPivot beaconPivot = Substitute.For(); - beaconPivot.PivotNumber.Returns(2000); + beaconPivot.PivotNumber.Returns(2000UL); beaconPivot.PivotHash.Returns(TestItem.KeccakA); beaconPivot.PivotParentHash.Returns(TestItem.KeccakB); - beaconPivot.PivotDestinationNumber.Returns(1100); + beaconPivot.PivotDestinationNumber.Returns(1100UL); Context ctx = new() { @@ -354,7 +355,7 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n }; int chainLength = 111; - int pivotNumber = 100; + uint pivotNumber = 100; Context ctx = new() { @@ -369,7 +370,7 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n // First batch, should be enough to merge chain HeadersSyncBatch? request = await ctx.Feed.PrepareRequest(); Assert.That(request!, Is.Not.Null); - request!.Response = Enumerable.Range((int)request.StartNumber, request.RequestSize) + request!.Response = ULongRange(request.StartNumber, request.RequestSize) .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) .ToPooledList(request.RequestSize); @@ -385,8 +386,8 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n Assert.That(request, Is.Not.Null); // We respond it again - request!.Response = Enumerable.Range((int)request.StartNumber, request.RequestSize) - .Select((blockNumber) => ctx.RemoteBlockTree.FindHeader(blockNumber)) + request!.Response = ULongRange(request.StartNumber, request.RequestSize) + .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) .ToPooledList(request.RequestSize); ctx.Feed.HandleResponse(request); request.Dispose(); @@ -397,16 +398,19 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n Assert.That(request, Is.Null); } + // ERROR FIX (line 410): bestPointer changed from long to ulong to match BestKnownNumber + // and the ulong arithmetic used throughout this method and BuildHeadersSyncBatches. private async void BuildAndProcessHeaderSyncBatches( Context ctx, BlockTree blockTree, BlockTree syncedBlockTree, IBeaconPivot pivot, - long bestPointer, - long endLowestBeaconHeader) + ulong bestPointer, + ulong endLowestBeaconHeader) { Assert.That(ctx.BeaconSync.ShouldBeInBeaconHeaders(), Is.True); Assert.That(blockTree.BestKnownNumber, Is.EqualTo(bestPointer)); + // FindHeader now takes ulong directly — pass ulong values without casting. BlockHeader? startBestHeader = syncedBlockTree.FindHeader(bestPointer, BlockTreeLookupOptions.None); BlockHeader? pivotHeader = syncedBlockTree.FindHeader(pivot.PivotNumber, BlockTreeLookupOptions.None); Assert.That(blockTree.BestSuggestedHeader?.Hash, Is.EqualTo(startBestHeader?.Hash)); @@ -433,19 +437,21 @@ private async void BuildHeadersSyncBatches( BlockTree blockTree, BlockTree syncedBlockTree, IBeaconPivot pivot, - long endLowestBeaconHeader) + ulong endLowestBeaconHeader) { ctx.Feed.InitializeFeed(); - long lowestHeaderNumber = pivot.PivotNumber; + ulong lowestHeaderNumber = pivot.PivotNumber; while (lowestHeaderNumber > endLowestBeaconHeader) { using HeadersSyncBatch? batch = await ctx.Feed.PrepareRequest(); Assert.That(batch, Is.Not.Null); BuildHeadersSyncBatchResponse(batch, syncedBlockTree); ctx.Feed.HandleResponse(batch); - lowestHeaderNumber = lowestHeaderNumber - batch!.RequestSize < endLowestBeaconHeader + // ERROR FIX (lines 446, 448): Operator '-' is ambiguous between ulong and int. + // batch.RequestSize is int; cast to ulong so the subtraction resolves unambiguously. + lowestHeaderNumber = lowestHeaderNumber - (ulong)batch!.RequestSize < endLowestBeaconHeader ? endLowestBeaconHeader - : lowestHeaderNumber - batch.RequestSize; + : lowestHeaderNumber - (ulong)batch.RequestSize; BlockHeader? lowestHeader = syncedBlockTree.FindHeader(lowestHeaderNumber, BlockTreeLookupOptions.None); Assert.That(blockTree.LowestInsertedBeaconHeader?.Number, Is.EqualTo(lowestHeader?.Number)); @@ -466,10 +472,16 @@ private static void BuildHeadersSyncBatchResponse(HeadersSyncBatch? batch, IBloc batch.Response = new ArrayPoolList(headers.Count, headers); } - private static IBeaconPivot PreparePivot(long blockNumber, ISyncConfig syncConfig, IBlockTree blockTree, BlockHeader? pivotHeader = null) + private static IBeaconPivot PreparePivot(ulong blockNumber, ISyncConfig syncConfig, IBlockTree blockTree, BlockHeader? pivotHeader = null) { IBeaconPivot pivot = new BeaconPivot(syncConfig, new MemDb(), blockTree, AlwaysPoS.Instance, LimboLogs.Instance); pivot.EnsurePivot(pivotHeader ?? Build.A.BlockHeader.WithNumber(blockNumber).TestObject); return pivot; } + + private static IEnumerable ULongRange(ulong start, int count) + { + for (ulong i = start, end = start + (ulong)count; i < end; i++) + yield return i; + } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconPivotTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconPivotTests.cs index 6d382ccf3f25..1a261375494b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconPivotTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconPivotTests.cs @@ -33,7 +33,7 @@ public void Setup() PivotTotalDifficulty = "1000" }; _blockTree = Substitute.For(); - _blockTree.SyncPivot.Returns((1000, Keccak.Zero)); + _blockTree.SyncPivot.Returns((1000UL, Keccak.Zero)); } [Test] diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/StartingSyncPivotUpdaterTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/StartingSyncPivotUpdaterTests.cs index 71d6b6098b4a..7f60922d99fb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/StartingSyncPivotUpdaterTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/StartingSyncPivotUpdaterTests.cs @@ -88,14 +88,14 @@ public void TrySetFreshPivot_saves_FinalizedHash_in_db() SyncModeChangedEventArgs args = new(SyncMode.FastSync, SyncMode.UpdatingPivot); Hash256 expectedFinalizedHash = _externalPeerBlockTree!.HeadHash; - long expectedPivotBlockNumber = _externalPeerBlockTree!.Head!.Number; + ulong expectedPivotBlockNumber = _externalPeerBlockTree!.Head!.Number; _beaconSyncStrategy!.GetFinalizedHash().Returns(expectedFinalizedHash); _syncModeSelector!.Changed += Raise.EventWith(args); byte[] storedData = _metadataDb!.Get(MetadataDbKeys.UpdatedPivotData)!; Rlp.ValueDecoderContext ctx = new(storedData!); - long storedPivotBlockNumber = ctx.DecodeLong(); + ulong storedPivotBlockNumber = ctx.DecodeULong(); Hash256 storedFinalizedHash = ctx.DecodeKeccak()!; Assert.That(storedFinalizedHash, Is.EqualTo(expectedFinalizedHash)); @@ -152,7 +152,7 @@ public void TrySetFreshPivot_for_unsafe_updater_saves_pivot_64_blocks_behind_Hea SyncModeChangedEventArgs args = new(SyncMode.FastSync, SyncMode.UpdatingPivot); Hash256 expectedHeadBlockHash = _externalPeerBlockTree!.HeadHash; - long expectedPivotBlockNumber = _externalPeerBlockTree!.Head!.Number - 64; + ulong expectedPivotBlockNumber = _externalPeerBlockTree!.Head!.Number - 64; Hash256 expectedPivotBlockHash = _externalPeerBlockTree!.FindLevel(expectedPivotBlockNumber)!.BlockInfos[0].BlockHash; _beaconSyncStrategy!.GetHeadBlockHash().Returns(expectedHeadBlockHash); @@ -160,7 +160,7 @@ public void TrySetFreshPivot_for_unsafe_updater_saves_pivot_64_blocks_behind_Hea byte[] storedData = _metadataDb!.Get(MetadataDbKeys.UpdatedPivotData)!; Rlp.ValueDecoderContext ctx = new(storedData!); - long storedPivotBlockNumber = ctx.DecodeLong(); + ulong storedPivotBlockNumber = ctx.DecodeULong(); Hash256 storedPivotBlockHash = ctx.DecodeKeccak()!; Assert.That(storedPivotBlockNumber, Is.EqualTo(expectedPivotBlockNumber)); @@ -170,7 +170,7 @@ public void TrySetFreshPivot_for_unsafe_updater_saves_pivot_64_blocks_behind_Hea [Test] public void TrySetFreshPivot_for_unsafe_updater_ignores_peer_header_with_mismatched_number() { - long requestedPivotNumber = _externalPeerBlockTree!.Head!.Number - 64; + ulong requestedPivotNumber = _externalPeerBlockTree!.Head!.Number - 64; Hash256 wrongNumberHash = _externalPeerBlockTree!.FindLevel(requestedPivotNumber + 5)!.BlockInfos[0].BlockHash; _syncPeer!.GetBlockHeaders(requestedPivotNumber, 1, 0, default) .ReturnsForAnyArgs(_ => _externalPeerBlockTree!.FindHeaders(wrongNumberHash, 1, 0, default)); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/TestingRpcModuleTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/TestingRpcModuleTests.cs index faaae993a4eb..e6254226cc99 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/TestingRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/TestingRpcModuleTests.cs @@ -151,7 +151,7 @@ public async Task Tx_source_behavior(bool useNull, int expectedTxCount) { Transaction mempoolTx = BuildSignedTransactions(1)[0]; ITxSource txSource = Substitute.For(); - txSource.GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + txSource.GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(new[] { mempoolTx }); (TestingRpcModule module, Hash256 parentHash, BlockHeader parentHeader) = CreateBuildTestingModule(txSource: txSource); @@ -164,9 +164,9 @@ public async Task Tx_source_behavior(bool useNull, int expectedTxCount) Assert.That(((GetPayloadV5Result)result.Data!).ExecutionPayload.Transactions.Length, Is.EqualTo(expectedTxCount)); if (useNull) - txSource.Received(1).GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), true); + txSource.Received(1).GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), true); else - txSource.DidNotReceive().GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); + txSource.DidNotReceive().GetTransactions(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); } [Test] @@ -484,10 +484,10 @@ private static Transaction[] BuildSignedTransactions(int count) { Transaction[] transactions = new Transaction[count]; - for (int i = 0; i < count; i++) + for (uint i = 0; i < count; i++) { transactions[i] = Core.Test.Builders.Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce(i) .WithTimestamp((UInt256)(1_000 + i)) .WithTo(Core.Test.Builders.TestItem.AddressC) .WithValue(i + 1) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostPayloadAttributes.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostPayloadAttributes.cs index a4e8e224568d..8bd189a29f58 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostPayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostPayloadAttributes.cs @@ -7,7 +7,7 @@ namespace Nethermind.Merge.Plugin.BlockProduction.Boost; public class BoostPayloadAttributes : PayloadAttributes { - public long? GasLimit { get; set; } + public ulong? GasLimit { get; set; } - public override long? GetGasLimit() => GasLimit; + public override ulong? GetGasLimit() => GasLimit; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs index d5c5acf9153d..4f34ea6dc17a 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs @@ -112,7 +112,7 @@ public string StartPreparingPayload(BlockHeader parentHeader, PayloadAttributes return payloadId; [MethodImpl(MethodImplOptions.NoInlining)] - void LogMultiStartRequest(string payloadId, long number) => _logger.Info($"Payload for block {number} with same parameters has already started. PayloadId: {payloadId}"); + void LogMultiStartRequest(string payloadId, ulong number) => _logger.Info($"Payload for block {number} with same parameters has already started. PayloadId: {payloadId}"); } protected virtual Block ProduceEmptyBlock(string payloadId, BlockHeader parentHeader, PayloadAttributes payloadAttributes) @@ -361,7 +361,7 @@ private void LogProductionResult(Task t, Block currentBestBlock, UInt256 blobs += blobCount; blobTx++; tx.TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas); - gas += (ulong)tx.SpentGas * premiumPerGas; + gas += tx.SpentGas * premiumPerGas; } } _logger.Info($" Produced {blockFees.ToDecimal(null) / weiToEth,6:N4}{BlocksConfig.GasTokenTicker,4} {block.ToString(block.Difficulty != 0 ? Block.Format.HashNumberDiffAndTx : Block.Format.HashNumberMGasAndTx)} | {time.TotalMilliseconds,8:N2} ms {((blobs > 0) ? $"{blobs,2:N0} blobs in {blobTx,2:N0} tx @ {(decimal)gas / weiToGwei,7:N0} gwei" : "")}"); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs index 0a0a19d53ba1..ba0dc09c5bef 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs @@ -30,15 +30,15 @@ public class ExecutionPayload : IForkValidator, IExecutionPayloadParams, IExecut public Hash256 BlockHash { get; set; } = Keccak.Zero; - public long BlockNumber { get; set; } + public ulong BlockNumber { get; set; } public byte[] ExtraData { get; set; } = []; public Address FeeRecipient { get; set; } = Address.Zero; - public long GasLimit { get; set; } + public ulong GasLimit { get; set; } - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public Bloom LogsBloom { get; set; } = Bloom.Empty; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/ForkchoiceStateV1.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/ForkchoiceStateV1.cs index 1eb47a3018ff..9d0a0caac8ef 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/ForkchoiceStateV1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/ForkchoiceStateV1.cs @@ -30,7 +30,7 @@ public class ForkchoiceStateV1(Hash256 headBlockHash, Hash256 finalizedBlockHash public Hash256 FinalizedBlockHash { get; set; } = finalizedBlockHash; public override string ToString() => $"ForkChoice: {HeadBlockHash}, Safe: {SafeBlockHash}, Finalized: {FinalizedBlockHash}"; - public string ToString(long? headNumber, long? safeNumber, long? finalizedNumber) => + public string ToString(ulong? headNumber, ulong? safeNumber, ulong? finalizedNumber) => headNumber is null || safeNumber is null || finalizedNumber is null ? ToString() : $"ForkChoice: {headNumber} ({HeadBlockHash.ToShortString()}), Safe: {safeNumber} ({SafeBlockHash.ToShortString()}), Finalized: {finalizedNumber} ({FinalizedBlockHash.ToShortString()})"; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/GetPayloadDirectResponseWriter.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/GetPayloadDirectResponseWriter.cs index 03d7a132f192..2d42db3f24e1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/GetPayloadDirectResponseWriter.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/GetPayloadDirectResponseWriter.cs @@ -255,8 +255,8 @@ private static void WriteNullableUlongHexString(IBufferWriter writer, ulon HexWriter.WriteUlongHexString(writer, value.GetValueOrDefault()); } - private static void WriteLongHexString(IBufferWriter writer, long value) => - HexWriter.WriteUlongHexString(writer, (ulong)value); + private static void WriteLongHexString(IBufferWriter writer, ulong value) => + HexWriter.WriteUlongHexString(writer, value); private static void WriteHexString(IBufferWriter writer, ReadOnlySpan data, bool chunked) => HexWriter.WriteHexString(writer, data, chunked); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/TransitionConfigurationV1.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/TransitionConfigurationV1.cs index 78e526d27466..f5e556b28de3 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/TransitionConfigurationV1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/TransitionConfigurationV1.cs @@ -26,5 +26,5 @@ public class TransitionConfigurationV1 /// /// Maps on TERMINAL_BLOCK_NUMBER parameter of EIP-3675 /// - public long TerminalBlockNumber { get; set; } + public ulong TerminalBlockNumber { get; set; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs index f88284f27687..077efcd255f4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs @@ -30,6 +30,6 @@ public Task> engine_forkchoiceUpdatedV4 public Task>> engine_getPayloadBodiesByHashV2(IReadOnlyList blockHashes) => _executionGetPayloadBodiesByHashV2Handler.Handle(blockHashes); - public Task>> engine_getPayloadBodiesByRangeV2(long start, long count) + public Task>> engine_getPayloadBodiesByRangeV2(ulong start, ulong count) => _executionGetPayloadBodiesByRangeV2Handler.Handle(start, count); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Shanghai.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Shanghai.cs index 21d1f6f014c0..f9f9d5732387 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Shanghai.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Shanghai.cs @@ -27,7 +27,7 @@ public Task> engine_forkchoiceUpdatedV2 public ResultWrapper> engine_getPayloadBodiesByHashV1(IReadOnlyList blockHashes) => _executionGetPayloadBodiesByHashV1Handler.Handle(blockHashes); - public Task>> engine_getPayloadBodiesByRangeV1(long start, long count) + public Task>> engine_getPayloadBodiesByRangeV1(ulong start, ulong count) => _executionGetPayloadBodiesByRangeV1Handler.Handle(start, count); public Task> engine_newPayloadV2(ExecutionPayload executionPayload) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ExchangeTransitionConfigurationV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ExchangeTransitionConfigurationV1Handler.cs index 1b47589e7280..31450baf61cb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ExchangeTransitionConfigurationV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ExchangeTransitionConfigurationV1Handler.cs @@ -24,7 +24,7 @@ public class ExchangeTransitionConfigurationV1Handler( public ResultWrapper Handle(TransitionConfigurationV1 beaconTransitionConfiguration) { UInt256 terminalTotalDifficulty = _poSSwitcher.TerminalTotalDifficulty ?? _ttdPlaceholderForCl; - long configuredTerminalBlockNumber = _poSSwitcher.ConfiguredTerminalBlockNumber ?? 0; + ulong configuredTerminalBlockNumber = _poSSwitcher.ConfiguredTerminalBlockNumber ?? 0; Hash256 configuredTerminalBlockHash = _poSSwitcher.ConfiguredTerminalBlockHash ?? Keccak.Zero; if (terminalTotalDifficulty == _ttdPlaceholderForCl) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs index e03e814515ad..befc2127d707 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs @@ -92,7 +92,7 @@ protected virtual bool IsOnMainChainBehindFinalized(BlockHeader newHeadHeader, F // L1-derived finality models override this to relax the bounds check while keeping // ancestry validation. protected virtual ResultWrapper? RejectIfInconsistent( - BlockHeader? header, long lowerBound, string label, BlockHeader newHeadHeader, string requestStr) + BlockHeader? header, ulong lowerBound, string label, BlockHeader newHeadHeader, string requestStr) { if ((header is not null && (header.Number < lowerBound || header.Number > newHeadHeader.Number)) || IsInconsistent(header, newHeadHeader)) @@ -241,7 +241,7 @@ protected virtual bool IsOnMainChainBehindFinalized(BlockHeader newHeadHeader, F // Spec ordering within a single FCU: finalized <= safe <= head. Ancestry must be // re-validated on every FCU - the binding is (head, finalized, safe), so a repeated // finalized/safe hash paired with a new head on a sibling branch is still a spec violation. - long finalizedNumber = finalizedHeader?.Number ?? 0; + ulong finalizedNumber = finalizedHeader?.Number ?? 0; if (RejectIfInconsistent(finalizedHeader, 0, "finalized", newHeadHeader, requestStr) is { } finalizedError) return finalizedError; if (RejectIfInconsistent(safeBlockHeader, finalizedNumber, "safe", newHeadHeader, requestStr) is { } safeError) return safeError; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs index edae1b6ec028..c73c983f9d32 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs @@ -19,7 +19,7 @@ public abstract class GetPayloadBodiesByRangeHandler(IBlockTree blockTr private readonly ILogger _logger = logManager.GetClassLogger(typeof(GetPayloadBodiesByRangeHandler<>)); - public Task>> Handle(long start, long count) + public Task>> Handle(ulong start, ulong count) { if (start < 1 || count < 1) { @@ -42,14 +42,14 @@ public abstract class GetPayloadBodiesByRangeHandler(IBlockTree blockTr protected virtual IReadOnlyList CreateResponse(TResult?[] results) => results; - private TResult?[] GetRequests(long start, long count) + private TResult?[] GetRequests(ulong start, ulong count) { - long headNumber = blockTree.Head?.Number ?? 0; - long end = Math.Min(start + count - 1, headNumber); + ulong headNumber = blockTree.Head?.Number ?? 0; + ulong end = Math.Min(start + count - 1, headNumber); if (end < start) return []; TResult?[] results = new TResult?[end - start + 1]; - for (long i = start; i <= end; i++) + for (ulong i = start; i <= end; i++) { Block? block = blockTree.FindBlock(i); results[i - start] = block is null ? null : CreateResult(block); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV2Handler.cs index 0a0185547ba3..db6b0da40692 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV2Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV2Handler.cs @@ -21,7 +21,7 @@ public class GetPayloadBodiesByRangeV2Handler(IBlockTree blockTree, ILogManager private readonly ILogger _logger = logManager.GetClassLogger(typeof(GetPayloadBodiesByRangeV2Handler)); - public Task>> Handle(long start, long count) + public Task>> Handle(ulong start, ulong count) { if (start < 1 || count < 1) { @@ -40,16 +40,16 @@ public class GetPayloadBodiesByRangeV2Handler(IBlockTree blockTree, ILogManager return ResultWrapper>.Success(GetRequests(start, count)); } - private PayloadBodiesV2DirectResponse GetRequests(long start, long count) + private PayloadBodiesV2DirectResponse GetRequests(ulong start, ulong count) { - long headNumber = blockTree.Head?.Number ?? 0; - long end = Math.Min(start + count - 1, headNumber); + ulong headNumber = blockTree.Head?.Number ?? 0; + ulong end = Math.Min(start + count - 1, headNumber); if (end < start) return new PayloadBodiesV2DirectResponse([]); PayloadBodiesV2DirectResponse.PayloadBody?[] results = new PayloadBodiesV2DirectResponse.PayloadBody?[end - start + 1]; try { - for (long i = start; i <= end; i++) + for (ulong i = start; i <= end; i++) { Block? block = blockTree.FindBlock(i); if (block is null) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV1Handler.cs index 3c4a50d57d4a..4db9def75735 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV1Handler.cs @@ -10,5 +10,5 @@ namespace Nethermind.Merge.Plugin.Handlers; public interface IGetPayloadBodiesByRangeV1Handler { - Task>> Handle(long start, long count); + Task>> Handle(ulong start, ulong count); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV2Handler.cs index a409a8ab861f..d35529719065 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV2Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IGetPayloadBodiesByRangeV2Handler.cs @@ -10,5 +10,5 @@ namespace Nethermind.Merge.Plugin.Handlers; public interface IGetPayloadBodiesByRangeV2Handler { - Task>> Handle(long start, long count); + Task>> Handle(ulong start, ulong count); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/MergeSealer.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/MergeSealer.cs index c7333fe14fd2..0eef7f01a877 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/MergeSealer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/MergeSealer.cs @@ -26,7 +26,7 @@ public Task SealBlock(Block block, CancellationToken cancellationToken) return _preMergeSealer.SealBlock(block, cancellationToken); } - public bool CanSeal(long blockNumber, Hash256 parentHash) + public bool CanSeal(ulong blockNumber, Hash256 parentHash) { if (_poSSwitcher.HasEverReachedTerminalBlock()) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs index a0cb98e45027..c2b9bef68466 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs @@ -56,8 +56,8 @@ public sealed class NewPayloadHandler : IAsyncHandler _blockValidationTasks = new(); - private long _lastBlockNumber; - private long _lastBlockGasLimit; + private ulong _lastBlockNumber; + private ulong _lastBlockGasLimit; private readonly bool _simulateBlockProduction; public NewPayloadHandler( @@ -96,10 +96,10 @@ public NewPayloadHandler( _processingQueue.BlockRemoved += GetProcessingQueueOnBlockRemoved; } - private string GetGasChange(long blockGasLimit) => (blockGasLimit - _lastBlockGasLimit) switch + private string GetGasChange(ulong blockGasLimit) => (blockGasLimit - _lastBlockGasLimit) switch { > 0 => "👆", - < 0 => "👇", + // < 0 => "👇", _ => " " }; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Amsterdam.cs b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Amsterdam.cs index 2350a86ef76a..abf5bbc42811 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Amsterdam.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Amsterdam.cs @@ -41,5 +41,5 @@ public partial interface IEngineRpcModule : IRpcModule Description = "Returns an array of execution payload bodies for the provided number range", IsSharable = true, IsImplemented = true)] - Task>> engine_getPayloadBodiesByRangeV2(long start, long count); + Task>> engine_getPayloadBodiesByRangeV2(ulong start, ulong count); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Shanghai.cs b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Shanghai.cs index 49e44deebde4..623e0e3d0502 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Shanghai.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.Shanghai.cs @@ -35,7 +35,7 @@ public partial interface IEngineRpcModule : IRpcModule Description = "Returns an array of execution payload bodies for the provided number range", IsSharable = true, IsImplemented = true)] - Task>> engine_getPayloadBodiesByRangeV1(long start, long count); + Task>> engine_getPayloadBodiesByRangeV1(ulong start, ulong count); [JsonRpcMethod( Description = "Verifies the payload according to the execution environment rules and returns the verification status and hash of the last valid block.", diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs b/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs index 3c4f0f9287f1..7f1d62f47133 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs @@ -30,7 +30,7 @@ public interface IMergeConfig : IConfig public string? TerminalBlockHash { get; set; } [ConfigItem(Description = "The terminal PoW block number used for the transition.")] - public long? TerminalBlockNumber { get; set; } + public ulong? TerminalBlockNumber { get; set; } [ConfigItem(Description = "Deprecated since v1.14.7. Use `Blocks.SecondsPerSlot` instead.", DefaultValue = "12", HiddenFromDocs = true)] public ulong SecondsPerSlot { get; set; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergeBetterPeerStrategy.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergeBetterPeerStrategy.cs index 771174f9bd8c..aa29595ee3a6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergeBetterPeerStrategy.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergeBetterPeerStrategy.cs @@ -20,12 +20,12 @@ public class MergeBetterPeerStrategy( private readonly IBeaconPivot _beaconPivot = beaconPivot; private readonly ILogger _logger = logManager.GetClassLogger(); - public int Compare(in (UInt256? TotalDifficulty, long Number) valueX, in (UInt256? TotalDifficulty, long Number) valueY) => + public int Compare(in (UInt256? TotalDifficulty, ulong Number) valueX, in (UInt256? TotalDifficulty, ulong Number) valueY) => ShouldApplyPreMergeLogic(valueX.TotalDifficulty, valueY.TotalDifficulty) ? _preMergeBetterPeerStrategy.Compare(valueX, valueY) : valueX.Number.CompareTo(valueY.Number); - public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestBlock) + public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestBlock) { if (_logger.IsTrace) _logger.Trace($"IsBetterThanLocalChain BestPeerInfo.TD: {bestPeerInfo.TotalDifficulty}, BestPeerInfo.Number: {bestPeerInfo.Number}, LocalChainDifficulty {bestBlock.TotalDifficulty} LocalChainBestFullBlock: {bestBlock.Number} TerminalTotalDifficulty {_poSSwitcher.TerminalTotalDifficulty}"); return ShouldApplyPreMergeLogic(bestPeerInfo.TotalDifficulty, bestBlock.TotalDifficulty) @@ -33,7 +33,7 @@ public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, long Number) be : bestPeerInfo.Number > bestBlock.Number; } - public bool IsDesiredPeer(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestHeader) + public bool IsDesiredPeer(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestHeader) { if (_logger.IsTrace) _logger.Trace( $"IsDesiredPeer: " + diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs index e5e510b313c2..806a465e3b2e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs @@ -16,7 +16,7 @@ public class MergeConfig : IMergeConfig public string? TerminalBlockHash { get; set; } - public long? TerminalBlockNumber { get; set; } + public ulong? TerminalBlockNumber { get; set; } [Obsolete("Use BlocksConfig.SecondsPerSlot")] public ulong SecondsPerSlot { get; set; } = 12; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizationManager.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizationManager.cs index b1ea700057f6..93eddf212e6e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizationManager.cs @@ -40,7 +40,7 @@ public MergeFinalizationManager(IManualBlockFinalizationManager manualBlockFinal public Hash256 LastFinalizedHash { get => _manualBlockFinalizationManager.LastFinalizedHash; } - public virtual long LastFinalizedBlockLevel + public virtual ulong LastFinalizedBlockLevel { get { @@ -49,7 +49,7 @@ public virtual long LastFinalizedBlockLevel return _manualBlockFinalizationManager.LastFinalizedBlockLevel; } - return 0; + return 0UL; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizedStateProvider.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizedStateProvider.cs index f2484cc65761..9d4e28b5006c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizedStateProvider.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergeFinalizedStateProvider.cs @@ -12,7 +12,7 @@ namespace Nethermind.Merge.Plugin; public class MergeFinalizedStateProvider(IPoSSwitcher poSSwitcher, IBlockCacheService blockCacheService, IBlockTree blockTree, IFinalizedStateProvider baseFinalizedStateProvider) : IFinalizedStateProvider { - public long FinalizedBlockNumber + public ulong FinalizedBlockNumber { get { @@ -45,7 +45,7 @@ public long FinalizedBlockNumber } } - public Hash256? GetFinalizedStateRootAt(long blockNumber) + public Hash256? GetFinalizedStateRootAt(ulong blockNumber) { if (FinalizedBlockNumber < blockNumber) return null; return baseFinalizedStateProvider.GetFinalizedStateRootAt(blockNumber); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs b/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs index 1c5c4c2c7bb0..0dd3d0e1dfea 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs @@ -45,8 +45,8 @@ public class PoSSwitcher : IPoSSwitcher private readonly ILogger _logger; private Hash256? _terminalBlockHash; - private long? _terminalBlockNumber; - private long? _firstPoSBlockNumber; + private ulong? _terminalBlockNumber; + private ulong? _firstPoSBlockNumber; private bool _hasEverReachedTerminalDifficulty; private Hash256 _finalizedBlockHash = Keccak.Zero; private bool _terminalBlockExplicitSpecified; @@ -222,7 +222,7 @@ public bool IsPostMerge(BlockHeader header) => public Hash256 ConfiguredTerminalBlockHash => _mergeConfig.TerminalBlockHashParsed; - public long? ConfiguredTerminalBlockNumber => _mergeConfig.TerminalBlockNumber; + public ulong? ConfiguredTerminalBlockNumber => _mergeConfig.TerminalBlockNumber; private void LoadTerminalBlock() { @@ -240,7 +240,7 @@ private void LoadTerminalBlock() _firstPoSBlockNumber = _terminalBlockNumber + 1; } - private long? LoadTerminalBlockNumberFromDb() + private ulong? LoadTerminalBlockNumberFromDb() { try { @@ -248,7 +248,7 @@ private void LoadTerminalBlock() { byte[]? hashFromDb = _metadataDb.Get(MetadataDbKeys.TerminalPoWNumber); Rlp.ValueDecoderContext ctx = hashFromDb.AsRlpValueContext(); - return ctx.DecodeLong(); + return ctx.DecodeULong(); } } catch (RlpException) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs b/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs index ea4a4e673809..acd5d6088bc9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs @@ -16,7 +16,7 @@ public class ProcessedTransactionsDbCleaner : IDisposable private readonly IBlockFinalizationManager _finalizationManager; private readonly IDb _processedTxsDb; private readonly ILogger _logger; - private long _lastFinalizedBlock = 0; + private ulong _lastFinalizedBlock = 0; public Task CleaningTask { get; private set; } = Task.CompletedTask; public ProcessedTransactionsDbCleaner(IBlockFinalizationManager finalizationManager, IDb processedTxsDb, ILogManager logManager) @@ -36,7 +36,7 @@ private void OnBlocksFinalized(object? sender, FinalizeEventArgs e) } } - private void CleanProcessedTransactionsDb(long newlyFinalizedBlockNumber) + private void CleanProcessedTransactionsDb(ulong newlyFinalizedBlockNumber) { try { @@ -44,7 +44,7 @@ private void CleanProcessedTransactionsDb(long newlyFinalizedBlockNumber) { foreach (byte[] key in _processedTxsDb.GetAllKeys()) { - long blockNumber = key.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + ulong blockNumber = key.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); if (newlyFinalizedBlockNumber >= blockNumber) { if (_logger.IsTrace) _logger.Trace($"Cleaning processed blob txs from block {blockNumber}"); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/GetPayloadBodiesByRangeSszHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/GetPayloadBodiesByRangeSszHandler.cs index ab41a753ee2f..1d9921ffb537 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/GetPayloadBodiesByRangeSszHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/GetPayloadBodiesByRangeSszHandler.cs @@ -28,7 +28,7 @@ public sealed class GetPayloadBodiesByRangeSszHandler(IEngine public override async Task HandleAsync(HttpContext ctx, int v, ReadOnlyMemory extra, ReadOnlySequence body) { - (long start, long count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(body); + (ulong start, ulong count) = SszCodec.DecodeGetPayloadBodiesByRangeRequest(body); if (count > MaxPayloadBodiesRequest) { await WriteErrorAsync(ctx, StatusCodes.Status400BadRequest, diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/SszVersionDescriptors.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/SszVersionDescriptors.cs index 7ff1ac99cdb7..0f46156cadbc 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/SszVersionDescriptors.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/SszVersionDescriptors.cs @@ -204,14 +204,14 @@ public static int Encode(IReadOnlyList bodies, IB public interface IPayloadBodiesByRangeVersion where TResult : class { static abstract int VersionNumber { get; } - static abstract Task>> Call(IEngineRpcModule engine, long start, long count); + static abstract Task>> Call(IEngineRpcModule engine, ulong start, ulong count); static abstract int Encode(IReadOnlyList bodies, IBufferWriter writer); } public readonly struct PayloadBodiesByRangeDescriptorV1 : IPayloadBodiesByRangeVersion { public static int VersionNumber => EngineApiVersions.PayloadBodiesByRange.V1; - public static Task>> Call(IEngineRpcModule engine, long start, long count) + public static Task>> Call(IEngineRpcModule engine, ulong start, ulong count) => engine.engine_getPayloadBodiesByRangeV1(start, count); public static int Encode(IReadOnlyList bodies, IBufferWriter writer) => SszCodec.EncodePayloadBodiesV1Response(bodies, writer); @@ -220,7 +220,7 @@ public static int Encode(IReadOnlyList bodies, IB public readonly struct PayloadBodiesByRangeDescriptorV2 : IPayloadBodiesByRangeVersion { public static int VersionNumber => EngineApiVersions.PayloadBodiesByRange.V2; - public static Task>> Call(IEngineRpcModule engine, long start, long count) + public static Task>> Call(IEngineRpcModule engine, ulong start, ulong count) => engine.engine_getPayloadBodiesByRangeV2(start, count); public static int Encode(IReadOnlyList bodies, IBufferWriter writer) => SszCodec.EncodePayloadBodiesV2Response(bodies, writer); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs index c1f6e3c2c07d..ed2f8373f9ce 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs @@ -164,10 +164,23 @@ public static Hash256[] DecodeGetPayloadBodiesByHashRequest(ReadOnlySequence buf) + /// + /// Decodes an SSZ-encoded GetPayloadBodiesByRange request and returns the + /// start block number and count as ulong values. + /// + /// + /// Previously returned (long start, long count) and went through + /// SszNumericChecks.CheckedLong to guard against overflow when narrowing + /// uint64 wire values to long. Now that BlockHeader.Number + /// (and the engine-API handler signatures) are ulong, no narrowing is + /// required: the wire values are used directly. SszNumericChecks.CheckedLong + /// has no remaining callers and should be deleted. + /// + public static (ulong start, ulong count) DecodeGetPayloadBodiesByRangeRequest(ReadOnlySequence buf) { GetPayloadBodiesByRangeRequestWire.Decode(buf, out GetPayloadBodiesByRangeRequestWire wire); - return (SszNumericChecks.CheckedLong(wire.Start), SszNumericChecks.CheckedLong(wire.Count)); + // wire.Start and wire.Count are SSZ uint64 fields — already ulong, no cast needed. + return (wire.Start, wire.Count); } public static int EncodePayloadBodiesV1Response(IReadOnlyList bodies, IBufferWriter writer) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs index 8152a8debf73..36ace6555693 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs @@ -79,19 +79,19 @@ public Hash256 PrevRandao public ulong BlockNumber { - get => (ulong)Inner.BlockNumber; + get => Inner.BlockNumber; set => Inner.BlockNumber = SszNumericChecks.CheckedLong(value); } public ulong GasLimit { - get => (ulong)Inner.GasLimit; + get => Inner.GasLimit; set => Inner.GasLimit = SszNumericChecks.CheckedLong(value); } public ulong GasUsed { - get => (ulong)Inner.GasUsed; + get => Inner.GasUsed; set => Inner.GasUsed = SszNumericChecks.CheckedLong(value); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs index 17b2cdef07b6..c41a0c2ee4d4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs @@ -15,12 +15,12 @@ internal static class SszNumericChecks /// when the value exceeds . ///
[MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long CheckedLong(ulong value) + public static ulong CheckedLong(ulong value) { if (value > long.MaxValue) ThrowLongOutOfRange(value); - return (long)value; + return value; [DoesNotReturn, StackTraceHidden] static void ThrowLongOutOfRange(ulong value) => diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs index 625ff6686bca..31f3ed0ea86e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs @@ -44,9 +44,9 @@ public sealed class BeaconHeadersSyncFeed( private readonly ILogger _logger = logManager.GetClassLogger(); private bool _chainMerged; - protected override long HeadersDestinationNumber => _pivot.PivotDestinationNumber; + protected override ulong HeadersDestinationNumber => _pivot.PivotDestinationNumber; - protected override bool AllHeadersDownloaded => (_blockTree.LowestInsertedBeaconHeader?.Number ?? long.MaxValue) <= + protected override bool AllHeadersDownloaded => (_blockTree.LowestInsertedBeaconHeader?.Number ?? ulong.MaxValue) <= _pivot.PivotDestinationNumber || _chainMerged; protected override BlockHeader? LowestInsertedBlockHeader @@ -59,7 +59,7 @@ protected override BlockHeader? LowestInsertedBlockHeader } } - protected override long TotalBlocks => _pivotNumber - HeadersDestinationNumber + 1; + protected override ulong TotalBlocks => _pivotNumber - HeadersDestinationNumber + 1; protected override ProgressLogger HeadersSyncProgressLoggerReport => _syncReport.BeaconHeaders; public override string FeedName => nameof(BeaconHeadersSyncFeed); @@ -71,7 +71,7 @@ protected override BlockHeader? LowestInsertedBlockHeader public override AllocationContexts Contexts => AllocationContexts.Headers; - private long ExpectedPivotNumber => + private ulong ExpectedPivotNumber => _pivot.PivotParentHash is not null ? _pivot.PivotNumber - 1 : _pivot.PivotNumber; private Hash256 ExpectedPivotHash => _pivot.PivotParentHash ?? _pivot.PivotHash ?? Keccak.Zero; @@ -84,7 +84,7 @@ protected override void ResetPivot() _pivotNumber = ExpectedPivotNumber; _expectedNextHeader = new NextHeader(ExpectedPivotHash, _poSSwitcher.FinalTotalDifficulty); - long startNumber = _pivotNumber; + ulong startNumber = _pivotNumber; // In case we already have beacon sync happened before BlockHeader? lowestInserted = LowestInsertedBlockHeader; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index f9e855645baa..034a9bc41fc5 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs @@ -58,7 +58,7 @@ public BeaconPivot( LoadBeaconPivot(); } - public long PivotNumber => CurrentBeaconPivot?.Number ?? _blockTree.SyncPivot.BlockNumber; + public ulong PivotNumber => CurrentBeaconPivot?.Number ?? _blockTree.SyncPivot.BlockNumber; public Hash256? PivotHash => CurrentBeaconPivot?.Hash ?? _blockTree.SyncPivot.BlockHash; @@ -70,14 +70,14 @@ public BeaconPivot( public Hash256? PivotParentHash => CurrentBeaconPivot?.ParentHash ?? _blockTree.SyncPivot.BlockHash; // The stopping point (inclusive) for the reverse beacon header sync. - public long PivotDestinationNumber + public ulong PivotDestinationNumber { get { if (CurrentBeaconPivot is null) { // Need to rethink if this is expected. Maybe it need to forward sync without a pivot. - return 0; + return 0UL; } // If head is not null, that means we processed some block before. @@ -85,8 +85,8 @@ public long PivotDestinationNumber if (_blockTree.Head is not null && _blockTree.Head?.Number != 0) { // However, the head may not be canon, so the destination need to be before that. - long safeNumber = _blockTree.Head!.Number - Reorganization.MaxDepth + 1; - return Math.Max(1, safeNumber); + ulong safeNumber = _blockTree.Head!.Number - Reorganization.MaxDepth + 1; + return (ulong)Math.Max(1, safeNumber); } return _blockTree.SyncPivot.BlockNumber + 1; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconSync.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconSync.cs index e3957e4e8f3a..09ee2a7756c6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconSync.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconSync.cs @@ -107,7 +107,7 @@ lowestInsertedBeaconHeader is not null && public bool MergeTransitionFinished => _poSSwitcher.TransitionFinished; - public long? GetTargetBlockHeight() + public ulong? GetTargetBlockHeight() { if (_beaconPivot.BeaconPivotExists()) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs index 6099f793511d..85b4ef8113ec 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs @@ -28,7 +28,7 @@ public class ChainLevelHelper( private readonly ILogger _logger = logManager.GetClassLogger(); private readonly IBeaconPivot _beaconPivot = beaconPivot; - private void OnMissingBeaconHeader(long blockNumber) + private void OnMissingBeaconHeader(ulong blockNumber) { if (_beaconPivot.ProcessDestination?.Number > blockNumber) { @@ -37,8 +37,8 @@ private void OnMissingBeaconHeader(long blockNumber) // A gap is expected when forward sync hasn't reached `blockNumber` yet (best beacon header // still below it) or when backward beacon sync hasn't reached it yet (lowest beacon header // still above it). Trigger a new beacon sync to close the gap. - bool aboveBeaconCoverage = (_blockTree.BestSuggestedBeaconHeader?.Number ?? -1) < blockNumber; - bool belowBeaconCoverage = (_blockTree.LowestInsertedBeaconHeader?.Number ?? long.MaxValue) > blockNumber; + bool aboveBeaconCoverage = (_blockTree.BestSuggestedBeaconHeader?.Number ?? ulong.MinValue) < blockNumber; + bool belowBeaconCoverage = (_blockTree.LowestInsertedBeaconHeader?.Number ?? ulong.MaxValue) > blockNumber; bool expectedDuringSync = aboveBeaconCoverage || belowBeaconCoverage; if (!expectedDuringSync) @@ -56,7 +56,7 @@ private void OnMissingBeaconHeader(long blockNumber) public BlockHeader[]? GetNextHeaders(int maxCount, long maxHeaderNumber, int skipLastBlockCount = 0) { - (long? startingPoint, Hash256? startingPointBlockHash) = GetStartingPoint(); + (ulong? startingPoint, Hash256? startingPointBlockHash) = GetStartingPoint(); if (startingPoint is null) { if (_logger.IsTrace) @@ -162,9 +162,9 @@ private void OnMissingBeaconHeader(long blockNumber) /// block that was processed where we should continue processing. ///
/// - private (long?, Hash256?) GetStartingPoint() + private (ulong?, Hash256?) GetStartingPoint() { - long startingPoint = Math.Min(_blockTree.BestKnownNumber + 1, _beaconPivot.ProcessDestination?.Number ?? long.MaxValue); + ulong startingPoint = Math.Min(_blockTree.BestKnownNumber + 1, _beaconPivot.ProcessDestination?.Number ?? long.MaxValue); bool shouldContinue; if (_logger.IsTrace) _logger.Trace($"ChainLevelHelper. starting point's starting point is {startingPoint}. Best known number: {_blockTree.BestKnownNumber}, Process destination: {_beaconPivot.ProcessDestination?.Number}"); @@ -218,7 +218,7 @@ private void OnMissingBeaconHeader(long blockNumber) return (startingPoint, parentBlockInfo.BlockHash); } - private BlockInfo? GetBeaconMainChainBlockInfo(long startingPoint) + private BlockInfo? GetBeaconMainChainBlockInfo(ulong startingPoint) { ChainLevelInfo? startingLevel = _blockTree.FindLevel(startingPoint); BlockInfo? beaconMainChainBlock = startingLevel?.BeaconMainChainBlock; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PostMergeBlocksSyncPeerAllocationStrategy.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PostMergeBlocksSyncPeerAllocationStrategy.cs index fd316d932392..8e51e97d1049 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PostMergeBlocksSyncPeerAllocationStrategy.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PostMergeBlocksSyncPeerAllocationStrategy.cs @@ -10,9 +10,9 @@ namespace Nethermind.Merge.Plugin.Synchronization; -public class PostMergeBlocksSyncPeerAllocationStrategy(long? minBlocksAhead, IBeaconPivot beaconPivot) : IPeerAllocationStrategy +public class PostMergeBlocksSyncPeerAllocationStrategy(ulong? minBlocksAhead, IBeaconPivot beaconPivot) : IPeerAllocationStrategy { - private readonly long? _minBlocksAhead = minBlocksAhead; + private readonly ulong? _minBlocksAhead = minBlocksAhead; private readonly IBeaconPivot _beaconPivot = beaconPivot; private const decimal MinDiffPercentageForSpeedSwitch = 0.10m; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs index ffe191da5a3c..fa75fb42b8b9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs @@ -119,7 +119,7 @@ private async void OnSyncModeChanged(object? sender, SyncModeChangedEventArgs sy private async Task TrySetFreshPivot(CancellationToken cancellationToken) { - (Hash256 Hash, long Number)? potentialPivotData = await TryGetPivotData(cancellationToken); + (Hash256 Hash, ulong Number)? potentialPivotData = await TryGetPivotData(cancellationToken); if (potentialPivotData is null) { @@ -130,7 +130,7 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) return TryOverwritePivot(potentialPivotData.Value.Hash, potentialPivotData.Value.Number); } - protected virtual async Task<(Hash256 Hash, long Number)?> TryGetPivotData(CancellationToken cancellationToken) + protected virtual async Task<(Hash256 Hash, ulong Number)?> TryGetPivotData(CancellationToken cancellationToken) { // getting finalized block hash as it is safe, because can't be reorganized Hash256? finalizedBlockHash = _beaconSyncStrategy.GetFinalizedHash(); @@ -139,17 +139,17 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) { UpdateAndPrintPotentialNewPivot(finalizedBlockHash); - long? finalizedBlockNumber = TryGetBlockNumberFromBlockCache(finalizedBlockHash) + ulong? finalizedBlockNumber = TryGetBlockNumberFromBlockCache(finalizedBlockHash) ?? TryGetFinalizedBlockNumberFromBlockTree(finalizedBlockHash) ?? await TryGetFromPeers(finalizedBlockHash, cancellationToken); - return finalizedBlockNumber is null ? null : (finalizedBlockHash, (long)finalizedBlockNumber); + return finalizedBlockNumber is null ? null : (finalizedBlockHash, finalizedBlockNumber.Value); } return null; } - protected long? TryGetBlockNumberFromBlockCache(Hash256 finalizedBlockHash, string type = Pivot) + protected ulong? TryGetBlockNumberFromBlockCache(Hash256 finalizedBlockHash, string type = Pivot) { if (_logger.IsDebug) _logger.Debug($"Looking for {type} block in block cache"); if (_blockCacheService.BlockCache.TryGetValue(finalizedBlockHash, out Block? finalizedBlock)) @@ -165,7 +165,7 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) return null; } - private long? TryGetFinalizedBlockNumberFromBlockTree(Hash256 finalizedBlockHash) + private ulong? TryGetFinalizedBlockNumberFromBlockTree(Hash256 finalizedBlockHash) { if (_logger.IsDebug) _logger.Debug("Looking for header of pivot block in blockTree"); BlockHeader? finalizedHeader = _blockTree.FindHeader(finalizedBlockHash, BlockTreeLookupOptions.DoNotCreateLevelIfMissing); @@ -182,13 +182,15 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) return null; } - protected async Task TryGetFromPeers(Hash256? hash, CancellationToken cancellationToken, string type = Pivot) => + protected async Task TryGetFromPeers(Hash256? hash, CancellationToken cancellationToken, string type = Pivot) => (await TryGetFromPeers(hash, cancellationToken, static async (peer, hash256, token) => { BlockHeader? header = await peer.GetHeadBlockHeader(hash256, token); // Only accept a header that is actually the requested block; a peer must not substitute another. return header is not null && header.Hash == hash256 ? header : null; - }, type))?.Number; + }, type)) is { } h + ? h.Number + : null; protected async Task TryGetFromPeers(T id, CancellationToken cancellationToken, Func> getHeader, string? type = Pivot) @@ -228,9 +230,9 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) return null; } - private bool TryOverwritePivot(Hash256 potentialPivotBlockHash, long potentialPivotBlockNumber) + private bool TryOverwritePivot(Hash256 potentialPivotBlockHash, ulong potentialPivotBlockNumber) { - long targetBlock = _beaconSyncStrategy.GetTargetBlockHeight() ?? 0; + ulong targetBlock = _beaconSyncStrategy.GetTargetBlockHeight() ?? 0UL; bool isCloseToHead = targetBlock <= potentialPivotBlockNumber || (targetBlock - potentialPivotBlockNumber) < Constants.MaxDistanceFromHead; bool newPivotHigherThanOld = potentialPivotBlockNumber > _blockTree.SyncPivot.BlockNumber; @@ -247,7 +249,7 @@ private bool TryOverwritePivot(Hash256 potentialPivotBlockHash, long potentialPi return false; } - private void UpdateConfigValues(Hash256 finalizedBlockHash, long finalizedBlockNumber) + private void UpdateConfigValues(Hash256 finalizedBlockHash, ulong finalizedBlockNumber) { _blockTree.SyncPivot = (finalizedBlockNumber, finalizedBlockHash); _syncConfig.MaxAttemptsToUpdatePivot = 0; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/UnsafeStartingSyncPivotUpdater.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/UnsafeStartingSyncPivotUpdater.cs index b24f98a0bf81..ea2eea444863 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/UnsafeStartingSyncPivotUpdater.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/UnsafeStartingSyncPivotUpdater.cs @@ -30,7 +30,7 @@ public class UnsafeStartingSyncPivotUpdater( : StartingSyncPivotUpdater(blockTree, syncModeSelector, syncPeerPool, syncConfig, blockCacheService, beaconSyncStrategy, logManager) { - protected override async Task<(Hash256 Hash, long Number)?> TryGetPivotData(CancellationToken cancellationToken) + protected override async Task<(Hash256 Hash, ulong Number)?> TryGetPivotData(CancellationToken cancellationToken) { // getting potentially unsafe head block hash, because some chains (e.g. optimism) aren't providing finalized block hash until fully synced Hash256? headBlockHash = _beaconSyncStrategy.GetHeadBlockHash(); @@ -38,13 +38,13 @@ public class UnsafeStartingSyncPivotUpdater( if (headBlockHash is not null && headBlockHash != Keccak.Zero) { const string head = "head"; - long? headBlockNumber = TryGetBlockNumberFromBlockCache(headBlockHash, head) + ulong headBlockNumber = TryGetBlockNumberFromBlockCache(headBlockHash, head) ?? await TryGetFromPeers(headBlockHash, cancellationToken, head) - ?? 0; + ?? 0UL; if (headBlockNumber > Reorganization.MaxDepth) { - long potentialPivotBlockNumber = headBlockNumber.Value - Reorganization.MaxDepth; + ulong potentialPivotBlockNumber = headBlockNumber - Reorganization.MaxDepth; Hash256? potentialPivotBlockHash = TryGetPotentialPivotBlockNumberFromBlockCache(potentialPivotBlockNumber) @@ -61,7 +61,7 @@ public class UnsafeStartingSyncPivotUpdater( return null; } - private Task TryGetFromPeers(long blockNumber, CancellationToken cancellationToken) => + private Task TryGetFromPeers(ulong blockNumber, CancellationToken cancellationToken) => TryGetFromPeers(blockNumber, cancellationToken, static async (peer, number, token) => { using IOwnedReadOnlyList? x = await peer.GetBlockHeaders(number, 1, 0, token); @@ -70,7 +70,7 @@ public class UnsafeStartingSyncPivotUpdater( return headers.Length == 1 && headers[0].Number == number ? headers[0] : null; }); - private Hash256? TryGetPotentialPivotBlockNumberFromBlockCache(long potentialPivotBlockNumber) + private Hash256? TryGetPotentialPivotBlockNumberFromBlockCache(ulong potentialPivotBlockNumber) { if (_logger.IsDebug) _logger.Debug("Looking for header of pivot block in block cache"); diff --git a/src/Nethermind/Nethermind.Mining.Test/FollowOtherMinersTests.cs b/src/Nethermind/Nethermind.Mining.Test/FollowOtherMinersTests.cs index c55396a32d69..1a25242d87fe 100644 --- a/src/Nethermind/Nethermind.Mining.Test/FollowOtherMinersTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/FollowOtherMinersTests.cs @@ -14,25 +14,25 @@ namespace Nethermind.Mining.Test [TestFixture] public class FollowOtherMinersTests { - [TestCase(1000000, 1000000)] - [TestCase(1999999, 1999999)] - [TestCase(2000000, 2000000)] - [TestCase(2000001, 2000001)] - [TestCase(3000000, 3000000)] - public void Test(long current, long expected) + [TestCase(1000000UL, 1000000UL)] + [TestCase(1999999UL, 1999999UL)] + [TestCase(2000000UL, 2000000UL)] + [TestCase(2000001UL, 2000001UL)] + [TestCase(3000000UL, 3000000UL)] + public void Test(ulong current, ulong expected) { BlockHeader header = Build.A.BlockHeader.WithGasLimit(current).TestObject; FollowOtherMiners followOtherMiners = new(MainnetSpecProvider.Instance); Assert.That(followOtherMiners.GetGasLimit(header), Is.EqualTo(expected)); } - [TestCase(1000000, 2000000)] - [TestCase(2000000, 4000000)] - [TestCase(2000001, 4000002)] - [TestCase(3000000, 6000000)] - public void FollowOtherMines_on_1559_fork_block(long current, long expected) + [TestCase(1000000UL, 2000000UL)] + [TestCase(2000000UL, 4000000UL)] + [TestCase(2000001UL, 4000002UL)] + [TestCase(3000000UL, 6000000UL)] + public void FollowOtherMines_on_1559_fork_block(ulong current, ulong expected) { - int forkNumber = 5; + ulong forkNumber = 5; OverridableReleaseSpec spec = new(London.Instance) { Eip1559TransitionBlock = forkNumber diff --git a/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs index 8ee6ab35410a..c798000e2dea 100644 --- a/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs @@ -13,12 +13,12 @@ namespace Nethermind.Mining.Test [TestFixture] public class GasLimitCalculatorTests { - [TestCase(1000000, 2000000, 1000975)] - [TestCase(1999999, 2000000, 2000000)] - [TestCase(2000000, 2000000, 2000000)] - [TestCase(2000001, 2000000, 2000000)] - [TestCase(3000000, 2000000, 2997072)] - public void Test(long current, long target, long expected) + [TestCase(1000000UL, 2000000L, 1000975UL)] + [TestCase(1999999UL, 2000000L, 2000000UL)] + [TestCase(2000000UL, 2000000L, 2000000UL)] + [TestCase(2000001UL, 2000000L, 2000000UL)] + [TestCase(3000000UL, 2000000L, 2997072UL)] + public void Test(ulong current, long target, ulong expected) { BlocksConfig blocksConfig = new(); blocksConfig.TargetBlockGasLimit = target; diff --git a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs index 245f6039631d..61789ac80536 100644 --- a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs @@ -55,7 +55,7 @@ public void Sync_hint_and_get() { HintBasedCache hintBasedCache = new(static e => new NullDataSet(), LimboLogs.Instance); hintBasedCache.Hint(_guidA, 200000, 200000); - Assert.That(hintBasedCache.Get((uint)(200000 / Ethash.EpochLength)), Is.Not.Null); + Assert.That(hintBasedCache.Get((uint)(200000UL / Ethash.EpochLength)), Is.Not.Null); } [Test] @@ -82,7 +82,7 @@ void KeepHinting(Guid guid, int start) await Task.WhenAll(a, b, c); Assert.That(hintBasedCache.CachedEpochsCount, Is.EqualTo(5)); - for (uint i = (uint)(range / Ethash.EpochLength); i < (uint)((range + 120000) / Ethash.EpochLength); i++) + for (uint i = (uint)((ulong)range / Ethash.EpochLength); i < (uint)((ulong)(range + 120000) / Ethash.EpochLength); i++) { Assert.That(hintBasedCache.Get(i), Is.Not.Null); } diff --git a/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs b/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs index 2c1b2441900e..9b625344c0a5 100644 --- a/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs @@ -26,79 +26,79 @@ namespace Nethermind.Network.Test; [TestFixture] public class ForkInfoTests { - [TestCase(0, 0ul, "0xfc64ec04", 1_150_000ul, "Unsynced")] - [TestCase(1_149_999, 0ul, "0xfc64ec04", 1_150_000ul, "Last Frontier block")] - [TestCase(1_150_000, 0ul, "0x97c2c34c", 1_920_000ul, "First Homestead block")] - [TestCase(1_919_999, 0ul, "0x97c2c34c", 1_920_000ul, "Last Homestead block")] - [TestCase(1_920_000, 0ul, "0x91d1f948", 2_463_000ul, "First DAO block")] - [TestCase(2_462_999, 0ul, "0x91d1f948", 2_463_000ul, "Last DAO block")] - [TestCase(2_463_000, 0ul, "0x7a64da13", 2_675_000ul, "First Tangerine block")] - [TestCase(2_674_999, 0ul, "0x7a64da13", 2_675_000ul, "Last Tangerine block")] - [TestCase(2_675_000, 0ul, "0x3edd5b10", 4_370_000ul, "First Spurious block")] - [TestCase(4_369_999, 0ul, "0x3edd5b10", 4_370_000ul, "Last Spurious block")] - [TestCase(4_370_000, 0ul, "0xa00bc324", 7_280_000ul, "First Byzantium block")] - [TestCase(7_279_999, 0ul, "0xa00bc324", 7_280_000ul, "Last Byzantium block")] - [TestCase(7_280_000, 0ul, "0x668db0af", 9_069_000ul, "First Constantinople block")] - [TestCase(9_068_999, 0ul, "0x668db0af", 9_069_000ul, "Last Constantinople block")] - [TestCase(9_069_000, 0ul, "0x879d6e30", 9_200_000ul, "First Istanbul block")] - [TestCase(9_199_999, 0ul, "0x879d6e30", 9_200_000ul, "Last Istanbul block")] - [TestCase(9_200_000, 0ul, "0xe029e991", 12_244_000ul, "Last Muir Glacier")] - [TestCase(12_244_000, 0ul, "0x0eb440f6", 12_965_000ul, "First Berlin")] - [TestCase(12_964_999, 0ul, "0x0eb440f6", 12_965_000ul, "Last Berlin")] - [TestCase(12_965_000, 0ul, "0xb715077d", 13_773_000ul, "First London")] - [TestCase(13_772_999, 0ul, "0xb715077d", 13_773_000ul, "Last London")] - [TestCase(13_773_000, 0ul, "0x20c327fc", 15_050_000ul, "First Arrow Glacier")] - [TestCase(15_049_999, 0ul, "0x20c327fc", 15_050_000ul, "Last Arrow Glacier")] - [TestCase(15_050_000, 0ul, "0xf0afd0e3", 1_681_338_455ul, "First Gray Glacier")] - [TestCase(15_051_000, 0ul, "0xf0afd0e3", 1_681_338_455ul, "Future Gray Glacier")] - [TestCase(15_051_000, 1_681_338_455ul, "0xdce96c2d", 1_710_338_135ul, "First Shanghai timestamp")] - [TestCase(15_051_000, 1_710_338_134ul, "0xdce96c2d", 1_710_338_135ul, "Future Shanghai timestamp")] - [TestCase(15_051_000, 1_710_338_135ul, "0x9f3d2254", 1_746_612_311ul, "First Cancun timestamp")] - [TestCase(15_051_000, 1_746_612_310ul, "0x9f3d2254", 1_746_612_311ul, "Future Cancun timestamp")] - [TestCase(15_051_000, 1_746_612_311ul, "0xc376cf8b", 1_764_798_551ul, "First Prague timestamp")] - [TestCase(15_051_000, 1_764_798_550ul, "0xc376cf8b", 1_764_798_551ul, "Future Prague timestamp")] - [TestCase(15_051_000, 1_764_798_551ul, "0x5167e2a6", 1_765_290_071ul, "First Osaka timestamp")] - [TestCase(15_051_000, 1_765_290_070ul, "0x5167e2a6", 1_765_290_071ul, "Future Osaka timestamp")] - [TestCase(15_051_000, 1_765_290_071ul, "0xcba2a1c0", 1_767_747_671ul, "First BPO1 timestamp")] - [TestCase(15_051_000, 1_767_747_670ul, "0xcba2a1c0", 1_767_747_671ul, "Future BPO1 timestamp")] - [TestCase(15_051_000, 1_767_747_671ul, "0x07c9462e", 0ul, "First BPO2 timestamp")] - [TestCase(15_051_000, 1_867_747_671ul, "0x07c9462e", 0ul, "Future BPO2 timestamp")] - public void Fork_id_and_hash_as_expected(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.MainnetGenesis, forkHashHex, next, description, MainnetSpecProvider.Instance, "foundation.json"); - - [TestCase(0, 0ul, "0xfc64ec04", 1_150_000ul, "Unsynced")] - [TestCase(1_149_999, 0ul, "0xfc64ec04", 1_150_000ul, "Last Frontier block")] - [TestCase(1_150_000, 0ul, "0x97c2c34c", 1_920_000ul, "First Homestead block")] - [TestCase(1_919_999, 0ul, "0x97c2c34c", 1_920_000ul, "Last Homestead block")] - [TestCase(1_920_000, 0ul, "0x91d1f948", 2_463_000ul, "First DAO block")] - [TestCase(2_462_999, 0ul, "0x91d1f948", 2_463_000ul, "Last DAO block")] - [TestCase(2_463_000, 0ul, "0x7a64da13", 2_675_000ul, "First Tangerine block")] - [TestCase(2_674_999, 0ul, "0x7a64da13", 2_675_000ul, "Last Tangerine block")] - [TestCase(2_675_000, 0ul, "0x3edd5b10", 4_370_000ul, "First Spurious block")] - [TestCase(4_369_999, 0ul, "0x3edd5b10", 4_370_000ul, "Last Spurious block")] - [TestCase(4_370_000, 0ul, "0xa00bc324", 7_280_000ul, "First Byzantium block")] - [TestCase(7_279_999, 0ul, "0xa00bc324", 7_280_000ul, "Last Byzantium block")] - [TestCase(7_280_000, 0ul, "0x668db0af", 9_069_000ul, "First Constantinople block")] - [TestCase(9_068_999, 0ul, "0x668db0af", 9_069_000ul, "Last Constantinople block")] - [TestCase(9_069_000, 0ul, "0x879d6e30", 9_200_000ul, "First Istanbul block")] - [TestCase(9_199_999, 0ul, "0x879d6e30", 9_200_000ul, "Last Istanbul block")] - [TestCase(9_200_000, 0ul, "0xe029e991", 12_244_000ul, "Last Muir Glacier")] - [TestCase(12_244_000, 0ul, "0x0eb440f6", 12_965_000ul, "First Berlin")] - [TestCase(12_964_999, 0ul, "0x0eb440f6", 12_965_000ul, "Last Berlin")] - [TestCase(12_965_000, 0ul, "0xb715077d", 13_773_000ul, "First London")] - [TestCase(13_772_999, 0ul, "0xb715077d", 13_773_000ul, "Last London")] - [TestCase(13_773_000, 0ul, "0x20c327fc", 15_050_000ul, "First Arrow Glacier")] - [TestCase(15_049_999, 0ul, "0x20c327fc", 15_050_000ul, "Last Arrow Glacier")] - [TestCase(15_050_000, 0ul, "0xf0afd0e3", 1_668_000_000ul, "First Gray Glacier")] - [TestCase(17_999_999, 0ul, "0xf0afd0e3", 1_668_000_000ul, "Last Gray Glacier")] - [TestCase(20_000_000, 1_668_000_000ul, "0x71147644", 0ul, "First Shanghai")] - [TestCase(21_000_000, 1_768_000_000ul, "0x71147644", 0ul, "Future Shanghai")] - public void Fork_id_and_hash_as_expected_with_timestamps(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.MainnetGenesis, forkHashHex, next, description, "TimestampForkIdTest.json", + [TestCase(0ul, 0ul, "0xfc64ec04", 1_150_000ul, "Unsynced")] + [TestCase(1_149_999ul, 0ul, "0xfc64ec04", 1_150_000ul, "Last Frontier block")] + [TestCase(1_150_000ul, 0ul, "0x97c2c34c", 1_920_000ul, "First Homestead block")] + [TestCase(1_919_999ul, 0ul, "0x97c2c34c", 1_920_000ul, "Last Homestead block")] + [TestCase(1_920_000ul, 0ul, "0x91d1f948", 2_463_000ul, "First DAO block")] + [TestCase(2_462_999ul, 0ul, "0x91d1f948", 2_463_000ul, "Last DAO block")] + [TestCase(2_463_000ul, 0ul, "0x7a64da13", 2_675_000ul, "First Tangerine block")] + [TestCase(2_674_999ul, 0ul, "0x7a64da13", 2_675_000ul, "Last Tangerine block")] + [TestCase(2_675_000ul, 0ul, "0x3edd5b10", 4_370_000ul, "First Spurious block")] + [TestCase(4_369_999ul, 0ul, "0x3edd5b10", 4_370_000ul, "Last Spurious block")] + [TestCase(4_370_000ul, 0ul, "0xa00bc324", 7_280_000ul, "First Byzantium block")] + [TestCase(7_279_999ul, 0ul, "0xa00bc324", 7_280_000ul, "Last Byzantium block")] + [TestCase(7_280_000ul, 0ul, "0x668db0af", 9_069_000ul, "First Constantinople block")] + [TestCase(9_068_999ul, 0ul, "0x668db0af", 9_069_000ul, "Last Constantinople block")] + [TestCase(9_069_000ul, 0ul, "0x879d6e30", 9_200_000ul, "First Istanbul block")] + [TestCase(9_199_999ul, 0ul, "0x879d6e30", 9_200_000ul, "Last Istanbul block")] + [TestCase(9_200_000ul, 0ul, "0xe029e991", 12_244_000ul, "Last Muir Glacier")] + [TestCase(12_244_000ul, 0ul, "0x0eb440f6", 12_965_000ul, "First Berlin")] + [TestCase(12_964_999ul, 0ul, "0x0eb440f6", 12_965_000ul, "Last Berlin")] + [TestCase(12_965_000ul, 0ul, "0xb715077d", 13_773_000ul, "First London")] + [TestCase(13_772_999ul, 0ul, "0xb715077d", 13_773_000ul, "Last London")] + [TestCase(13_773_000ul, 0ul, "0x20c327fc", 15_050_000ul, "First Arrow Glacier")] + [TestCase(15_049_999ul, 0ul, "0x20c327fc", 15_050_000ul, "Last Arrow Glacier")] + [TestCase(15_050_000ul, 0ul, "0xf0afd0e3", 1_681_338_455ul, "First Gray Glacier")] + [TestCase(15_051_000ul, 0ul, "0xf0afd0e3", 1_681_338_455ul, "Future Gray Glacier")] + [TestCase(15_051_000ul, 1_681_338_455ul, "0xdce96c2d", 1_710_338_135ul, "First Shanghai timestamp")] + [TestCase(15_051_000ul, 1_710_338_134ul, "0xdce96c2d", 1_710_338_135ul, "Future Shanghai timestamp")] + [TestCase(15_051_000ul, 1_710_338_135ul, "0x9f3d2254", 1_746_612_311ul, "First Cancun timestamp")] + [TestCase(15_051_000ul, 1_746_612_310ul, "0x9f3d2254", 1_746_612_311ul, "Future Cancun timestamp")] + [TestCase(15_051_000ul, 1_746_612_311ul, "0xc376cf8b", 1_764_798_551ul, "First Prague timestamp")] + [TestCase(15_051_000ul, 1_764_798_550ul, "0xc376cf8b", 1_764_798_551ul, "Future Prague timestamp")] + [TestCase(15_051_000ul, 1_764_798_551ul, "0x5167e2a6", 1_765_290_071ul, "First Osaka timestamp")] + [TestCase(15_051_000ul, 1_765_290_070ul, "0x5167e2a6", 1_765_290_071ul, "Future Osaka timestamp")] + [TestCase(15_051_000ul, 1_765_290_071ul, "0xcba2a1c0", 1_767_747_671ul, "First BPO1 timestamp")] + [TestCase(15_051_000ul, 1_767_747_670ul, "0xcba2a1c0", 1_767_747_671ul, "Future BPO1 timestamp")] + [TestCase(15_051_000ul, 1_767_747_671ul, "0x07c9462e", 0ul, "First BPO2 timestamp")] + [TestCase(15_051_000ul, 1_867_747_671ul, "0x07c9462e", 0ul, "Future BPO2 timestamp")] + public void Fork_id_and_hash_as_expected(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.MainnetGenesis, forkHashHex, next, description, MainnetSpecProvider.Instance, "foundation.json"); + + [TestCase(0ul, 0ul, "0xfc64ec04", 1_150_000ul, "Unsynced")] + [TestCase(1_149_999ul, 0ul, "0xfc64ec04", 1_150_000ul, "Last Frontier block")] + [TestCase(1_150_000ul, 0ul, "0x97c2c34c", 1_920_000ul, "First Homestead block")] + [TestCase(1_919_999ul, 0ul, "0x97c2c34c", 1_920_000ul, "Last Homestead block")] + [TestCase(1_920_000ul, 0ul, "0x91d1f948", 2_463_000ul, "First DAO block")] + [TestCase(2_462_999ul, 0ul, "0x91d1f948", 2_463_000ul, "Last DAO block")] + [TestCase(2_463_000ul, 0ul, "0x7a64da13", 2_675_000ul, "First Tangerine block")] + [TestCase(2_674_999ul, 0ul, "0x7a64da13", 2_675_000ul, "Last Tangerine block")] + [TestCase(2_675_000ul, 0ul, "0x3edd5b10", 4_370_000ul, "First Spurious block")] + [TestCase(4_369_999ul, 0ul, "0x3edd5b10", 4_370_000ul, "Last Spurious block")] + [TestCase(4_370_000ul, 0ul, "0xa00bc324", 7_280_000ul, "First Byzantium block")] + [TestCase(7_279_999ul, 0ul, "0xa00bc324", 7_280_000ul, "Last Byzantium block")] + [TestCase(7_280_000ul, 0ul, "0x668db0af", 9_069_000ul, "First Constantinople block")] + [TestCase(9_068_999ul, 0ul, "0x668db0af", 9_069_000ul, "Last Constantinople block")] + [TestCase(9_069_000ul, 0ul, "0x879d6e30", 9_200_000ul, "First Istanbul block")] + [TestCase(9_199_999ul, 0ul, "0x879d6e30", 9_200_000ul, "Last Istanbul block")] + [TestCase(9_200_000ul, 0ul, "0xe029e991", 12_244_000ul, "Last Muir Glacier")] + [TestCase(12_244_000ul, 0ul, "0x0eb440f6", 12_965_000ul, "First Berlin")] + [TestCase(12_964_999ul, 0ul, "0x0eb440f6", 12_965_000ul, "Last Berlin")] + [TestCase(12_965_000ul, 0ul, "0xb715077d", 13_773_000ul, "First London")] + [TestCase(13_772_999ul, 0ul, "0xb715077d", 13_773_000ul, "Last London")] + [TestCase(13_773_000ul, 0ul, "0x20c327fc", 15_050_000ul, "First Arrow Glacier")] + [TestCase(15_049_999ul, 0ul, "0x20c327fc", 15_050_000ul, "Last Arrow Glacier")] + [TestCase(15_050_000ul, 0ul, "0xf0afd0e3", 1_668_000_000ul, "First Gray Glacier")] + [TestCase(17_999_999ul, 0ul, "0xf0afd0e3", 1_668_000_000ul, "Last Gray Glacier")] + [TestCase(20_000_000ul, 1_668_000_000ul, "0x71147644", 0ul, "First Shanghai")] + [TestCase(21_000_000ul, 1_768_000_000ul, "0x71147644", 0ul, "Future Shanghai")] + public void Fork_id_and_hash_as_expected_with_timestamps(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.MainnetGenesis, forkHashHex, next, description, "TimestampForkIdTest.json", $"../../../../{Assembly.GetExecutingAssembly().GetName().Name}"); - [TestCase(15_050_000, 0ul, "0xf0afd0e3", 21_000_000ul, "First Gray Glacier")] - [TestCase(21_000_000, 0ul, "0x3f5fd195", 1681338455UL, "First Merge Fork Id test")] - [TestCase(21_811_000, 0ul, "0x3f5fd195", 1681338455UL, "Future Merge Fork Id test")] - public void Fork_id_and_hash_as_expected_with_merge_fork_id(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) + [TestCase(15_050_000ul, 0ul, "0xf0afd0e3", 21_000_000ul, "First Gray Glacier")] + [TestCase(21_000_000ul, 0ul, "0x3f5fd195", 1681338455UL, "First Merge Fork Id test")] + [TestCase(21_811_000ul, 0ul, "0x3f5fd195", 1681338455UL, "Future Merge Fork Id test")] + public void Fork_id_and_hash_as_expected_with_merge_fork_id(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) { ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); ChainSpec spec = loader.LoadEmbeddedOrFromFile("../../../../Chains/foundation.json"); @@ -108,71 +108,71 @@ public void Fork_id_and_hash_as_expected_with_merge_fork_id(long head, ulong hea Test(head, headTimestamp, KnownHashes.MainnetGenesis, forkHashHex, next, description, provider); } - [TestCase(0, 0ul, "0xFE3366E7", 1735371ul, "Sepolia genesis")] - [TestCase(1735370, 0ul, "0xFE3366E7", 1_735_371ul, "Sepolia Last block before MergeForkIdTransition")] - [TestCase(1735371, 0ul, "0xb96cbd13", 1_677_557_088ul, "First block - Sepolia MergeForkIdTransition")] - [TestCase(1735372, 1_677_557_088ul, "0xf7f9bc08", 1_706_655_072ul, "Shanghai")] - [TestCase(1735372, 1_706_655_071ul, "0xf7f9bc08", 1_706_655_072ul, "Future Shanghai")] - [TestCase(1735373, 1_706_655_072ul, "0x88cf81d9", 1_741_159_776ul, "First Cancun timestamp")] - [TestCase(1735374, 1_716_655_072ul, "0x88cf81d9", 1_741_159_776ul, "Future Cancun timestamp")] - [TestCase(1735373, 1_741_159_776ul, "0xed88b5fd", 1_760_427_360ul, "First Prague timestamp")] - [TestCase(1735374, 1_751_159_776ul, "0xed88b5fd", 1_760_427_360ul, "Future Prague timestamp")] - [TestCase(1735373, 1_760_427_360ul, "0xe2ae4999", 1_761_017_184ul, "First Osaka timestamp")] - [TestCase(1735374, 1_760_428_360ul, "0xe2ae4999", 1_761_017_184ul, "Future Osaka timestamp")] - [TestCase(1735373, 1_761_017_184ul, "0x56078a1e", 1_761_607_008ul, "First BPO1 timestamp")] - [TestCase(1735374, 1_761_018_184ul, "0x56078a1e", 1_761_607_008ul, "Future BPO1 timestamp")] - [TestCase(1735373, 1_761_607_008ul, "0x268956b6", 0ul, "First BPO2 timestamp")] - [TestCase(1735374, 1_761_608_008ul, "0x268956b6", 0ul, "Future BPO2 timestamp")] - public void Fork_id_and_hash_as_expected_on_sepolia(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.SepoliaGenesis, forkHashHex, next, description, SepoliaSpecProvider.Instance, "sepolia.json"); - - [TestCase(0, 0ul, "0xf64909b1", 1604400ul, "Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium")] - [TestCase(1604399, 0ul, "0xf64909b1", 1604400ul, "Last Byzantium block")] - [TestCase(1604400, 0ul, "0xfde2d083", 2508800ul, "First Constantinople block")] - [TestCase(2508799, 0ul, "0xfde2d083", 2508800ul, "Last Constantinople block")] - [TestCase(2508800, 0ul, "0xfc1d8f2f", 7298030ul, "First Petersburg block")] - [TestCase(7298029, 0ul, "0xfc1d8f2f", 7298030ul, "Last Petersburg block")] - [TestCase(7298030, 0ul, "0x54d05e6c", 9186425ul, "First Istanbul block")] - [TestCase(9186424, 0ul, "0x54d05e6c", 9186425ul, "Last Istanbul block")] - [TestCase(9186425, 0ul, "0xb6e6cd81", 16101500ul, "First POSDAO Activation block")] - [TestCase(16101499, 0ul, "0xb6e6cd81", 16101500ul, "Last POSDAO Activation block")] - [TestCase(16101500, 0ul, "0x069a83d9", 19040000ul, "First Berlin block")] - [TestCase(19039999, 0ul, "0x069a83d9", 19040000ul, "Last Berlin block")] - [TestCase(19040000, 0ul, "0x018479d3", GnosisSpecProvider.ShanghaiTimestamp, "First London block")] - [TestCase(21735000, 0ul, "0x018479d3", GnosisSpecProvider.ShanghaiTimestamp, "First GIP-31 block")] - [TestCase(31735000, GnosisSpecProvider.ShanghaiTimestamp, "0x2efe91ba", GnosisSpecProvider.CancunTimestamp, "First Shanghai timestamp")] - [TestCase(41735000, GnosisSpecProvider.CancunTimestamp, "0x1384dfc1", GnosisSpecProvider.PragueTimestamp, "First Cancun timestamp")] - [TestCase(91735000, GnosisSpecProvider.PragueTimestamp - 1, "0x1384dfc1", GnosisSpecProvider.PragueTimestamp, "Future Cancun timestamp")] - [TestCase(101735000, GnosisSpecProvider.PragueTimestamp, "0x2f095d4a", GnosisSpecProvider.BalancerTimestamp, "First Prague timestamp")] - [TestCase(101735000, GnosisSpecProvider.BalancerTimestamp - 1, "0x2f095d4a", GnosisSpecProvider.BalancerTimestamp, "Future Prague timestamp")] - [TestCase(111735000, GnosisSpecProvider.BalancerTimestamp, "0xd00284ad", GnosisSpecProvider.OsakaTimestamp, "First Balancer timestamp")] - [TestCase(111735000, GnosisSpecProvider.OsakaTimestamp - 1, "0xd00284ad", GnosisSpecProvider.OsakaTimestamp, "Future Balancer timestamp")] - [TestCase(121735000, GnosisSpecProvider.OsakaTimestamp, "0xcfca387c", 0ul, "First Osaka timestamp")] - [TestCase(121735000, GnosisSpecProvider.OsakaTimestamp + 100, "0xcfca387c", 0ul, "Future Osaka timestamp")] - public void Fork_id_and_hash_as_expected_on_gnosis(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => + [TestCase(0ul, 0ul, "0xFE3366E7", 1735371ul, "Sepolia genesis")] + [TestCase(1735370ul, 0ul, "0xFE3366E7", 1_735_371ul, "Sepolia Last block before MergeForkIdTransition")] + [TestCase(1735371ul, 0ul, "0xb96cbd13", 1_677_557_088ul, "First block - Sepolia MergeForkIdTransition")] + [TestCase(1735372ul, 1_677_557_088ul, "0xf7f9bc08", 1_706_655_072ul, "Shanghai")] + [TestCase(1735372ul, 1_706_655_071ul, "0xf7f9bc08", 1_706_655_072ul, "Future Shanghai")] + [TestCase(1735373ul, 1_706_655_072ul, "0x88cf81d9", 1_741_159_776ul, "First Cancun timestamp")] + [TestCase(1735374ul, 1_716_655_072ul, "0x88cf81d9", 1_741_159_776ul, "Future Cancun timestamp")] + [TestCase(1735373ul, 1_741_159_776ul, "0xed88b5fd", 1_760_427_360ul, "First Prague timestamp")] + [TestCase(1735374ul, 1_751_159_776ul, "0xed88b5fd", 1_760_427_360ul, "Future Prague timestamp")] + [TestCase(1735373ul, 1_760_427_360ul, "0xe2ae4999", 1_761_017_184ul, "First Osaka timestamp")] + [TestCase(1735374ul, 1_760_428_360ul, "0xe2ae4999", 1_761_017_184ul, "Future Osaka timestamp")] + [TestCase(1735373ul, 1_761_017_184ul, "0x56078a1e", 1_761_607_008ul, "First BPO1 timestamp")] + [TestCase(1735374ul, 1_761_018_184ul, "0x56078a1e", 1_761_607_008ul, "Future BPO1 timestamp")] + [TestCase(1735373ul, 1_761_607_008ul, "0x268956b6", 0ul, "First BPO2 timestamp")] + [TestCase(1735374ul, 1_761_608_008ul, "0x268956b6", 0ul, "Future BPO2 timestamp")] + public void Fork_id_and_hash_as_expected_on_sepolia(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.SepoliaGenesis, forkHashHex, next, description, SepoliaSpecProvider.Instance, "sepolia.json"); + + [TestCase(0ul, 0ul, "0xf64909b1", 1604400ul, "Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium")] + [TestCase(1604399ul, 0ul, "0xf64909b1", 1604400ul, "Last Byzantium block")] + [TestCase(1604400ul, 0ul, "0xfde2d083", 2508800ul, "First Constantinople block")] + [TestCase(2508799ul, 0ul, "0xfde2d083", 2508800ul, "Last Constantinople block")] + [TestCase(2508800ul, 0ul, "0xfc1d8f2f", 7298030ul, "First Petersburg block")] + [TestCase(7298029ul, 0ul, "0xfc1d8f2f", 7298030ul, "Last Petersburg block")] + [TestCase(7298030ul, 0ul, "0x54d05e6c", 9186425ul, "First Istanbul block")] + [TestCase(9186424ul, 0ul, "0x54d05e6c", 9186425ul, "Last Istanbul block")] + [TestCase(9186425ul, 0ul, "0xb6e6cd81", 16101500ul, "First POSDAO Activation block")] + [TestCase(16101499ul, 0ul, "0xb6e6cd81", 16101500ul, "Last POSDAO Activation block")] + [TestCase(16101500ul, 0ul, "0x069a83d9", 19040000ul, "First Berlin block")] + [TestCase(19039999ul, 0ul, "0x069a83d9", 19040000ul, "Last Berlin block")] + [TestCase(19040000ul, 0ul, "0x018479d3", GnosisSpecProvider.ShanghaiTimestamp, "First London block")] + [TestCase(21735000ul, 0ul, "0x018479d3", GnosisSpecProvider.ShanghaiTimestamp, "First GIP-31 block")] + [TestCase(31735000ul, GnosisSpecProvider.ShanghaiTimestamp, "0x2efe91ba", GnosisSpecProvider.CancunTimestamp, "First Shanghai timestamp")] + [TestCase(41735000ul, GnosisSpecProvider.CancunTimestamp, "0x1384dfc1", GnosisSpecProvider.PragueTimestamp, "First Cancun timestamp")] + [TestCase(91735000ul, GnosisSpecProvider.PragueTimestamp - 1, "0x1384dfc1", GnosisSpecProvider.PragueTimestamp, "Future Cancun timestamp")] + [TestCase(101735000ul, GnosisSpecProvider.PragueTimestamp, "0x2f095d4a", GnosisSpecProvider.BalancerTimestamp, "First Prague timestamp")] + [TestCase(101735000ul, GnosisSpecProvider.BalancerTimestamp - 1, "0x2f095d4a", GnosisSpecProvider.BalancerTimestamp, "Future Prague timestamp")] + [TestCase(111735000ul, GnosisSpecProvider.BalancerTimestamp, "0xd00284ad", GnosisSpecProvider.OsakaTimestamp, "First Balancer timestamp")] + [TestCase(111735000ul, GnosisSpecProvider.OsakaTimestamp - 1, "0xd00284ad", GnosisSpecProvider.OsakaTimestamp, "Future Balancer timestamp")] + [TestCase(121735000ul, GnosisSpecProvider.OsakaTimestamp, "0xcfca387c", 0ul, "First Osaka timestamp")] + [TestCase(121735000ul, GnosisSpecProvider.OsakaTimestamp + 100, "0xcfca387c", 0ul, "Future Osaka timestamp")] + public void Fork_id_and_hash_as_expected_on_gnosis(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.GnosisGenesis, forkHashHex, next, description, GnosisSpecProvider.Instance, "gnosis.json"); - [TestCase(0L, 0UL, "0x50d39d7b", ChiadoSpecProvider.ShanghaiTimestamp, "Chiado genesis")] - [TestCase(3945317, ChiadoSpecProvider.ShanghaiTimestamp, "0xa15a4252", ChiadoSpecProvider.CancunTimestamp, "First Shanghai timestamp")] - [TestCase(4_000_000, ChiadoSpecProvider.CancunTimestamp, "0x5fbc16bc", ChiadoSpecProvider.PragueTimestamp, "First Cancun timestamp")] - [TestCase(5_000_000, ChiadoSpecProvider.PragueTimestamp - 1, "0x5fbc16bc", ChiadoSpecProvider.PragueTimestamp, "Future Cancun timestamp")] - [TestCase(5_000_000, ChiadoSpecProvider.PragueTimestamp, "0x8ba51786", ChiadoSpecProvider.OsakaTimestamp, "First Prague timestamp")] - [TestCase(5_000_000, ChiadoSpecProvider.OsakaTimestamp - 1, "0x8ba51786", ChiadoSpecProvider.OsakaTimestamp, "Future Prague timestamp")] - [TestCase(5_000_000, ChiadoSpecProvider.OsakaTimestamp, "0x71c457cd", 0ul, "First Osaka timestamp")] - [TestCase(5_000_000, ChiadoSpecProvider.OsakaTimestamp + 100, "0x71c457cd", 0ul, "Future Osaka timestamp")] - public void Fork_id_and_hash_as_expected_on_chiado(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => + [TestCase(0ul, 0UL, "0x50d39d7b", ChiadoSpecProvider.ShanghaiTimestamp, "Chiado genesis")] + [TestCase(3945317ul, ChiadoSpecProvider.ShanghaiTimestamp, "0xa15a4252", ChiadoSpecProvider.CancunTimestamp, "First Shanghai timestamp")] + [TestCase(4_000_000ul, ChiadoSpecProvider.CancunTimestamp, "0x5fbc16bc", ChiadoSpecProvider.PragueTimestamp, "First Cancun timestamp")] + [TestCase(5_000_000ul, ChiadoSpecProvider.PragueTimestamp - 1, "0x5fbc16bc", ChiadoSpecProvider.PragueTimestamp, "Future Cancun timestamp")] + [TestCase(5_000_000ul, ChiadoSpecProvider.PragueTimestamp, "0x8ba51786", ChiadoSpecProvider.OsakaTimestamp, "First Prague timestamp")] + [TestCase(5_000_000ul, ChiadoSpecProvider.OsakaTimestamp - 1, "0x8ba51786", ChiadoSpecProvider.OsakaTimestamp, "Future Prague timestamp")] + [TestCase(5_000_000ul, ChiadoSpecProvider.OsakaTimestamp, "0x71c457cd", 0ul, "First Osaka timestamp")] + [TestCase(5_000_000ul, ChiadoSpecProvider.OsakaTimestamp + 100, "0x71c457cd", 0ul, "Future Osaka timestamp")] + public void Fork_id_and_hash_as_expected_on_chiado(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Test(head, headTimestamp, KnownHashes.ChiadoGenesis, forkHashHex, next, description, ChiadoSpecProvider.Instance, "chiado.json"); - [TestCase(0L, HoodiSpecProvider.CancunTimestamp, "0xbef71d30", HoodiSpecProvider.PragueTimestamp, "First Cancun timestamp")] - [TestCase(5_000_000, HoodiSpecProvider.PragueTimestamp - 1, "0xbef71d30", HoodiSpecProvider.PragueTimestamp, "Future Cancun timestamp")] - [TestCase(5_000_000, HoodiSpecProvider.PragueTimestamp, "0x929e24e", HoodiSpecProvider.OsakaTimestamp, "First Prague timestamp")] - [TestCase(5_000_000, HoodiSpecProvider.OsakaTimestamp - 1, "0x929e24e", HoodiSpecProvider.OsakaTimestamp, "Future Prague timestamp")] - [TestCase(6_000_000, HoodiSpecProvider.OsakaTimestamp, "0xe7e0e7ff", HoodiSpecProvider.BPO1Timestamp, "First Osaka timestamp")] - [TestCase(6_000_000, HoodiSpecProvider.BPO1Timestamp - 1, "0xe7e0e7ff", HoodiSpecProvider.BPO1Timestamp, "Future Osaka timestamp")] - [TestCase(7_000_000, HoodiSpecProvider.BPO1Timestamp, "0x3893353e", HoodiSpecProvider.BPO2Timestamp, "First BPO1 timestamp")] - [TestCase(7_000_000, HoodiSpecProvider.BPO2Timestamp - 1, "0x3893353e", HoodiSpecProvider.BPO2Timestamp, "Future BPO1 timestamp")] - [TestCase(8_000_000, HoodiSpecProvider.BPO2Timestamp, "0x23aa1351", 0ul, "First BPO2 timestamp")] - [TestCase(8_000_000, HoodiSpecProvider.BPO2Timestamp + 100000, "0x23aa1351", 0ul, "Future BPO2 timestamp")] - public void Fork_id_and_hash_as_expected_on_hoodi(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) + [TestCase(0ul, HoodiSpecProvider.CancunTimestamp, "0xbef71d30", HoodiSpecProvider.PragueTimestamp, "First Cancun timestamp")] + [TestCase(5_000_000ul, HoodiSpecProvider.PragueTimestamp - 1, "0xbef71d30", HoodiSpecProvider.PragueTimestamp, "Future Cancun timestamp")] + [TestCase(5_000_000ul, HoodiSpecProvider.PragueTimestamp, "0x929e24e", HoodiSpecProvider.OsakaTimestamp, "First Prague timestamp")] + [TestCase(5_000_000ul, HoodiSpecProvider.OsakaTimestamp - 1, "0x929e24e", HoodiSpecProvider.OsakaTimestamp, "Future Prague timestamp")] + [TestCase(6_000_000ul, HoodiSpecProvider.OsakaTimestamp, "0xe7e0e7ff", HoodiSpecProvider.BPO1Timestamp, "First Osaka timestamp")] + [TestCase(6_000_000ul, HoodiSpecProvider.BPO1Timestamp - 1, "0xe7e0e7ff", HoodiSpecProvider.BPO1Timestamp, "Future Osaka timestamp")] + [TestCase(7_000_000ul, HoodiSpecProvider.BPO1Timestamp, "0x3893353e", HoodiSpecProvider.BPO2Timestamp, "First BPO1 timestamp")] + [TestCase(7_000_000ul, HoodiSpecProvider.BPO2Timestamp - 1, "0x3893353e", HoodiSpecProvider.BPO2Timestamp, "Future BPO1 timestamp")] + [TestCase(8_000_000ul, HoodiSpecProvider.BPO2Timestamp, "0x23aa1351", 0ul, "First BPO2 timestamp")] + [TestCase(8_000_000ul, HoodiSpecProvider.BPO2Timestamp + 100000, "0x23aa1351", 0ul, "Future BPO2 timestamp")] + public void Fork_id_and_hash_as_expected_on_hoodi(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) { ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); ChainSpec spec = loader.LoadEmbeddedOrFromFile("../../../../Chains/hoodi.json"); @@ -184,61 +184,61 @@ public void Fork_id_and_hash_as_expected_on_hoodi(long head, ulong headTimestamp [TestCase(MainnetSpecProvider.GrayGlacierBlockNumber, 0ul, "0xf0afd0e3", 0ul, ValidationResult.Valid)] // Local is mainnet Petersburg, remote announces the same. No future fork is announced. - [TestCase(7987396, 0ul, "0x668db0af", 0ul, ValidationResult.Valid)] + [TestCase(7987396ul, 0ul, "0x668db0af", 0ul, ValidationResult.Valid)] // Local is mainnet Petersburg, remote announces the same. Remote also announces a next fork // at block 0xffffffff, but that is uncertain. - [TestCase(7987396, 0ul, "0x668db0af", ulong.MaxValue, ValidationResult.Valid)] + [TestCase(7987396ul, 0ul, "0x668db0af", ulong.MaxValue, ValidationResult.Valid)] // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // also Byzantium, but it's not yet aware of Petersburg (e.g. non updated node before the fork). // In this case we don't know if Petersburg passed yet or not. - [TestCase(7279999, 0ul, "0xa00bc324", 0ul, ValidationResult.Valid)] + [TestCase(7279999ul, 0ul, "0xa00bc324", 0ul, ValidationResult.Valid)] // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // also Byzantium, and it's also aware of Petersburg (e.g. updated node before the fork). We // don't know if Petersburg passed yet (will pass) or not. - [TestCase(7279999, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] + [TestCase(7279999ul, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // also Byzantium, and it's also aware of some random fork (e.g. misconfigured Petersburg). As // neither forks passed at neither nodes, they may mismatch, but we still connect for now. - [TestCase(7279999, 0ul, "0xa00bc324", ulong.MaxValue, ValidationResult.Valid)] + [TestCase(7279999ul, 0ul, "0xa00bc324", ulong.MaxValue, ValidationResult.Valid)] // Local is mainnet exactly on Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote // is simply out of sync, accept. - [TestCase(7280000, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] + [TestCase(7280000ul, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] // Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote // is simply out of sync, accept. - [TestCase(7987396, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] + [TestCase(7987396ul, 0ul, "0xa00bc324", 7280000ul, ValidationResult.Valid)] // Local is mainnet Petersburg, remote announces Spurious + knowledge about Byzantium. Remote // is definitely out of sync. It may or may not need the Petersburg update, we don't know yet. - [TestCase(7987396, 0ul, "0x3edd5b10", 4370000ul, ValidationResult.Valid)] + [TestCase(7987396ul, 0ul, "0x3edd5b10", 4370000ul, ValidationResult.Valid)] // Local is mainnet Byzantium, remote announces Petersburg. Local is out of sync, accept. - [TestCase(7279999, 0ul, "0x668db0af", 0ul, ValidationResult.Valid)] + [TestCase(7279999ul, 0ul, "0x668db0af", 0ul, ValidationResult.Valid)] // Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local // out of sync. Local also knows about a future fork, but that is uncertain yet. - [TestCase(4369999, 0ul, "0xa00bc324", 0ul, ValidationResult.Valid)] + [TestCase(4369999ul, 0ul, "0xa00bc324", 0ul, ValidationResult.Valid)] // Local is mainnet Petersburg. remote announces Byzantium but is not aware of further forks. // Remote needs software update. - [TestCase(7987396, 0ul, "0xa00bc324", 0ul, ValidationResult.RemoteStale)] + [TestCase(7987396ul, 0ul, "0xa00bc324", 0ul, ValidationResult.RemoteStale)] // Local is mainnet Petersburg, and isn't aware of more forks. Remote announces Petersburg + // 0xffffffff. Local needs software update, reject. - [TestCase(7987396, 0ul, "0x5cddc0e1", 0ul, ValidationResult.IncompatibleOrStale)] + [TestCase(7987396ul, 0ul, "0x5cddc0e1", 0ul, ValidationResult.IncompatibleOrStale)] // Local is mainnet Byzantium, and is aware of Petersburg. Remote announces Petersburg + // 0xffffffff. Local needs software update, reject. - [TestCase(7279999, 0ul, "0x5cddc0e1", 0ul, ValidationResult.IncompatibleOrStale)] + [TestCase(7279999ul, 0ul, "0x5cddc0e1", 0ul, ValidationResult.IncompatibleOrStale)] // Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing // fork) at block 7279999, before Petersburg. Local is incompatible. - [TestCase(7279999, 0ul, "0xa00bc324", 7279999ul, ValidationResult.IncompatibleOrStale)] + [TestCase(7279999ul, 0ul, "0xa00bc324", 7279999ul, ValidationResult.IncompatibleOrStale)] //------------------------------------ // Block to timestamp transition tests @@ -247,72 +247,72 @@ public void Fork_id_and_hash_as_expected_on_hoodi(long head, ulong headTimestamp // Local is mainnet currently in Gray Glacier only (so it's aware of Shanghai), remote announces // also Gray Glacier, but it's not yet aware of Shanghai (e.g. non updated node before the fork). // In this case we don't know if Shanghai passed yet or not. - [TestCase(15050000, 0ul, "0xf0afd0e3", 0ul, ValidationResult.Valid, true)] + [TestCase(15050000ul, 0ul, "0xf0afd0e3", 0ul, ValidationResult.Valid, true)] // Local is mainnet currently in Gray Glacier only (so it's aware of Shanghai), remote announces // also Gray Glacier, and it's also aware of Shanghai (e.g. updated node before the fork). We // don't know if Shanghai passed yet (will pass) or not. - [TestCase(15050000, 0ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] + [TestCase(15050000ul, 0ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] // Local is mainnet currently in Gray Glacier only (so it's aware of Shanghai), remote announces // also Gray Glacier, and it's also aware of some random fork (e.g. misconfigured Shanghai). As // neither forks passed at neither nodes, they may mismatch, but we still connect for now. - [TestCase(15050000, 0ul, "0xf0afd0e3", ulong.MaxValue, ValidationResult.Valid, true)] + [TestCase(15050000ul, 0ul, "0xf0afd0e3", ulong.MaxValue, ValidationResult.Valid, true)] // Local is mainnet exactly on Shanghai, remote announces Gray Glacier + knowledge about Shanghai. Remote // is simply out of sync, accept. - [TestCase(20000000, 1_668_000_000ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] // Local is mainnet Shanghai, remote announces Gray Glacier + knowledge about Shanghai. Remote // is simply out of sync, accept. - [TestCase(20123456, 1_668_111_111ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] + [TestCase(20123456ul, 1_668_111_111ul, "0xf0afd0e3", 1_668_000_000ul, ValidationResult.Valid, true)] // Local is mainnet Shanghai, remote announces Arrow Glacier + knowledge about Gray Glacier. Remote // is definitely out of sync. It may or may not need the Shanghai update, we don't know yet. - [TestCase(20000000, 1_668_000_000ul, "0x20c327fc", 15_050_000ul, ValidationResult.Valid, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0x20c327fc", 15_050_000ul, ValidationResult.Valid, true)] // Local is mainnet Gray Glacier, remote announces Shanghai. Local is out of sync, accept. - [TestCase(15_050_000, 0ul, "0x71147644", 0ul, ValidationResult.Valid, true)] + [TestCase(15_050_000ul, 0ul, "0x71147644", 0ul, ValidationResult.Valid, true)] // Local is mainnet Arrow Glacier, remote announces Gray Glacier, but is not aware of Shanghai. Local // out of sync. Local also knows about a future fork, but that is uncertain yet. - [TestCase(13_773_000, 0ul, "0xf0afd0e3", 0ul, ValidationResult.Valid, true)] + [TestCase(13_773_000ul, 0ul, "0xf0afd0e3", 0ul, ValidationResult.Valid, true)] // Local is mainnet Shanghai. remote announces Gray Glacier but is not aware of further forks. // Remote needs software update. - [TestCase(20000000, 1_668_000_000ul, "0xf0afd0e3", 0ul, ValidationResult.RemoteStale, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0xf0afd0e3", 0ul, ValidationResult.RemoteStale, true)] // Local is mainnet Gray Glacier, and isn't aware of more forks. Remote announces Gray Glacier + // 0xffffffff. Local needs software update, reject. - [TestCase(15_050_000, 0ul, "0x87654321", ulong.MaxValue, ValidationResult.IncompatibleOrStale)] + [TestCase(15_050_000ul, 0ul, "0x87654321", ulong.MaxValue, ValidationResult.IncompatibleOrStale)] // Local is mainnet Gray Glacier, and is aware of Shanghai. Remote announces Shanghai + // 0xffffffff. Local needs software update, reject. - [TestCase(15_050_000, 0ul, "0x98765432", ulong.MaxValue, ValidationResult.IncompatibleOrStale, true)] + [TestCase(15_050_000ul, 0ul, "0x98765432", ulong.MaxValue, ValidationResult.IncompatibleOrStale, true)] // Local is mainnet Gray Glacier. Remote is also in Gray Glacier, but announces Gopherium (non existing // fork) at block 7279999, before Shanghai. Local is incompatible. - [TestCase(19999999, 1667999999ul, "0xf0afd0e3", 1667999999ul, ValidationResult.IncompatibleOrStale, true)] + [TestCase(19999999ul, 1667999999ul, "0xf0afd0e3", 1667999999ul, ValidationResult.IncompatibleOrStale, true)] //---------------------- // Timestamp based tests //---------------------- // Local is mainnet Shanghai, remote announces the same. No future fork is announced. - [TestCase(20000000, 1_668_000_000ul, "0x71147644", 0ul, ValidationResult.Valid, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0x71147644", 0ul, ValidationResult.Valid, true)] // Local is mainnet Shanghai, remote announces the same. Remote also announces a next fork // at time 0xffffffff, but that is uncertain. - [TestCase(20000000, 1_668_000_000ul, "0x71147644", ulong.MaxValue, ValidationResult.Valid, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0x71147644", ulong.MaxValue, ValidationResult.Valid, true)] // Local is mainnet Shanghai, and isn't aware of more forks. Remote announces Shanghai + // 0xffffffff. Local needs software update, reject. - [TestCase(20000000, 1_668_000_000ul, "0x846271649", 0ul, ValidationResult.IncompatibleOrStale, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0x846271649", 0ul, ValidationResult.IncompatibleOrStale, true)] // Local is mainnet Shanghai, remote is random Shanghai. - [TestCase(20000000, 1_668_000_000ul, "0x12345678", 0ul, ValidationResult.IncompatibleOrStale, true)] + [TestCase(20000000ul, 1_668_000_000ul, "0x12345678", 0ul, ValidationResult.IncompatibleOrStale, true)] - public void Test_fork_id_validation_mainnet(long headNumber, ulong headTimestamp, string hash, ulong next, ValidationResult result, bool UseTimestampSpec = false) + public void Test_fork_id_validation_mainnet(ulong headNumber, ulong headTimestamp, string hash, ulong next, ValidationResult result, bool UseTimestampSpec = false) { IBlockTree blockTree = Substitute.For(); Block head = Build.A.Block.WithNumber(headNumber).WithTimestamp(headTimestamp).TestObject; @@ -353,13 +353,13 @@ public void Chain_id_and_network_id_have_proper_default_values(ulong? specNetwor Assert.That(provider.NetworkId, Is.EqualTo(expectedNetworkId)); } - public static void Test(long head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, ISpecProvider specProvider, string chainSpec, string path = "../../../../Chains") + public static void Test(ulong head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, ISpecProvider specProvider, string chainSpec, string path = "../../../../Chains") { Test(head, headTimestamp, genesisHash, forkHashHex, next, description, specProvider); Test(head, headTimestamp, genesisHash, forkHashHex, next, description, chainSpec, path); } - public static void Test(long head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, string chainSpec, string path = "../../../../Chains") + public static void Test(ulong head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, string chainSpec, string path = "../../../../Chains") { ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); ChainSpec spec = loader.LoadEmbeddedOrFromFile(Path.Combine(path, chainSpec)); @@ -367,7 +367,7 @@ public static void Test(long head, ulong headTimestamp, Hash256 genesisHash, str Test(head, headTimestamp, genesisHash, forkHashHex, next, description, provider); } - private static void Test(long head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, ISpecProvider specProvider) + private static void Test(ulong head, ulong headTimestamp, Hash256 genesisHash, string forkHashHex, ulong next, string description, ISpecProvider specProvider) { uint expectedForkHash = Bytes.FromHexString(forkHashHex).ReadEthUInt32(); diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandlerTests.cs index 911148d22437..21335b57d8af 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandlerTests.cs @@ -342,7 +342,7 @@ public void Disconnects_peer_if_adding_new_block_fails() [Test] public void Can_handle_new_block_hashes() { - using NewBlockHashesMessage msg = new((Keccak.Zero, 1), (Keccak.Zero, 2)); + using NewBlockHashesMessage msg = new((Keccak.Zero, 1UL), (Keccak.Zero, 2UL)); HandleIncomingStatusMessage(); HandleZeroMessage(msg, Eth62MessageCode.NewBlockHashes); } @@ -350,7 +350,7 @@ public void Can_handle_new_block_hashes() [Test] public void Should_disconnect_peer_sending_new_block_hashes_in_PoS() { - using NewBlockHashesMessage msg = new((Keccak.Zero, 1), (Keccak.Zero, 2)); + using NewBlockHashesMessage msg = new((Keccak.Zero, 1UL), (Keccak.Zero, 2UL)); _gossipPolicy.ShouldDisconnectGossipingNodes.Returns(true); diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/NewBlockHashesMessageSerializerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/NewBlockHashesMessageSerializerTests.cs index 9c1b059c660c..bdf44aa21b7c 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/NewBlockHashesMessageSerializerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V62/NewBlockHashesMessageSerializerTests.cs @@ -13,7 +13,7 @@ public class NewBlockHashesMessageSerializerTests [Test] public void Roundtrip() { - using NewBlockHashesMessage message = new((Keccak.Compute("1"), 1), (Keccak.Compute("2"), 2)); + using NewBlockHashesMessage message = new((Keccak.Compute("1"), 1UL), (Keccak.Compute("2"), 2UL)); NewBlockHashesMessageSerializer serializer = new(); SerializerTester.TestZero(serializer, message); } diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs index 2c8f7704551b..f042d587c576 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs @@ -111,7 +111,7 @@ public void should_send_up_to_MaxCount_hashes_in_one_NewPooledTransactionHashesM for (int i = 0; i < txCount; i++) { - txs[i] = Build.A.Transaction.WithNonce((UInt256)i).SignedAndResolved().TestObject; + txs[i] = Build.A.Transaction.WithNonce((ulong)i).SignedAndResolved().TestObject; } _handler.SendNewTransactions(txs, false); @@ -131,7 +131,7 @@ public void should_send_more_than_MaxCount_hashes_in_more_than_one_NewPooledTran for (int i = 0; i < txCount; i++) { - txs[i] = Build.A.Transaction.WithNonce((UInt256)i).SignedAndResolved().TestObject; + txs[i] = Build.A.Transaction.WithNonce((ulong)i).SignedAndResolved().TestObject; } _handler.SendNewTransactions(txs, false); diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs index fd7cec96f28c..53cd69de0883 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs @@ -201,7 +201,7 @@ public void should_send_up_to_MaxCount_hashes_in_one_NewPooledTransactionHashesM for (int i = 0; i < txCount; i++) { - txs[i] = Build.A.Transaction.WithNonce((UInt256)i).SignedAndResolved().TestObject; + txs[i] = Build.A.Transaction.WithNonce((ulong)i).SignedAndResolved().TestObject; } _handler.SendNewTransactions(txs, false); @@ -215,7 +215,7 @@ public void should_send_up_to_MaxCount_hashes_in_one_NewPooledTransactionHashesM [Test] public void should_send_blob_tx_announcement_in_NewPooledTransactionHashesMessage68() { - Transaction tx = Build.A.Transaction.WithNonce((UInt256)0).WithShardBlobTxTypeAndFields().SignedAndResolved().TestObject; + Transaction tx = Build.A.Transaction.WithNonce(0UL).WithShardBlobTxTypeAndFields().SignedAndResolved().TestObject; _handler.SendNewTransaction(tx); @@ -239,7 +239,7 @@ public void should_send_more_than_MaxCount_hashes_in_more_than_one_NewPooledTran for (int i = 0; i < txCount; i++) { - txs[i] = Build.A.Transaction.WithNonce((UInt256)i).SignedAndResolved().TestObject; + txs[i] = Build.A.Transaction.WithNonce((ulong)i).SignedAndResolved().TestObject; } _handler.SendNewTransactions(txs, false); diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandlerTests.cs index 2326b185e7ba..160e896e2271 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandlerTests.cs @@ -67,7 +67,7 @@ public void Setup() _syncManager.Head.Returns(_genesisBlock.Header); _syncManager.Genesis.Returns(_genesisBlock.Header); _syncManager.FindHeader(Arg.Any()).Returns(_genesisBlock.Header); - _syncManager.LowestBlock.Returns(0); + _syncManager.LowestBlock.Returns(0UL); _timerFactory = Substitute.For(); _txGossipPolicy = Substitute.For(); _txGossipPolicy.ShouldListenToGossipedTransactions.Returns(true); @@ -279,15 +279,15 @@ public void Should_handle_BlockRangeUpdate() private static IEnumerable InvalidBlockRangeUpdates() { - yield return new TestCaseData(2L, 1L, Keccak.Compute("2")).SetName("earliest_after_latest"); - yield return new TestCaseData(1L, 2L, Keccak.Zero).SetName("empty_hash"); + yield return new TestCaseData(2UL, 1UL, Keccak.Compute("2")).SetName("earliest_after_latest"); + yield return new TestCaseData(1UL, 2UL, Keccak.Zero).SetName("empty_hash"); } [TestCaseSource(nameof(InvalidBlockRangeUpdates))] - public void Should_disconnect_on_invalid_BlockRangeUpdate(long earliestBlock, long latestBlock, Hash256 latestBlockHash) + public void Should_disconnect_on_invalid_BlockRangeUpdate(ulong earliestBlock, ulong latestBlock, Hash256 latestBlockHash) { HandleIncomingStatusMessage(); - long headNumber = _handler.HeadNumber; + ulong headNumber = _handler.HeadNumber; Hash256? headHash = _handler.HeadHash; using BlockRangeUpdateMessage msg = new() diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandlerTests.cs index 7e9771bbfbfc..7b36b40593d5 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandlerTests.cs @@ -52,8 +52,8 @@ public class Eth70ProtocolHandlerTests [SetUp] public void Setup() { - SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = (ulong)2.MiB; - SyncPeerProtocolHandlerBase.HardOutgoingReceiptsMessageSizeLimit = (ulong)10.MiB; + SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = 2UL.MiB; + SyncPeerProtocolHandlerBase.HardOutgoingReceiptsMessageSizeLimit = 10UL.MiB; NetworkDiagTracer.IsEnabled = true; _session = Substitute.For(); @@ -67,7 +67,7 @@ public void Setup() _syncManager.Head.Returns(_genesisBlock.Header); _syncManager.Genesis.Returns(_genesisBlock.Header); _syncManager.FindHeader(Arg.Any()).Returns(_genesisBlock.Header); - _syncManager.LowestBlock.Returns(0); + _syncManager.LowestBlock.Returns(0UL); _timerFactory = Substitute.For(); _txGossipPolicy = Substitute.For(); _txGossipPolicy.ShouldListenToGossipedTransactions.Returns(true); @@ -124,8 +124,8 @@ public void Default_size_limits_match_eth_protocol_limits() [Test] public void Should_mark_last_block_incomplete_when_truncated() { - SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = (ulong)1.MB; - SyncPeerProtocolHandlerBase.HardOutgoingReceiptsMessageSizeLimit = (ulong)1.MB; + SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = 1UL.MB; + SyncPeerProtocolHandlerBase.HardOutgoingReceiptsMessageSizeLimit = 1UL.MB; const int receiptCount = 20000; using GetReceiptsMessage70 request = new(1111, 0, new[] { Keccak.Zero }.ToPooledList()); @@ -669,7 +669,7 @@ public async Task Should_validate_receipt_cumulative_against_header_gas_used_by_ BlockHeader header = Build.A.BlockHeader .WithHash(blockHash) .WithNumber(1) - .WithGasUsed(GasCostOf.Transaction * headerGasUsedMultiplier) + .WithGasUsed(GasCostOf.Transaction * (ulong)headerGasUsedMultiplier) .TestObject; _syncManager.FindHeader(blockHash).Returns(header); @@ -681,7 +681,7 @@ public async Task Should_validate_receipt_cumulative_against_header_gas_used_by_ TxReceipt[] receipts = new TxReceipt[receiptGasUsedMultiplier]; for (int i = 0; i < receipts.Length; i++) { - receipts[i] = new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (i + 1), Logs = [] }; + receipts[i] = new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (ulong)(i + 1), Logs = [] }; } _session.When(s => s.DeliverMessage(Arg.Any())).Do(call => @@ -746,7 +746,7 @@ public async Task Should_return_immediately_when_peer_returns_fewer_blocks_than_ int toReturn = Math.Min(7, actualRequested); TxReceipt[][] payload = Enumerable.Range(0, toReturn) - .Select(i => new[] { new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (i + 1), Logs = [] } }) + .Select(i => new[] { new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (ulong)(i + 1), Logs = [] } }) .ToArray(); ReceiptsMessage70 response = new(sent.RequestId, payload.ToPooledList(), lastBlockIncomplete: false); @@ -1035,7 +1035,7 @@ public void Should_split_large_block_when_exceeding_hard_limit() [Test] public void Should_not_split_small_block_when_hitting_limit_single_block() { - SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = (ulong)10.MB; + SyncPeerProtocolHandlerBase.SoftOutgoingMessageSizeLimit = 10UL.MB; TxReceipt[] smallBlockReceipts = [ @@ -1080,20 +1080,20 @@ private static TxReceipt[] BuildSequentialReceipts(int count) TxReceipt[] receipts = new TxReceipt[count]; for (int i = 0; i < receipts.Length; i++) { - receipts[i] = new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (i + 1), Logs = [] }; + receipts[i] = new TxReceipt { GasUsedTotal = GasCostOf.Transaction * (ulong)(i + 1), Logs = [] }; } return receipts; } - private static TxReceipt BuildReceiptWithLogData(long gasUsedTotal, int logDataSize) => + private static TxReceipt BuildReceiptWithLogData(ulong gasUsedTotal, int logDataSize) => new() { GasUsedTotal = gasUsedTotal, Logs = [new LogEntry(TestItem.AddressA, new byte[logDataSize], [])] }; - private void SetupBlockMetadata(Hash256 blockHash, long gasLimit, long gasUsed, params long[] txGasLimits) + private void SetupBlockMetadata(Hash256 blockHash, ulong gasLimit, ulong gasUsed, params ulong[] txGasLimits) { Transaction[] transactions = new Transaction[txGasLimits.Length]; for (int i = 0; i < txGasLimits.Length; i++) @@ -1147,8 +1147,8 @@ private static IEnumerable SingleBlockReceiptResponseCases() public sealed record InvalidPartialContinuationCase( Hash256[] RequestedHashes, Dictionary Responses, - long FirstBlockGasUsed, - long? SecondBlockGasUsed, + ulong FirstBlockGasUsed, + ulong? SecondBlockGasUsed, string ExpectedExceptionMessage); public sealed record ReceiptsPageResponse(TxReceipt[][] Receipts, bool LastBlockIncomplete); diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V71/Eth71ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V71/Eth71ProtocolHandlerTests.cs index 0c1958efd1f7..66931dbd4273 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V71/Eth71ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V71/Eth71ProtocolHandlerTests.cs @@ -67,7 +67,7 @@ public void Setup() _genesisBlock = Build.A.Block.Genesis.TestObject; _syncManager.Head.Returns(_genesisBlock.Header); _syncManager.Genesis.Returns(_genesisBlock.Header); - _syncManager.LowestBlock.Returns(0); + _syncManager.LowestBlock.Returns(0UL); _timerFactory = Substitute.For(); _txGossipPolicy = Substitute.For(); _txGossipPolicy.ShouldListenToGossipedTransactions.Returns(true); diff --git a/src/Nethermind/Nethermind.Network/ForkInfo.cs b/src/Nethermind/Nethermind.Network/ForkInfo.cs index 20b90362bd80..29d59ddb301b 100644 --- a/src/Nethermind/Nethermind.Network/ForkInfo.cs +++ b/src/Nethermind/Nethermind.Network/ForkInfo.cs @@ -65,7 +65,8 @@ private static ulong GetNextActivation(int index, ForkActivation[] transitionAct static ulong GetActivation(ForkActivation forkActivation) => GetActivationPrimitive(forkActivation.Timestamp, 4UL) - ?? (ulong)GetActivationPrimitive(forkActivation.BlockNumber, 4L); + ?? GetActivationPrimitive(forkActivation.BlockNumber, 4UL) + ?? 0UL; index += 1; return index < transitionActivations.Length @@ -73,7 +74,7 @@ static ulong GetActivation(ForkActivation forkActivation) => : 0; } - public ForkId GetForkId(long headNumber, ulong headTimestamp) + public ForkId GetForkId(ulong headNumber, ulong headTimestamp) { EnsureInitialized(); @@ -117,7 +118,7 @@ public ValidationResult ValidateForkId(ForkId peerId, BlockHeader? head) && (forkIsLast || IsTimestamp(found.Id.Next)) && (peerForkIsLast || IsTimestamp(peerId.Next)); - ulong headActivation = usingTimestamp ? head.Timestamp : (ulong)head.Number; + ulong headActivation = usingTimestamp ? head.Timestamp : head.Number; if (found.Id.Next != peerId.Next) // if the next fork is different { diff --git a/src/Nethermind/Nethermind.Network/IForkInfo.cs b/src/Nethermind/Nethermind.Network/IForkInfo.cs index ed506a4a5349..669ddc37650f 100644 --- a/src/Nethermind/Nethermind.Network/IForkInfo.cs +++ b/src/Nethermind/Nethermind.Network/IForkInfo.cs @@ -8,7 +8,7 @@ namespace Nethermind.Network; public interface IForkInfo { - ForkId GetForkId(long headNumber, ulong headTimestamp); + ForkId GetForkId(ulong headNumber, ulong headTimestamp); /// /// Verify that the forkid from peer matches our forks. diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs index 55433aca46e9..5c751f68d6e6 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs @@ -40,7 +40,7 @@ public abstract class SyncPeerProtocolHandlerBase : ZeroProtocolHandlerBase, ISy public virtual bool IncludeInTxPool => true; protected ISyncServer SyncServer { get; } - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public Hash256 HeadHash { get; set; } // this means that we know what the number, hash, and total diff of the head block is @@ -110,7 +110,7 @@ async Task ISyncPeer.GetBlockBodies(IReadOnlyList blo token); } - async Task> ISyncPeer.GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) + async Task> ISyncPeer.GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) { if (maxBlocks == 0) { diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs index b9bae4671a4d..51c534b7a8a9 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs @@ -302,10 +302,10 @@ private void PrepareAndSubmitTransaction(Transaction tx, bool isTrace) private void Handle(NewBlockHashesMessage newBlockHashes) { - (Hash256, long)[] blockHashes = newBlockHashes.BlockHashes; + (Hash256, ulong)[] blockHashes = newBlockHashes.BlockHashes; for (int i = 0; i < blockHashes.Length; i++) { - (Hash256 hash, long number) = blockHashes[i]; + (Hash256 hash, ulong number) = blockHashes[i]; SyncServer.HintBlock(hash, number, this); } } @@ -381,7 +381,7 @@ private void SendNewBlock(Block block) Send(msg); } - private void HintNewBlock(Hash256 blockHash, long number) + private void HintNewBlock(Hash256 blockHash, ulong number) { if (Logger.IsTrace) Logger.Trace($"OUT {Counter:D5} HintBlock to {Node:c}"); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessage.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessage.cs index 8e178a1353e9..f3fa824f69fe 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessage.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessage.cs @@ -13,7 +13,7 @@ public class GetBlockHeadersMessage : P2PMessage public override int PacketType => Eth62MessageCode.GetBlockHeaders; public override string Protocol => "eth"; - public long StartBlockNumber { get; set; } + public ulong StartBlockNumber { get; set; } public Hash256? StartBlockHash { get; set; } public long MaxHeaders { get; set; } public long Skip { get; set; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessageSerializer.cs index f4fd0204bb05..e83b3515126c 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/GetBlockHeadersMessageSerializer.cs @@ -23,7 +23,7 @@ public static GetBlockHeadersMessage Deserialize(ref Rlp.ValueDecoderContext ctx } else { - message.StartBlockNumber = (long)new UInt256(startingBytes, true); + message.StartBlockNumber = (ulong)new UInt256(startingBytes, true); } message.MaxHeaders = ctx.DecodeUInt(); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessage.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessage.cs index 3b70686905f0..ef4e52187b2b 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessage.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessage.cs @@ -6,12 +6,12 @@ namespace Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages { - public class NewBlockHashesMessage(params (Hash256, long)[] blockHashes) : P2PMessage + public class NewBlockHashesMessage(params (Hash256, ulong)[] blockHashes) : P2PMessage { public override int PacketType => Eth62MessageCode.NewBlockHashes; public override string Protocol => "eth"; - public (Hash256, long)[] BlockHashes { get; } = blockHashes; + public (Hash256, ulong)[] BlockHashes { get; } = blockHashes; public override string ToString() => $"{nameof(NewBlockHashesMessage)}({BlockHashes?.Length ?? 0})"; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs index a38b40947dc7..a22ec1806946 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs @@ -47,12 +47,12 @@ public int GetLength(NewBlockHashesMessage message, out int contentLength) private static NewBlockHashesMessage Deserialize(ref Rlp.ValueDecoderContext ctx) { - (Hash256, long)[] blockHashes = ctx.DecodeArray(static (ref Rlp.ValueDecoderContext c) => + (Hash256, ulong)[] blockHashes = ctx.DecodeArray(static (ref Rlp.ValueDecoderContext c) => { int length = c.ReadSequenceLength(); int checkPosition = c.Position + length; - (Hash256, long) result = (c.DecodeKeccak(), (long)c.DecodeUInt256()); + (Hash256, ulong) result = (c.DecodeKeccak(), (ulong)c.DecodeUInt256()); c.Check(checkPosition); return result; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs index 46de9281c878..c3dfdd831cf4 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs @@ -38,7 +38,7 @@ public void Serialize(IByteBuffer byteBuffer, ReceiptsMessage message) stream.StartSequence(contentLength); // Track the last ‐ seen block number & its RLP behavior - long lastBlockNumber = -1; + ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet RlpBehaviors behaviors = RlpBehaviors.None; foreach (TxReceipt?[]? txReceipts in message.TxReceipts.AsSpan()) @@ -148,7 +148,7 @@ private int GetInnerLength(TxReceipt?[]? txReceipts) int contentLength = 0; // Track the last‐seen block number and its spec - long lastBlockNumber = -1; + ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet RlpBehaviors behaviors = RlpBehaviors.None; for (int i = 0; i < txReceipts.Length; i++) diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessage.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessage.cs index b36be88abcdb..f0dafb481e71 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessage.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessage.cs @@ -18,12 +18,12 @@ public class BlockRangeUpdateMessage : P2PMessage /// /// Number of the earliest available full block. /// - public long EarliestBlock { get; set; } + public ulong EarliestBlock { get; set; } /// /// Number of the latest available full block number. /// - public long LatestBlock { get; set; } + public ulong LatestBlock { get; set; } /// /// Hash of the latest available full block. diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessageSerializer.cs index af2b9cee5452..5a857fb72cd2 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/BlockRangeUpdateMessageSerializer.cs @@ -32,8 +32,8 @@ private static BlockRangeUpdateMessage Deserialize(ref Rlp.ValueDecoderContext c return new BlockRangeUpdateMessage { - EarliestBlock = ctx.DecodeLong(), - LatestBlock = ctx.DecodeLong(), + EarliestBlock = ctx.DecodeULong(), + LatestBlock = ctx.DecodeULong(), LatestBlockHash = ctx.DecodeKeccak() ?? Hash256.Zero }; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs index fd818ad60b27..406406ea2d2b 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs @@ -35,16 +35,16 @@ public sealed class ReceiptMessageDecoder69(bool skipStateAndStatus = false) : R if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; - txReceipt.GasUsedTotal = ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); } else if (firstItem.Length is >= 1 and <= 4) { - txReceipt.GasUsedTotal = firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Hash256(firstItem); - txReceipt.GasUsedTotal = ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); } int lastCheck = ctx.ReadSequenceLength() + ctx.Position; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs index ee04f63ec5c5..e2e48a8685ae 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs @@ -14,8 +14,8 @@ public class StatusMessage69 : P2PMessage public UInt256 NetworkId { get; set; } public required Hash256 GenesisHash { get; set; } public ForkId ForkId { get; set; } - public long EarliestBlock { get; set; } - public long LatestBlock { get; set; } + public ulong EarliestBlock { get; set; } + public ulong LatestBlock { get; set; } public required Hash256 LatestBlockHash { get; set; } public override int PacketType => Eth69MessageCode.Status; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs index 79baad9d8723..edfe3cd88c5c 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs @@ -56,8 +56,8 @@ private static StatusMessage69 Deserialize(ref Rlp.ValueDecoderContext ctx) NetworkId = ctx.DecodeUInt256(), GenesisHash = ctx.DecodeKeccak() ?? Hash256.Zero, ForkId = DecodeForkId(ref ctx), - EarliestBlock = ctx.DecodeLong(), - LatestBlock = ctx.DecodeLong(), + EarliestBlock = ctx.DecodeULong(), + LatestBlock = ctx.DecodeULong(), LatestBlockHash = ctx.DecodeKeccak() ?? Hash256.Zero }; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs index 611a1d7fb0c2..687f8b37f1fe 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs @@ -169,7 +169,7 @@ private ReceiptsResponse FulfillReceiptsRequest(GetReceiptsMessage70 getReceipts ulong blockReceiptsContentSize = 0; int taken = 0; - long lastBlockNumber = -1; + ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet RlpBehaviors behaviors = RlpBehaviors.None; for (int receiptIndex = startIndex; receiptIndex < receipts.Length; receiptIndex++) { @@ -230,15 +230,15 @@ public override async Task> GetReceipts(IReadOnl { ArrayPoolList aggregated = new(blockHashes.Count); ArrayPoolList? partialReceipts = null; - long partialReceiptsGas = 0; - long partialReceiptsLogsGas = 0; + ulong partialReceiptsGas = 0; + ulong partialReceiptsLogsGas = 0; ulong partialReceiptsContentSize = 0; int blockIndex = 0; int firstBlockReceiptIndex = 0; ulong totalResponseSize = 0; - using ArrayPoolList expectedGasUsed = new(blockHashes.Count); - using ArrayPoolList blockGasLimits = new(blockHashes.Count); + using ArrayPoolList expectedGasUsed = new(blockHashes.Count); + using ArrayPoolList blockGasLimits = new(blockHashes.Count); using ArrayPoolList blockTransactions = new(blockHashes.Count); using ArrayPoolList receiptRlpBehaviors = new(blockHashes.Count); using ArrayPoolList validateReceiptGasUpperBoundAgainstHeader = new(blockHashes.Count); @@ -315,8 +315,8 @@ public override async Task> GetReceipts(IReadOnl bool isFirst = i == 0; bool isLast = i == txReceipts.Length - 1; TxReceipt[] blockReceipts = txReceipts[i] ?? throw new SubprotocolException("Unexpected null receipt block payload"); - long blockExpectedGasUsed = expectedGasUsed[blockIndex]; - long blockGasLimit = blockGasLimits[blockIndex]; + ulong blockExpectedGasUsed = expectedGasUsed[blockIndex]; + ulong blockGasLimit = blockGasLimits[blockIndex]; Transaction[]? transactions = blockTransactions[blockIndex]; RlpBehaviors receiptBehaviors = receiptRlpBehaviors[blockIndex]; bool validateGasUpperBound = validateReceiptGasUpperBoundAgainstHeader[blockIndex]; @@ -422,7 +422,7 @@ private static TxReceipt[] CopyReceipts(TxReceipt[] receipts, int startIndex, in private ulong GetBlockReceiptsSize(TxReceipt[] receipts, int startIndex) { ulong receiptsContentSize = 0; - long lastBlockNumber = -1; + ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet RlpBehaviors behaviors = RlpBehaviors.None; for (int i = startIndex; i < receipts.Length; i++) { @@ -446,7 +446,7 @@ private static ulong GetEth70ReceiptsResponseSize(ulong receiptsContentSize, lon return GetRlpSequenceSize(responseContentSize); } - private ulong GetReceiptSize(TxReceipt receipt, ref long lastBlockNumber, ref RlpBehaviors behaviors) + private ulong GetReceiptSize(TxReceipt receipt, ref ulong lastBlockNumber, ref RlpBehaviors behaviors) { if (receipt.BlockNumber != lastBlockNumber) { @@ -486,27 +486,27 @@ private readonly struct ReceiptsResponse(IOwnedReadOnlyList txRecei public bool LastBlockIncomplete { get; } = lastBlockIncomplete; } - private readonly struct ReceiptsValidationResult(long gasUsedTotal, long logsGas, ulong receiptsContentSize) + private readonly struct ReceiptsValidationResult(ulong gasUsedTotal, ulong logsGas, ulong receiptsContentSize) { - public long GasUsedTotal { get; } = gasUsedTotal; + public ulong GasUsedTotal { get; } = gasUsedTotal; - public long LogsGas { get; } = logsGas; + public ulong LogsGas { get; } = logsGas; public ulong ReceiptsContentSize { get; } = receiptsContentSize; } private ReceiptsValidationResult ValidateBlockReceipts( TxReceipt[] blockReceipts, - long expectedGasUsed, - long blockGasLimit, + ulong expectedGasUsed, + ulong blockGasLimit, Transaction[]? transactions, RlpBehaviors receiptBehaviors, bool validateReceiptGasUpperBoundAgainstHeader, bool validateReceiptGasEqualToHeader, int firstReceiptIndex, bool isCompleteSegment, - long previousGasUsed, - long previousLogsGas, + ulong previousGasUsed, + ulong previousLogsGas, ulong previousReceiptsContentSize) { if (blockReceipts is { Length: 0 }) @@ -518,7 +518,7 @@ private ReceiptsValidationResult ValidateBlockReceipts( } previousGasUsed = GetPreviousGasUsedForSegment(firstReceiptIndex, previousGasUsed); - long logsGas = previousLogsGas; + ulong logsGas = previousLogsGas; ulong receiptsContentSize = previousReceiptsContentSize; for (int i = 0; i < blockReceipts.Length; i++) @@ -548,9 +548,9 @@ private static void ValidateEmptyReceiptsSegment(int firstReceiptIndex, bool isC } } - private static long GetPreviousGasUsedForSegment(int firstReceiptIndex, long previousGasUsed) + private static ulong GetPreviousGasUsedForSegment(int firstReceiptIndex, ulong previousGasUsed) { - long minimalPreviousGasUsed = checked((long)firstReceiptIndex * GasCostOf.Transaction); + ulong minimalPreviousGasUsed = checked((ulong)firstReceiptIndex * GasCostOf.Transaction); return Math.Max(previousGasUsed, minimalPreviousGasUsed); } @@ -560,14 +560,14 @@ private static long GetPreviousGasUsedForSegment(int firstReceiptIndex, long pre private static ulong GetReceiptSize(TxReceipt receipt, RlpBehaviors behaviors) => (ulong)ReceiptMessageDecoder.GetLength(receipt, behaviors); - private static long ValidateReceiptGas(TxReceipt receipt, long previousGasUsed) + private static ulong ValidateReceiptGas(TxReceipt receipt, ulong previousGasUsed) { - long receiptGasUsed = GetReceiptGasUsed(receipt, previousGasUsed); + ulong receiptGasUsed = GetReceiptGasUsed(receipt, previousGasUsed); ValidateReceiptGasCoversIntrinsicCost(receiptGasUsed); return receipt.GasUsedTotal; } - private static long GetReceiptGasUsed(TxReceipt receipt, long previousGasUsed) + private static ulong GetReceiptGasUsed(TxReceipt receipt, ulong previousGasUsed) { if (receipt.GasUsedTotal < previousGasUsed) { @@ -577,7 +577,7 @@ private static long GetReceiptGasUsed(TxReceipt receipt, long previousGasUsed) return receipt.GasUsedTotal - previousGasUsed; } - private static void ValidateReceiptGasCoversIntrinsicCost(long receiptGasUsed) + private static void ValidateReceiptGasCoversIntrinsicCost(ulong receiptGasUsed) { if (GasCostOf.Transaction > receiptGasUsed) { @@ -585,7 +585,7 @@ private static void ValidateReceiptGasCoversIntrinsicCost(long receiptGasUsed) } } - private static long AddReceiptLogsGas(long logsGas, TxReceipt receipt) + private static ulong AddReceiptLogsGas(ulong logsGas, TxReceipt receipt) { if (receipt.Logs is null) { @@ -596,7 +596,7 @@ private static long AddReceiptLogsGas(long logsGas, TxReceipt receipt) { int topics = log.Topics?.Length ?? 0; int dataLength = log.Data?.Length ?? 0; - logsGas = checked(logsGas + GasCostOf.Log + topics * GasCostOf.LogTopic + dataLength * GasCostOf.LogData); + logsGas = checked(logsGas + GasCostOf.Log + (ulong)topics * GasCostOf.LogTopic + (ulong)dataLength * GasCostOf.LogData); } return logsGas; @@ -647,9 +647,9 @@ private static void ValidateReceiptSizeAgainstTransactionGasLimit( } } - private static void ValidateTotalReceiptsSizeAgainstBlockGasLimit(ulong receiptsContentSize, long blockGasLimit) + private static void ValidateTotalReceiptsSizeAgainstBlockGasLimit(ulong receiptsContentSize, ulong blockGasLimit) { - if (blockGasLimit <= 0) + if (blockGasLimit == 0) { return; } @@ -662,13 +662,12 @@ private static void ValidateTotalReceiptsSizeAgainstBlockGasLimit(ulong receipts } } - private static ulong GetReceiptSizeLimit(long gasLimit) => - gasLimit <= 0 ? 0 : (ulong)gasLimit / 8; + private static ulong GetReceiptSizeLimit(ulong gasLimit) => gasLimit / 8; private static void ValidateSegmentGasAgainstHeader( - long actualGasUsed, - long logsGas, - long expectedGasUsed, + ulong actualGasUsed, + ulong logsGas, + ulong expectedGasUsed, bool isCompleteSegment, bool validateReceiptGasUpperBoundAgainstHeader, bool validateReceiptGasEqualToHeader) @@ -680,7 +679,7 @@ private static void ValidateSegmentGasAgainstHeader( if (isCompleteSegment) { - long gasUpperBound = validateReceiptGasUpperBoundAgainstHeader && expectedGasUsed > 0 ? expectedGasUsed : actualGasUsed; + ulong gasUpperBound = validateReceiptGasUpperBoundAgainstHeader && expectedGasUsed > 0 ? expectedGasUsed : actualGasUsed; if (logsGas > gasUpperBound) { throw new SubprotocolException("Logs gas exceeds block gas used"); diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin.Test/AsyncFileWriteQueueTests.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin.Test/AsyncFileWriteQueueTests.cs index 7f36d0565a28..42d9a4fdb513 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin.Test/AsyncFileWriteQueueTests.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin.Test/AsyncFileWriteQueueTests.cs @@ -12,7 +12,7 @@ public class AsyncFileWriteQueueTests private string _tempDir = null!; private AsyncFileWriteQueue _queue = null!; - private static PerBlockTraceOutput CreateTrace(long blockNumber) => new() + private static PerBlockTraceOutput CreateTrace(ulong blockNumber) => new() { Metadata = new PerBlockMetadata { BlockNumber = blockNumber }, OpcodeCounts = new Dictionary { [0x00] = 1 } diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/CumulativeTraceOutput.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/CumulativeTraceOutput.cs index 498942f0159d..688cdb2904d8 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/CumulativeTraceOutput.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/CumulativeTraceOutput.cs @@ -35,13 +35,13 @@ public sealed class CumulativeMetadata /// Gets or sets the first block number included in the cumulative count. /// [JsonPropertyName("firstBlock")] - public required long FirstBlock { get; init; } + public required ulong FirstBlock { get; init; } /// /// Gets or sets the last block number included in the cumulative count. /// [JsonPropertyName("lastBlock")] - public required long LastBlock { get; init; } + public required ulong LastBlock { get; init; } /// /// Gets or sets the total number of blocks processed. @@ -95,14 +95,14 @@ public sealed class CumulativeMetadata /// [JsonPropertyName("configuredStartBlock")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public long? ConfiguredStartBlock { get; init; } + public ulong? ConfiguredStartBlock { get; init; } /// /// Gets or sets the configured end block (if range was specified). /// [JsonPropertyName("configuredEndBlock")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public long? ConfiguredEndBlock { get; init; } + public ulong? ConfiguredEndBlock { get; init; } /// /// Gets or sets warnings encountered during tracing. diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/PerBlockTraceOutput.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/PerBlockTraceOutput.cs index 0e47366a83a7..2530af8dcd14 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/PerBlockTraceOutput.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/PerBlockTraceOutput.cs @@ -35,7 +35,7 @@ public sealed class PerBlockMetadata /// Gets or sets the block number. /// [JsonPropertyName("blockNumber")] - public required long BlockNumber { get; init; } + public required ulong BlockNumber { get; init; } /// /// Gets or sets the parent block hash. @@ -49,7 +49,7 @@ public sealed class PerBlockMetadata /// [JsonPropertyName("timestamp")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public long? Timestamp { get; init; } + public ulong? Timestamp { get; init; } /// /// Gets or sets the number of transactions in the block. @@ -63,7 +63,7 @@ public sealed class PerBlockMetadata /// [JsonPropertyName("gasUsed")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public long? GasUsed { get; init; } + public ulong? GasUsed { get; init; } /// /// Gets or sets the UTC timestamp when this block trace was created. diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/TraceMetadata.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/TraceMetadata.cs index 834f354fb94c..c5c085fb63cf 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/TraceMetadata.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Output/TraceMetadata.cs @@ -14,13 +14,13 @@ public sealed class TraceMetadata /// Gets or sets the first block number traced (inclusive). /// [JsonPropertyName("startBlock")] - public required long StartBlock { get; init; } + public required ulong StartBlock { get; init; } /// /// Gets or sets the last block number traced (inclusive). /// [JsonPropertyName("endBlock")] - public required long EndBlock { get; init; } + public required ulong EndBlock { get; init; } /// /// Gets or sets the tracing mode used (RealTime or Retrospective). @@ -63,5 +63,5 @@ public sealed class TraceMetadata /// [JsonPropertyName("skippedBlocks")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public long[]? SkippedBlocks { get; init; } + public ulong[]? SkippedBlocks { get; init; } } diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs index 1ab35eed4957..bfbaad2d9fcc 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs @@ -74,12 +74,12 @@ public TraceConfiguration( /// /// Gets the effective start block after resolving configuration. /// - public long EffectiveStartBlock { get; init; } + public ulong EffectiveStartBlock { get; init; } /// /// Gets the effective end block after resolving configuration. /// - public long EffectiveEndBlock { get; init; } + public ulong EffectiveEndBlock { get; init; } /// /// Gets the list of warnings generated during configuration resolution. @@ -111,22 +111,22 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu config.MaxDegreeOfParallelism); // Resolve effective block range - long effectiveStart; - long effectiveEnd; + ulong effectiveStart; + ulong effectiveEnd; List warnings = []; // Check for conflicting parameters if (config.StartBlock.HasValue && config.EndBlock.HasValue && config.RecentBlocks.HasValue) { warnings.Add("Both explicit range (StartBlock/EndBlock) and RecentBlocks specified. Using explicit range, ignoring RecentBlocks."); - effectiveStart = config.StartBlock.Value; - effectiveEnd = config.EndBlock.Value; + effectiveStart = (ulong)config.StartBlock.Value; + effectiveEnd = (ulong)config.EndBlock.Value; } else if (config.StartBlock.HasValue && config.EndBlock.HasValue) { // Explicit range - effectiveStart = config.StartBlock.Value; - effectiveEnd = config.EndBlock.Value; + effectiveStart = (ulong)config.StartBlock.Value; + effectiveEnd = (ulong)config.EndBlock.Value; } else if (config.RecentBlocks.HasValue) { @@ -135,16 +135,18 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu if (mode == TracingMode.RealTime) { // RealTime: next N blocks starting from current chain tip + 1 - effectiveStart = currentChainTip + 1; - effectiveEnd = currentChainTip + config.RecentBlocks.Value; + effectiveStart = (ulong)currentChainTip + 1; + effectiveEnd = (ulong)currentChainTip + (ulong)config.RecentBlocks.Value; } else { // Retrospective and RetrospectiveExecution: recent N blocks from chain tip - effectiveEnd = currentChainTip; - effectiveStart = Math.Max(0, currentChainTip - config.RecentBlocks.Value + 1); + effectiveEnd = (ulong)currentChainTip; + effectiveStart = currentChainTip >= config.RecentBlocks.Value - 1 + ? (ulong)(currentChainTip - config.RecentBlocks.Value + 1) + : 0; - if (effectiveStart == 0 && config.RecentBlocks.Value > currentChainTip + 1) + if (effectiveStart == 0 && config.RecentBlocks.Value > currentChainTip + 1L) { warnings.Add($"Requested {config.RecentBlocks.Value} blocks but only {currentChainTip + 1} available. Tracing all available blocks."); } @@ -153,15 +155,15 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu else if (config.StartBlock.HasValue) { // Start block only, use current chain tip as end - effectiveStart = config.StartBlock.Value; - effectiveEnd = currentChainTip; + effectiveStart = (ulong)config.StartBlock.Value; + effectiveEnd = (ulong)currentChainTip; warnings.Add($"Only StartBlock specified, using current chain tip ({currentChainTip}) as EndBlock."); } else if (config.EndBlock.HasValue) { // End block only, use 0 as start effectiveStart = 0; - effectiveEnd = config.EndBlock.Value; + effectiveEnd = (ulong)config.EndBlock.Value; warnings.Add("Only EndBlock specified, using 0 as StartBlock."); } else diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeBlockTracer.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeBlockTracer.cs index 0174b6f708e4..c4c7e06327f8 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeBlockTracer.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeBlockTracer.cs @@ -93,7 +93,7 @@ internal sealed record OpcodeBlockTrace { public required Hash256 BlockHash { get; init; } public required Hash256 ParentHash { get; init; } - public required long BlockNumber { get; init; } + public required ulong BlockNumber { get; init; } public required ulong Timestamp { get; init; } public required int TransactionCount { get; init; } public required IReadOnlyDictionary Opcodes { get; init; } diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeCountingTxTracer.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeCountingTxTracer.cs index e1bc55a6bc6f..22bef7c71766 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeCountingTxTracer.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeCountingTxTracer.cs @@ -30,7 +30,7 @@ public long TotalOpcodes } } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) => + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) => _opcodeCounters[(byte)opcode]++; public void AccumulateInto(long[] aggregate) diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs index b14fdc490090..50f3af6b5e84 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs @@ -39,7 +39,7 @@ public sealed class OpcodeTraceRecorder( private Stopwatch? _stopwatch; private CancellationTokenSource? _cts; private Task? _tracingTask; - private long _lastProcessedBlock; + private ulong _lastProcessedBlock; private bool _isComplete; private ISyncModeSelector? _syncModeSelector; private bool _syncModeWarningLogged; @@ -59,7 +59,7 @@ public Task PrepareAsync(INethermindApi api, CancellationToken cancellationToken try { // Get current chain tip - long currentChainTip = api.BlockTree?.Head?.Number ?? 0; + long currentChainTip = (long)(api.BlockTree?.Head?.Number ?? 0UL); // Parse mode for validation TracingMode mode = TracingMode.RealTime; @@ -105,7 +105,7 @@ public Task PrepareAsync(INethermindApi api, CancellationToken cancellationToken // Initialize progress tracker _progress = new TracingProgress(_traceConfig.EffectiveStartBlock, _traceConfig.EffectiveEndBlock); - _lastProcessedBlock = _traceConfig.EffectiveStartBlock - 1; + _lastProcessedBlock = _traceConfig.EffectiveStartBlock > 0 ? _traceConfig.EffectiveStartBlock - 1 : 0; if (_logger.IsInfo) { @@ -172,21 +172,21 @@ public void Attach(INethermindApi api) // For RealTime mode with Blocks parameter, recalculate range based on current chain tip // This ensures we trace the NEXT N blocks from when the tracer attaches, not from init time - long effectiveStart = _traceConfig.EffectiveStartBlock; - long effectiveEnd = _traceConfig.EffectiveEndBlock; + long effectiveStart = (long)_traceConfig.EffectiveStartBlock; + long effectiveEnd = (long)_traceConfig.EffectiveEndBlock; if (_config.RecentBlocks.HasValue && !_config.StartBlock.HasValue && !_config.EndBlock.HasValue) { - long currentTip = api.BlockTree?.Head?.Number ?? 0; + long currentTip = (long)(api.BlockTree?.Head?.Number ?? 0UL); effectiveStart = currentTip + 1; effectiveEnd = currentTip + _config.RecentBlocks.Value; // Update progress tracker and trace config with new range - _progress = new TracingProgress(effectiveStart, effectiveEnd); + _progress = new TracingProgress((ulong)effectiveStart, (ulong)effectiveEnd); _traceConfig = _traceConfig with { - EffectiveStartBlock = effectiveStart, - EffectiveEndBlock = effectiveEnd + EffectiveStartBlock = (ulong)effectiveStart, + EffectiveEndBlock = (ulong)effectiveEnd }; if (_logger.IsInfo) @@ -195,7 +195,7 @@ public void Attach(INethermindApi api) } } - BlockRange range = new(effectiveStart, effectiveEnd); + BlockRange range = new((ulong)effectiveStart, (ulong)effectiveEnd); _realTimeTracer = new RealTimeTracer( _counter, range, @@ -315,7 +315,7 @@ public Task ExecuteTracingAsync(INethermindApi api) _tracingTask = Task.Run(async () => { - long[]? skippedBlocks = null; + ulong[]? skippedBlocks = null; try { @@ -349,7 +349,7 @@ public Task ExecuteTracingAsync(INethermindApi api) await executionTracer.TraceBlockRangeAsync(range, _progress, _cts.Token).ConfigureAwait(false); - long[] skippedSnapshot = [.. executionTracer.SkippedBlocks]; + ulong[] skippedSnapshot = [.. executionTracer.SkippedBlocks]; if (skippedSnapshot.Length > 0) { Array.Sort(skippedSnapshot); @@ -406,7 +406,7 @@ public Task ExecuteTracingAsync(INethermindApi api) return _tracingTask; } - private void OnBlockCompletedRealTime(long blockNumber) + private void OnBlockCompletedRealTime(ulong blockNumber) { _lastProcessedBlock = blockNumber; _progress?.UpdateProgress(blockNumber); @@ -424,7 +424,7 @@ private void OnBlockCompletedRealTime(long blockNumber) } } - private async Task WriteOutputAsync(long[]? skippedBlocks = null) + private async Task WriteOutputAsync(ulong[]? skippedBlocks = null) { if (_traceConfig is null) { diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RealTimeTracer.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RealTimeTracer.cs index 516035c3c079..b6f2838ddec5 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RealTimeTracer.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RealTimeTracer.cs @@ -17,7 +17,7 @@ public sealed class RealTimeTracer : IAsyncDisposable private readonly OpcodeCounter _counter; private readonly BlockRange _range; private readonly ILogger _logger; - private readonly Action _onBlockCompleted; + private readonly Action _onBlockCompleted; private readonly string _sessionId; // Dual output writers @@ -29,8 +29,9 @@ public sealed class RealTimeTracer : IAsyncDisposable private readonly Stopwatch _stopwatch; private readonly DateTime _startedAt; private readonly SemaphoreSlim _cumulativeWriteLock = new(1, 1); - private long _firstBlock = -1; - private long _lastBlock = -1; + private ulong _firstBlock; + private ulong _lastBlock; + private bool _hasProcessedAnyBlock; private long _totalBlocksProcessed; private bool _rangeCompleted; private Task? _rangeCompleteFinalizeTask; @@ -64,7 +65,7 @@ public RealTimeTracer( BlockRange range, string outputDirectory, string sessionId, - Action onBlockCompleted, + Action onBlockCompleted, ILogManager logManager) { ArgumentNullException.ThrowIfNull(outputDirectory); @@ -113,9 +114,10 @@ internal void OnBlockCompleted(OpcodeBlockTrace trace) // Update tracking state _totalBlocksProcessed++; - if (_firstBlock < 0) + if (!_hasProcessedAnyBlock) { _firstBlock = trace.BlockNumber; + _hasProcessedAnyBlock = true; } _lastBlock = trace.BlockNumber; @@ -172,7 +174,7 @@ private static PerBlockTraceOutput CreatePerBlockOutput(OpcodeBlockTrace trace) { BlockNumber = trace.BlockNumber, ParentHash = trace.ParentHash.ToString(), - Timestamp = (long)trace.Timestamp, + Timestamp = trace.Timestamp, TransactionCount = trace.TransactionCount, GasUsed = null, TracedAt = DateTime.UtcNow @@ -188,8 +190,8 @@ private CumulativeTraceOutput CreateCumulativeOutput(string completionStatus) => { Metadata = new CumulativeMetadata { - FirstBlock = _firstBlock >= 0 ? _firstBlock : _range.StartBlock, - LastBlock = _lastBlock >= 0 ? _lastBlock : _range.StartBlock, + FirstBlock = _hasProcessedAnyBlock ? _firstBlock : _range.StartBlock, + LastBlock = _hasProcessedAnyBlock ? _lastBlock : _range.StartBlock, TotalBlocksProcessed = _totalBlocksProcessed, SessionId = _sessionId, Mode = "RealTime", diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveExecutionTracer.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveExecutionTracer.cs index 96b748a9a6ad..1a026c7d9050 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveExecutionTracer.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveExecutionTracer.cs @@ -32,12 +32,12 @@ public sealed class RetrospectiveExecutionTracer private readonly OpcodeCounter _counter; private readonly ILogger _logger; private readonly int _maxDegreeOfParallelism; - private readonly ConcurrentQueue _skippedBlocks = new(); + private readonly ConcurrentQueue _skippedBlocks = new(); /// /// Gets the block numbers that were skipped due to unavailable state. /// - public IReadOnlyCollection SkippedBlocks => _skippedBlocks; + public IReadOnlyCollection SkippedBlocks => _skippedBlocks; /// /// Initializes a new instance of the class. @@ -91,7 +91,7 @@ public async Task TraceBlockRangeAsync(BlockRange range, TracingProgress progres } // Generate block numbers without int cast to avoid overflow for large ranges - IEnumerable blockNumbers = GenerateBlockNumbers(range); + IEnumerable blockNumbers = GenerateBlockNumbers(range); // Configure parallel processing options ParallelOptions parallelOptions = new() @@ -108,9 +108,9 @@ await Parallel.ForEachAsync(blockNumbers, parallelOptions, (blockNumber, ct) => }).ConfigureAwait(false); } - private static IEnumerable GenerateBlockNumbers(BlockRange range) + private static IEnumerable GenerateBlockNumbers(BlockRange range) { - for (long i = range.StartBlock; i <= range.EndBlock; i++) + for (ulong i = range.StartBlock; i <= range.EndBlock; i++) { yield return i; } @@ -125,7 +125,7 @@ private static IEnumerable GenerateBlockNumbers(BlockRange range) /// The block number to process. /// The progress tracker. /// Cancellation token. - private void ProcessBlockSync(long blockNumber, TracingProgress progress, CancellationToken cancellationToken) + private void ProcessBlockSync(ulong blockNumber, TracingProgress progress, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveTracer.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveTracer.cs index 8ce30f34c615..d27854542863 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveTracer.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/RetrospectiveTracer.cs @@ -51,7 +51,7 @@ public async Task TraceBlockRangeAsync(BlockRange range, TracingProgress progres } // Generate block numbers without int cast to avoid overflow for large ranges - IEnumerable blockNumbers = GenerateBlockNumbers(range); + IEnumerable blockNumbers = GenerateBlockNumbers(range); ParallelOptions parallelOptions = new() { @@ -98,9 +98,9 @@ await Parallel.ForEachAsync(blockNumbers, parallelOptions, (blockNumber, ct) => }).ConfigureAwait(false); } - private static IEnumerable GenerateBlockNumbers(BlockRange range) + private static IEnumerable GenerateBlockNumbers(BlockRange range) { - for (long i = range.StartBlock; i <= range.EndBlock; i++) + for (ulong i = range.StartBlock; i <= range.EndBlock; i++) { yield return i; } diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TracingProgress.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TracingProgress.cs index ae3c39f99dcb..f4ad7e49726f 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TracingProgress.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TracingProgress.cs @@ -6,23 +6,23 @@ namespace Nethermind.OpcodeTracing.Plugin; /// /// Tracks progress during long-running tracing operations. /// -public sealed class TracingProgress(long startBlock, long endBlock) +public sealed class TracingProgress(ulong startBlock, ulong endBlock) { - private long _currentBlock = startBlock - 1; - private readonly long _startBlock = startBlock; - private readonly long _totalBlocks = endBlock - startBlock + 1; + private ulong _currentBlock = startBlock - 1; + private readonly ulong _startBlock = startBlock; + private readonly ulong _totalBlocks = endBlock - startBlock + 1; private readonly DateTime _startTime = DateTime.UtcNow; - private long _lastLoggedBlock = startBlock - 1; + private ulong _lastLoggedBlock = startBlock - 1; /// /// Gets the last fully processed block number. /// - public long CurrentBlock => Interlocked.Read(ref _currentBlock); + public ulong CurrentBlock => Interlocked.Read(ref _currentBlock); /// /// Gets the total number of blocks to process. /// - public long TotalBlocks => _totalBlocks; + public ulong TotalBlocks => _totalBlocks; /// /// Gets the tracing start timestamp (UTC). @@ -43,7 +43,7 @@ public sealed class TracingProgress(long startBlock, long endBlock) /// Updates the current block progress. /// /// The block number that was just completed. - public void UpdateProgress(long blockNumber) => + public void UpdateProgress(ulong blockNumber) => Interlocked.Exchange(ref _currentBlock, blockNumber); /// @@ -52,8 +52,8 @@ public void UpdateProgress(long blockNumber) => /// True if progress should be logged; otherwise, false. public bool ShouldLogProgress() { - long current = CurrentBlock; - long lastLogged = Interlocked.Read(ref _lastLoggedBlock); + ulong current = CurrentBlock; + ulong lastLogged = Interlocked.Read(ref _lastLoggedBlock); if (current - lastLogged >= 1000) { diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRange.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRange.cs index 2c1480818d5d..2d0213afe3f3 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRange.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRange.cs @@ -14,7 +14,7 @@ public readonly record struct BlockRange /// The first block number (inclusive). /// The last block number (inclusive). /// Thrown when end block is less than start block or start block is negative. - public BlockRange(long startBlock, long endBlock) + public BlockRange(ulong startBlock, ulong endBlock) { if (endBlock < startBlock) { @@ -33,15 +33,15 @@ public BlockRange(long startBlock, long endBlock) /// /// Gets the first block number in the range (inclusive). /// - public long StartBlock { get; } + public ulong StartBlock { get; } /// /// Gets the last block number in the range (inclusive). /// - public long EndBlock { get; } + public ulong EndBlock { get; } /// /// Gets the total number of blocks in this range. /// - public long Count => EndBlock - StartBlock + 1; + public ulong Count => EndBlock - StartBlock + 1; } diff --git a/src/Nethermind/Nethermind.Optimism.Test/CL/DepositTransactionBuilderTest.cs b/src/Nethermind/Nethermind.Optimism.Test/CL/DepositTransactionBuilderTest.cs index 750c273bbb75..81f0bddffea8 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/CL/DepositTransactionBuilderTest.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/CL/DepositTransactionBuilderTest.cs @@ -260,7 +260,7 @@ public void DeriveUserDeposits_SuccessfulDeposit() .WithSenderAddress(from) .WithTo(to) .WithValue(depositLogEventV0.Value) - .WithGasLimit((long)depositLogEventV0.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -322,7 +322,7 @@ public void DeriveUserDeposits_IsCreation() .WithSenderAddress(from) .WithTo(null) .WithValue(depositLogEventV0.Value) - .WithGasLimit((long)depositLogEventV0.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -409,7 +409,7 @@ public void DeriveUserDeposits_MultipleReceiptsMixedStatus() .WithSenderAddress(from) .WithTo(to) .WithValue(depositLogEventV0.Value) - .WithGasLimit((long)depositLogEventV0.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -497,7 +497,7 @@ public void DeriveUserDeposits_SuccessfulDepositMultipleLogs() .WithSenderAddress(from) .WithTo(to) .WithValue(depositLogEventV0_0.Value) - .WithGasLimit((long)depositLogEventV0_0.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0_0.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -511,7 +511,7 @@ public void DeriveUserDeposits_SuccessfulDepositMultipleLogs() .WithSenderAddress(from) .WithTo(null) .WithValue(depositLogEventV0_1.Value) - .WithGasLimit((long)depositLogEventV0_1.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0_1.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -683,7 +683,7 @@ public void DeriveUserDeposits_SuccessfulDepositNotAllDepositLogs() .WithSenderAddress(from_0) .WithTo(to_0) .WithValue(depositLogEventV0_0.Value) - .WithGasLimit((long)depositLogEventV0_0.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0_0.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) @@ -697,7 +697,7 @@ public void DeriveUserDeposits_SuccessfulDepositNotAllDepositLogs() .WithSenderAddress(from_1) .WithTo(to_1) .WithValue(depositLogEventV0_1.Value) - .WithGasLimit((long)depositLogEventV0_1.Gas) // WARNING: dangerous cast + .WithGasLimit(depositLogEventV0_1.Gas) .WithGasPrice(0) .WithMaxPriorityFeePerGas(0) .WithMaxFeePerGas(0) diff --git a/src/Nethermind/Nethermind.Optimism.Test/ForkInfoTests.cs b/src/Nethermind/Nethermind.Optimism.Test/ForkInfoTests.cs index e1ac93c82896..980631ccdafc 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/ForkInfoTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/ForkInfoTests.cs @@ -10,8 +10,8 @@ public class ForkInfoTests { private static readonly Hash256 OpMainnetGenesis = new("0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b"); - [TestCase(38_950_927, 1_764_691_201ul, "0xd53e568f", 0ul, "OP Mainnet - Jovian")] - public void Fork_id_and_hash_as_expected(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) => + [TestCase(38_950_927UL, 1_764_691_201ul, "0xd53e568f", 0ul, "OP Mainnet - Jovian")] + public void Fork_id_and_hash_as_expected(ulong head, ulong headTimestamp, string forkHashHex, ulong next, string description) => Network.Test.ForkInfoTests.Test(head, headTimestamp, OpMainnetGenesis, forkHashHex, next, description, "op-mainnet.json.zst"); } diff --git a/src/Nethermind/Nethermind.Optimism.Test/OptimismBaseFeeCalculatorTests.cs b/src/Nethermind/Nethermind.Optimism.Test/OptimismBaseFeeCalculatorTests.cs index bbc8eb8c881a..738fb2e7f27a 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/OptimismBaseFeeCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/OptimismBaseFeeCalculatorTests.cs @@ -16,13 +16,13 @@ public class OptimismBaseFeeCalculatorTests /// /// Tests sourced from /// - [TestCase(15_000_000, 10_000_000, 10u, 2u)] // Target - [TestCase(10_000_000, 9_666_667, 10u, 2u)] // Below - [TestCase(20_000_000, 10_333_333, 10u, 2u)] // Above - [TestCase(3_000_000, 10_000_000, 2u, 10u)] // Target - [TestCase(1_000_000, 6_666_667, 2u, 10u)] // Below - [TestCase(30_000_000, 55_000_000, 2u, 10u)] // Above - public void CalculatesBaseFee_AfterHolocene_UsingExtraDataParameters(long gasUsed, long expectedBaseFee, UInt32 denominator, UInt32 elasticity) + [TestCase(15_000_000UL, 10_000_000, 10u, 2u)] // Target + [TestCase(10_000_000UL, 9_666_667, 10u, 2u)] // Below + [TestCase(20_000_000UL, 10_333_333, 10u, 2u)] // Above + [TestCase(3_000_000UL, 10_000_000, 2u, 10u)] // Target + [TestCase(1_000_000UL, 6_666_667, 2u, 10u)] // Below + [TestCase(30_000_000UL, 55_000_000, 2u, 10u)] // Above + public void CalculatesBaseFee_AfterHolocene_UsingExtraDataParameters(ulong gasUsed, long expectedBaseFee, UInt32 denominator, UInt32 elasticity) { const ulong HoloceneTimestamp = 10_000_000; @@ -52,28 +52,28 @@ public void CalculatesBaseFee_AfterHolocene_UsingExtraDataParameters(long gasUse private static class JovianTest { - public const long GasLimit = 30_000_000; + public const ulong GasLimit = 30_000_000; public const uint Denominator = 50; public const uint Elasticity = 3; - public const long GasTarget = GasLimit / Elasticity; + public const ulong GasTarget = GasLimit / Elasticity; } /// /// Tests sourced from /// - [TestCase(1L, JovianTest.GasTarget - 1_000_000, 0L, Spec.HoloceneTimeStamp, 1_000_000_000, 1L)] - [TestCase(1L, JovianTest.GasTarget, 0L, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] - [TestCase(1L, JovianTest.GasTarget + 1_000_000, 0L, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] - [TestCase(2_000_000_000, JovianTest.GasTarget + 10_000_000, 0L, Spec.JovianTimeStamp, 1_000_000_000, 2_040_000_000)] - [TestCase(1, JovianTest.GasTarget - 1_000_000, 0L, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] - [TestCase(2_097_152, JovianTest.GasTarget - 1_000_000, 0L, Spec.JovianTimeStamp, 2_000_000, 2_092_958)] - [TestCase(10_000, JovianTest.GasTarget - 1, 0L, Spec.JovianTimeStamp, 10_000, 10_000)] - [TestCase(10_000, JovianTest.GasTarget + 1, 0L, Spec.JovianTimeStamp, 10_000, 10_000 + 1)] + [TestCase(1L, JovianTest.GasTarget - 1_000_000, 0UL, Spec.HoloceneTimeStamp, 1_000_000_000, 1L)] + [TestCase(1L, JovianTest.GasTarget, 0UL, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] + [TestCase(1L, JovianTest.GasTarget + 1_000_000, 0UL, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] + [TestCase(2_000_000_000, JovianTest.GasTarget + 10_000_000, 0UL, Spec.JovianTimeStamp, 1_000_000_000, 2_040_000_000)] + [TestCase(1, JovianTest.GasTarget - 1_000_000, 0UL, Spec.JovianTimeStamp, 1_000_000_000, 1_000_000_000)] + [TestCase(2_097_152, JovianTest.GasTarget - 1_000_000, 0UL, Spec.JovianTimeStamp, 2_000_000, 2_092_958)] + [TestCase(10_000, JovianTest.GasTarget - 1, 0UL, Spec.JovianTimeStamp, 10_000, 10_000)] + [TestCase(10_000, JovianTest.GasTarget + 1, 0UL, Spec.JovianTimeStamp, 10_000, 10_000 + 1)] [TestCase(10_000, JovianTest.GasTarget, JovianTest.GasLimit, Spec.HoloceneTimeStamp, 1_000_000, 10_000)] [TestCase(10_000, JovianTest.GasTarget, JovianTest.GasTarget + 1, Spec.JovianTimeStamp, 10_000, 10_000 + 1)] [TestCase(2_000_000_000, JovianTest.GasTarget, JovianTest.GasTarget + 10_000_000, Spec.JovianTimeStamp, 1_000_000_000, 2_040_000_000)] public void CalculatesBaseFee_AfterJovian_Using( - long baseFee, long gasUsed, long blobGasUsed, ulong timestamp, + long baseFee, ulong gasUsed, ulong blobGasUsed, ulong timestamp, long minBaseFee, long expectedBaseFee ) { @@ -97,7 +97,7 @@ public void CalculatesBaseFee_AfterJovian_Using( .WithGasUsed(gasUsed) .WithBlobGasUsed((ulong)blobGasUsed) .WithBaseFee((UInt256)baseFee) - .WithTimestamp((ulong)timestamp) + .WithTimestamp(timestamp) .WithExtraData(extraData) .TestObject; diff --git a/src/Nethermind/Nethermind.Optimism.Test/OptimismHeaderValidatorTests.cs b/src/Nethermind/Nethermind.Optimism.Test/OptimismHeaderValidatorTests.cs index 4f3a8e996df1..4d492f4b2b67 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/OptimismHeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/OptimismHeaderValidatorTests.cs @@ -121,23 +121,23 @@ public void ValidateRequestHash((Hash256? requestHash, Valid isValid) testCase) private static IEnumerable GasLimitTestCases() { - yield return new(1_000, 500, 0, Valid.Always); - yield return new(1_000, 1_000, 0, Valid.Always); - yield return new(1_000, 1_000, 500, Valid.Always); - yield return new(1_000, 1_000, 1_000, Valid.Always); + yield return new(1_000UL, 500UL, 0, Valid.Always); + yield return new(1_000UL, 1_000UL, 0, Valid.Always); + yield return new(1_000UL, 1_000UL, 500, Valid.Always); + yield return new(1_000UL, 1_000UL, 1_000, Valid.Always); - yield return new TestCaseData(1_000, 500, null, Valid.Never).SetName("blobGasUsed missing"); - yield return new TestCaseData(1_000, 1_000, null, Valid.Never).SetName("blobGasUsed missing, gasUsed = gasLimit"); + yield return new TestCaseData(1_000UL, 500UL, null, Valid.Never).SetName("blobGasUsed missing"); + yield return new TestCaseData(1_000UL, 1_000UL, null, Valid.Never).SetName("blobGasUsed missing, gasUsed = gasLimit"); - yield return new TestCaseData(1_000, 1_000 + 1, 500, Valid.Never).SetName("gasUsed > gasLimit"); - yield return new TestCaseData(1_000, 1_000 + 1, 1_000, Valid.Never).SetName("gasUsed > gasLimit, blobGasUsed = gasLimit"); - yield return new TestCaseData(1_000, 1_000 + 1, 1_000 + 1, Valid.Never).SetName("blobGasUsed & gasUsed > gasLimit"); + yield return new TestCaseData(1_000UL, 1_000UL + 1UL, 500, Valid.Never).SetName("gasUsed > gasLimit"); + yield return new TestCaseData(1_000UL, 1_000UL + 1UL, 1_000, Valid.Never).SetName("gasUsed > gasLimit, blobGasUsed = gasLimit"); + yield return new TestCaseData(1_000UL, 1_000UL + 1UL, 1_000 + 1, Valid.Never).SetName("blobGasUsed & gasUsed > gasLimit"); - yield return new TestCaseData(1_000, 1_000, 1_000 + 1, Valid.Before(Spec.JovianTimeStamp)).SetName("blobGasUsed > gasLimit post Jovian"); + yield return new TestCaseData(1_000UL, 1_000UL, 1_000 + 1, Valid.Before(Spec.JovianTimeStamp)).SetName("blobGasUsed > gasLimit post Jovian"); } [TestCaseSource(nameof(GasLimitTestCases))] - public void ValidateGasLimit(int gasLimit, int gasUsed, int? blobGasUsed, Valid isValid) + public void ValidateGasLimit(ulong gasLimit, ulong gasUsed, int? blobGasUsed, Valid isValid) { (BlockHeader genesis, BlockHeader header) = BuildHeaders(b => b .WithGasLimit(gasLimit) diff --git a/src/Nethermind/Nethermind.Optimism.Test/Rpc/DepositTransactionForRpcTests.cs b/src/Nethermind/Nethermind.Optimism.Test/Rpc/DepositTransactionForRpcTests.cs index 1a680f07bbdf..fe3709a7d833 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/Rpc/DepositTransactionForRpcTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/Rpc/DepositTransactionForRpcTests.cs @@ -104,7 +104,7 @@ public void Accepts_valid_transaction_missing_field((string missingField, string Assert.That(toTransaction, Throws.Nothing); } - private static DepositTransactionForRpc DepositTxWithGas(long? gas) => new() + private static DepositTransactionForRpc DepositTxWithGas(ulong? gas) => new() { SourceHash = Hash256.Zero, From = Address.Zero, @@ -113,12 +113,12 @@ public void Accepts_valid_transaction_missing_field((string missingField, string Gas = gas, }; - [TestCase(5_000L, null, 5_000L)] - [TestCase(5_000L, 0L, 5_000L)] - [TestCase(5_000L, 1_000L, 1_000L)] - [TestCase(5_000L, 10_000L, 5_000L)] - [TestCase(null, 1_000L, 1_000L)] - public void ToTransaction_caps_and_defaults_gas(long? gas, long? gasCap, long expectedGasLimit) + [TestCase(5_000UL, null, 5_000UL)] + [TestCase(5_000UL, 0UL, 5_000UL)] + [TestCase(5_000UL, 1_000UL, 1_000UL)] + [TestCase(5_000UL, 10_000UL, 5_000UL)] + [TestCase(null, 1_000UL, 1_000UL)] + public void ToTransaction_caps_and_defaults_gas(ulong? gas, ulong? gasCap, ulong expectedGasLimit) { DepositTransactionForRpc rpcTx = DepositTxWithGas(gas); @@ -128,8 +128,8 @@ public void ToTransaction_caps_and_defaults_gas(long? gas, long? gasCap, long ex } [TestCase(null, null)] - [TestCase(null, 0L)] - public void ToTransaction_throws_when_gas_missing_and_no_cap(long? gas, long? gasCap) + [TestCase(null, 0UL)] + public void ToTransaction_throws_when_gas_missing_and_no_cap(ulong? gas, ulong? gasCap) { DepositTransactionForRpc rpcTx = DepositTxWithGas(gas); diff --git a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs index 31339783f2b3..8ff37bb5b775 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs @@ -90,7 +90,7 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis ChainId = chainId, Type = Txs.Types[(int)txIdx], Nonce = Txs.Nonces[(int)txIdx], - GasLimit = (long)Txs.Gases[(int)txIdx], + GasLimit = Txs.Gases[(int)txIdx], }; bool contractCreationBit = ((Txs.ContractCreationBits >> (int)txIdx) & 1) == 1; if (!contractCreationBit) @@ -115,20 +115,27 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis v = 27u + (parityBit ? 1u : 0u); } - (tx.Value, tx.GasPrice, tx.Data) = DecodeLegacyTransaction(Txs.Data[(int)txIdx].Span); + (UInt256 legacyValue, tx.GasPrice, byte[] legacyData) = DecodeLegacyTransaction(Txs.Data[(int)txIdx].Span); + tx.Value = (ulong)legacyValue; + tx.Data = legacyData; break; } case TxType.AccessList: { v = EthereumEcdsaExtensions.CalculateV(chainId, parityBit); - (tx.Value, tx.GasPrice, tx.Data, tx.AccessList) = DecodeAccessListTransaction(Txs.Data[(int)txIdx].Span); + (UInt256 accessValue, tx.GasPrice, byte[] accessData, tx.AccessList) = DecodeAccessListTransaction(Txs.Data[(int)txIdx].Span); + tx.Value = (ulong)accessValue; + tx.Data = accessData; break; } case TxType.EIP1559: { v = EthereumEcdsaExtensions.CalculateV(chainId, parityBit); - (tx.Value, tx.GasPrice, tx.DecodedMaxFeePerGas, tx.Data, tx.AccessList) = + (UInt256 eipValue, tx.GasPrice, UInt256 maxFee, byte[] eipData, tx.AccessList) = DecodeEip1559Transaction(Txs.Data[(int)txIdx].Span); + tx.Value = (ulong)eipValue; + tx.DecodedMaxFeePerGas = (ulong)maxFee; + tx.Data = eipData; break; } default: diff --git a/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs b/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs index 43a72b01a6e4..d9d2149f4c06 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs @@ -67,7 +67,7 @@ public Transaction BuildL1InfoTransaction(L1BlockInfo blockInfo) To = engineParameters.SystemTransactionTo, GasLimit = 1000000, IsOPSystemTransaction = false, - Value = UInt256.Zero, + Value = 0UL, SourceHash = sourceHash }; } @@ -149,8 +149,8 @@ static Hash256 ComputeSourceHash(Hash256 l1BlockHash, ulong logIndex) SenderAddress = from, To = depositLogEventV0.IsCreation ? null : to, Mint = depositLogEventV0.Mint, - Value = depositLogEventV0.Value, - GasLimit = (long)depositLogEventV0.Gas, // WARNING: dangerous cast + Value = (ulong)depositLogEventV0.Value, + GasLimit = depositLogEventV0.Gas, Data = depositLogEventV0.Data.ToArray(), SourceHash = sourceHash, IsOPSystemTransaction = false, diff --git a/src/Nethermind/Nethermind.Optimism/CL/Derivation/PayloadAttributesDeriver.cs b/src/Nethermind/Nethermind.Optimism/CL/Derivation/PayloadAttributesDeriver.cs index c4502d907324..c25a5451b97d 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Derivation/PayloadAttributesDeriver.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Derivation/PayloadAttributesDeriver.cs @@ -95,7 +95,7 @@ private OptimismPayloadAttributes BuildOneBlock(L1Block l1Origin, ulong timestam { OptimismPayloadAttributes payload = new() { - GasLimit = (long)systemConfig.GasLimit, + GasLimit = systemConfig.GasLimit, NoTxPool = true, ParentBeaconBlockRoot = l1Origin.ParentBeaconBlockRoot, Timestamp = timestamp, diff --git a/src/Nethermind/Nethermind.Optimism/CL/IL2Api.cs b/src/Nethermind/Nethermind.Optimism/CL/IL2Api.cs index fffbc284dad6..f3488a4e0a9f 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/IL2Api.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/IL2Api.cs @@ -18,7 +18,7 @@ public interface IL2Api Task GetHeadBlock(); Task GetFinalizedBlock(); Task GetSafeBlock(); - Task GetProof(Address accountAddress, HashSet storageKeys, long blockNumber); + Task GetProof(Address accountAddress, HashSet storageKeys, ulong blockNumber); Task ForkChoiceUpdatedV3( Hash256 headHash, Hash256 finalizedHash, Hash256 safeHash, OptimismPayloadAttributes? payloadAttributes = null); diff --git a/src/Nethermind/Nethermind.Optimism/CL/L1Bridge/EthereumEthApi.cs b/src/Nethermind/Nethermind.Optimism/CL/L1Bridge/EthereumEthApi.cs index f4b01ae58083..405a01504a1e 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/L1Bridge/EthereumEthApi.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/L1Bridge/EthereumEthApi.cs @@ -20,7 +20,7 @@ public class EthereumEthApi(string l1EthApiEndpoint, IJsonSerializer jsonSeriali public Task GetBlockByHash(Hash256 blockHash, bool fullTxs) => _ethRpcClient.Post("eth_getBlockByHash", new object[] { blockHash, fullTxs }); - public Task GetBlockByNumber(ulong blockNumber, bool fullTxs) => _ethRpcClient.Post("eth_getBlockByNumber", new BlockParameter((long)blockNumber), fullTxs); + public Task GetBlockByNumber(ulong blockNumber, bool fullTxs) => _ethRpcClient.Post("eth_getBlockByNumber", new BlockParameter(blockNumber), fullTxs); public Task GetHead(bool fullTxs) => _ethRpcClient.Post("eth_getBlockByNumber", BlockParameter.Latest, fullTxs); diff --git a/src/Nethermind/Nethermind.Optimism/CL/L2Api.cs b/src/Nethermind/Nethermind.Optimism/CL/L2Api.cs index 873fc0e4539a..98334dce7ca1 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/L2Api.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/L2Api.cs @@ -32,7 +32,7 @@ public class L2Api( public async Task GetBlockByNumber(ulong number) { - BlockForRpc? block = await RetryGetBlock(new((long)number)); + BlockForRpc? block = await RetryGetBlock(new(number)); ArgumentNullException.ThrowIfNull(block); // We cannot get null here PayloadAttributesRef payloadAttributes = PayloadAttributesFromBlockForRpc(block); return new L2Block @@ -73,7 +73,7 @@ private PayloadAttributesRef PayloadAttributesFromBlockForRpc(BlockForRpc? block l1BlockInfo = L1BlockInfoBuilder.FromL2DepositTxDataAndExtraData(txs[0].Data.Span, block.ExtraData); systemConfig = - systemConfigDeriver.SystemConfigFromL2BlockInfo(txs[0].Data.Span, block.ExtraData, (ulong)block.GasLimit); + systemConfigDeriver.SystemConfigFromL2BlockInfo(txs[0].Data.Span, block.ExtraData, block.GasLimit); } else { @@ -84,7 +84,7 @@ private PayloadAttributesRef PayloadAttributesFromBlockForRpc(BlockForRpc? block { PayloadAttributes = payloadAttributes, L1BlockInfo = l1BlockInfo, - Number = (ulong)block.Number!, + Number = block.Number!.Value, SystemConfig = systemConfig }; return result; @@ -138,7 +138,7 @@ public async Task GetHeadBlock() }; } - public Task GetProof(Address accountAddress, HashSet storageKeys, long blockNumber) + public Task GetProof(Address accountAddress, HashSet storageKeys, ulong blockNumber) { // TODO: Retry logic ResultWrapper result = l2EthRpc.eth_getProof(accountAddress, storageKeys, new BlockParameter(blockNumber)); diff --git a/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs b/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs index 5209c5addfc9..b3c723877be9 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/P2P/P2PBlockValidator.cs @@ -22,7 +22,7 @@ public class P2PBlockValidator( private readonly Address _sequencerP2PAddress = sequencerP2PAddress; private readonly ITimestamper _timestamper = timestamper; private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly Dictionary _numberOfBlocksSeen = []; + private readonly Dictionary _numberOfBlocksSeen = []; public ValidityStatus Validate(ExecutionPayloadV3 payload, P2PTopic topic) { diff --git a/src/Nethermind/Nethermind.Optimism/CL/P2P/PayloadDecoder.cs b/src/Nethermind/Nethermind.Optimism/CL/P2P/PayloadDecoder.cs index 7f467218fe75..969e2a675f4b 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/P2P/PayloadDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/P2P/PayloadDecoder.cs @@ -35,9 +35,9 @@ public ExecutionPayloadV3 DecodePayload(ReadOnlySpan data) payload.ReceiptsRoot = new(movingData.TakeAndMove(32)); payload.LogsBloom = new(movingData.TakeAndMove(256)); payload.PrevRandao = new(movingData.TakeAndMove(32)); - payload.BlockNumber = (long)BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); - payload.GasLimit = (long)BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); - payload.GasUsed = (long)BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); + payload.BlockNumber = BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); + payload.GasLimit = BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); + payload.GasUsed = BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); payload.Timestamp = BinaryPrimitives.ReadUInt64LittleEndian(movingData.TakeAndMove(8)); UInt32 extraDataOffset = 32 + BinaryPrimitives.ReadUInt32LittleEndian(movingData.TakeAndMove(4)); payload.BaseFeePerGas = new(movingData.TakeAndMove(32)); diff --git a/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismOptimismRpcModule.cs b/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismOptimismRpcModule.cs index 484d9854759c..fa4e310aef08 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismOptimismRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismOptimismRpcModule.cs @@ -39,7 +39,7 @@ public async Task> optimism_outputAtBlock(u L2Block block = await l2Api.GetBlockByNumber(blockNumber); - AccountProof? proof = await l2Api.GetProof(PreDeploys.L2ToL1MessagePasser, [], (long)block.Number); + AccountProof? proof = await l2Api.GetProof(PreDeploys.L2ToL1MessagePasser, [], block.Number); if (proof == null) { return ResultWrapper.Fail("Failed to get proof"); diff --git a/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismRollupConfig.cs b/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismRollupConfig.cs index 84208a55b512..7eaa19684c85 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismRollupConfig.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Rpc/OptimismRollupConfig.cs @@ -86,7 +86,7 @@ public static OptimismRollupConfig Build( Genesis = new OptimismGenesis { L1 = new BlockId { Number = clParameters.L1ChainId!.Value, Hash = clParameters.L1GenesisHash! }, - L2 = new BlockId { Number = (ulong)chainSpec.Genesis.Number, Hash = chainSpec.Genesis.GetOrCalculateHash() }, + L2 = new BlockId { Number = chainSpec.Genesis.Number, Hash = chainSpec.Genesis.GetOrCalculateHash() }, L2Time = chainSpec.Genesis.Timestamp, SystemConfig = clParameters.GenesisSystemConfig! }, diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBaseFeeCalculator.cs b/src/Nethermind/Nethermind.Optimism/OptimismBaseFeeCalculator.cs index 179e27ad18d1..3e74b9df2c05 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBaseFeeCalculator.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBaseFeeCalculator.cs @@ -42,7 +42,7 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) if (parent.BlobGasUsed is null) throw new InvalidOperationException($"{nameof(parent.BlobGasUsed)} does not store DA footprint in post-Jovian block."); - long daFootprint = (long)parent.BlobGasUsed; + ulong daFootprint = parent.BlobGasUsed.Value; // Override gas used for calculation if the DA footprint is larger UInt256 baseFee = daFootprint > parent.GasUsed @@ -58,9 +58,9 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) return baseFeeCalculator.Calculate(parent, spec); } - private UInt256 CalculateWithGasUsedOverride(BlockHeader parent, IEip1559Spec spec, long gasOverride) + private UInt256 CalculateWithGasUsedOverride(BlockHeader parent, IEip1559Spec spec, ulong gasOverride) { - long prevGasUsed = parent.GasUsed; + ulong prevGasUsed = parent.GasUsed; try { parent.GasUsed = gasOverride; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs index ad1de3007d6e..f805908f5e59 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs @@ -24,7 +24,7 @@ public class OptimismBlockReceiptTracer(IOptimismSpecHelper opSpecHelper, IWorld if (CurrentTx.IsDeposit()) { - depositNonce = _worldState.GetNonce(CurrentTx.SenderAddress!).ToUInt64(null); + depositNonce = _worldState.GetNonce(CurrentTx.SenderAddress!); // We write nonce after tx processing, so need to subtract one if (depositNonce > 0) { @@ -42,7 +42,7 @@ public class OptimismBlockReceiptTracer(IOptimismSpecHelper opSpecHelper, IWorld protected override TxReceipt BuildReceipt(Address recipient, in GasConsumed gasConsumed, byte statusCode, LogEntry[] logEntries, Hash256? stateRoot) { // Update cumulative gas tracking without creating a throwaway receipt - long cumulativeReceiptGas = UpdateCumulativeGasTracking(gasConsumed); + ulong cumulativeReceiptGas = UpdateCumulativeGasTracking(gasConsumed); (ulong? depositNonce, ulong? version) = GetDepositReceiptData(Block.Header); diff --git a/src/Nethermind/Nethermind.Optimism/OptimismChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Optimism/OptimismChainSpecEngineParameters.cs index ddd2376569a3..f7cbe52931e0 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismChainSpecEngineParameters.cs @@ -17,7 +17,7 @@ public class OptimismChainSpecEngineParameters : IChainSpecEngineParameters public ulong? RegolithTimestamp { get; set; } - public long? BedrockBlockNumber { get; set; } + public ulong? BedrockBlockNumber { get; set; } public ulong? CanyonTimestamp { get; set; } @@ -45,7 +45,7 @@ public class OptimismChainSpecEngineParameters : IChainSpecEngineParameters public byte[]? Create2DeployerCode { get; set; } - public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) + public void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) { ArgumentNullException.ThrowIfNull(CanyonBaseFeeChangeDenominator); if (CanyonTimestamp <= startTimestamp) @@ -56,7 +56,7 @@ public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTi spec.BaseFeeCalculator = new OptimismBaseFeeCalculator(HoloceneTimestamp, JovianTimestamp, new DefaultBaseFeeCalculator()); } - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) => AddIfNotNull(timestamps, JovianTimestamp); + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) => AddIfNotNull(timestamps, JovianTimestamp); private void AddIfNotNull(SortedSet timestamps, ulong? timestamp) { diff --git a/src/Nethermind/Nethermind.Optimism/OptimismCompactReceiptStorageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismCompactReceiptStorageDecoder.cs index 7f682891b5c1..466d33a0ca3f 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismCompactReceiptStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismCompactReceiptStorageDecoder.cs @@ -39,7 +39,7 @@ protected override OptimismTxReceipt DecodeInternal(ref ValueDecoderContext deco } txReceipt.Sender = decoderContext.DecodeAddress(); - txReceipt.GasUsedTotal = decoderContext.DecodePositiveLong(); + txReceipt.GasUsedTotal = decoderContext.DecodeULong(); int sequenceLength = decoderContext.ReadSequenceLength(); int logEntriesCheck = sequenceLength + decoderContext.Position; @@ -103,7 +103,7 @@ public void DecodeStructRef(scoped ref ValueDecoderContext decoderContext, RlpBe } decoderContext.DecodeAddressStructRef(out item.Sender); - item.GasUsedTotal = decoderContext.DecodePositiveLong(); + item.GasUsedTotal = decoderContext.DecodeULong(); (int prefixLength, int contentLength) = decoderContext.PeekPrefixAndContentLength(); int logsBytes = contentLength + prefixLength; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs b/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs index a26a03a3ac51..1bba8fa76f39 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs @@ -179,12 +179,12 @@ public static UInt256 ComputeDataGas(Transaction tx, bool isRegolith) { byte[] encoded = Rlp.Encode(tx, RlpBehaviors.SkipTypedWrapping).Bytes; - long zeroCount = encoded.Count(static b => b == 0); - long nonZeroCount = encoded.Length - zeroCount; + ulong zeroCount = (ulong)encoded.Count(static b => b == 0); + ulong nonZeroCount = (ulong)encoded.Length - zeroCount; // Add pre-EIP-3529 overhead - nonZeroCount += isRegolith ? 0 : OptimismConstants.PreRegolithNonZeroCountOverhead; + nonZeroCount += isRegolith ? 0UL : OptimismConstants.PreRegolithNonZeroCountOverhead; - return (ulong)(zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028); + return zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028; } // Fjord L1 formula: diff --git a/src/Nethermind/Nethermind.Optimism/OptimismGasLimitCalculator.cs b/src/Nethermind/Nethermind.Optimism/OptimismGasLimitCalculator.cs index 5e5a6932e95f..c83dd4eec618 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismGasLimitCalculator.cs @@ -9,6 +9,6 @@ namespace Nethermind.Optimism; public class OptimismGasLimitCalculator : IGasLimitCalculator { - public long GetGasLimit(BlockHeader parentHeader) => + public ulong GetGasLimit(BlockHeader parentHeader) => throw new InvalidOperationException("GasLimit in Optimism should come from payload attributes."); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismHeaderValidator.cs b/src/Nethermind/Nethermind.Optimism/OptimismHeaderValidator.cs index f451b15a2f5f..d29e544bb60f 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismHeaderValidator.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismHeaderValidator.cs @@ -99,7 +99,7 @@ protected override bool ValidateBlobGasFields(BlockHeader header, BlockHeader pa return false; } - if (blobGasUsed > (ulong)header.GasLimit) + if (blobGasUsed > header.GasLimit) { if (_logger.IsWarn) _logger.Warn($"Invalid block header ({header.Hash}) - gas used above gas limit"); error = ErrorMessages.DaFootprintExceededGasLimit; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismLegacyTxDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismLegacyTxDecoder.cs index cb51c7f88c87..7206e0f4c8a3 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismLegacyTxDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismLegacyTxDecoder.cs @@ -38,7 +38,7 @@ public sealed class OptimismLegacyTxValidator(ulong chainId) : ITxValidator public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) => IsWellFormed(transaction, releaseSpec, blockGasLimit: 0); - public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit) + public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit) { // In Optimism, EIP1559 is activated in Bedrock bool isPreBedrock = !releaseSpec.IsEip1559Enabled; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs b/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs index b28d24b244f4..37d33b31f265 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs @@ -13,7 +13,7 @@ public class OptimismPayloadTxSource : ITxSource { public bool SupportsBlobs => false; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) { if (payloadAttributes is OptimismPayloadAttributes optimismPayloadAttributes) { diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs index 99a316e69822..a51828c68f41 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs @@ -6,7 +6,7 @@ using Nethermind.Int256; using Nethermind.Optimism; -public class OptimismPoSSwitcher(ISpecProvider specProvider, long bedrockBlockNumber) : IPoSSwitcher +public class OptimismPoSSwitcher(ISpecProvider specProvider, ulong bedrockBlockNumber) : IPoSSwitcher { public OptimismPoSSwitcher(ISpecProvider specProvider, OptimismChainSpecEngineParameters optimismChainSpecEngineParameters) : this(specProvider, optimismChainSpecEngineParameters.BedrockBlockNumber!.Value) @@ -21,7 +21,7 @@ public OptimismPoSSwitcher(ISpecProvider specProvider, OptimismChainSpecEnginePa public Hash256? ConfiguredTerminalBlockHash => null; - public long? ConfiguredTerminalBlockNumber => null; + public ulong? ConfiguredTerminalBlockNumber => null; public event EventHandler TerminalBlockReached { add { } remove { } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs index 4c347752de0d..d792654304f9 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs @@ -33,16 +33,16 @@ protected override OptimismTxReceipt DecodeInternal(ref Rlp.ValueDecoderContext if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; - txReceipt.GasUsedTotal = (long)ctx.DecodeUBigInt(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } else if (firstItem.Length is >= 1 and <= 4) { - txReceipt.GasUsedTotal = firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Hash256(firstItem); - txReceipt.GasUsedTotal = (long)ctx.DecodeUBigInt(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } txReceipt.Bloom = ctx.DecodeBloom(); diff --git a/src/Nethermind/Nethermind.Optimism/OptimismSpecHelper.cs b/src/Nethermind/Nethermind.Optimism/OptimismSpecHelper.cs index 5d97fad91361..0f13e4e4a41d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismSpecHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismSpecHelper.cs @@ -7,7 +7,7 @@ namespace Nethermind.Optimism; public class OptimismSpecHelper(OptimismChainSpecEngineParameters parameters) : IOptimismSpecHelper { - private readonly long? _bedrockBlockNumber = parameters.BedrockBlockNumber; + private readonly ulong? _bedrockBlockNumber = parameters.BedrockBlockNumber; private readonly ulong? _regolithTimestamp = parameters.RegolithTimestamp; private readonly ulong? _canyonTimestamp = parameters.CanyonTimestamp; private readonly ulong? _deltaTimestamp = parameters.DeltaTimestamp; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 8f6e055b353e..3a04b726144b 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -91,14 +91,15 @@ protected override TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, I return TransactionResult.MinerPremiumNegative; } - if (UInt256.SubtractUnderflow(in senderBalance, in tx.ValueRef, out UInt256 balanceLeft)) + UInt256 txValue = (UInt256)tx.ValueRef; + if (UInt256.SubtractUnderflow(in senderBalance, in txValue, out UInt256 balanceLeft)) { TraceLogInvalidTx(tx, $"INSUFFICIENT_SENDER_BALANCE: ({tx.SenderAddress})_BALANCE = {senderBalance}"); return TransactionResult.InsufficientSenderBalance; } UInt256 l1Cost = _currentTxL1Cost ??= costHelper.ComputeL1Cost(tx, header, WorldState); - UInt256 maxOperatorCost = costHelper.ComputeOperatorCost(tx.GasLimit, header, WorldState); + UInt256 maxOperatorCost = costHelper.ComputeOperatorCost((long)tx.GasLimit, header, WorldState); if (UInt256.SubtractUnderflow(balanceLeft, l1Cost + maxOperatorCost, out balanceLeft)) { @@ -142,7 +143,7 @@ protected override TransactionResult ValidateSender(Transaction tx, BlockHeader tx.IsDeposit() ? TransactionResult.Ok : base.ValidateSender(tx, header, spec, tracer, opts); protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, - in TransactionSubstate substate, long spentGas, in UInt256 premiumPerGas, in UInt256 blobGasFee, int statusCode) + in TransactionSubstate substate, ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobGasFee, int statusCode) { if (!tx.IsDeposit()) { @@ -157,8 +158,8 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec if (opSpecHelper.IsIsthmus(header)) { - UInt256 operatorCostMax = costHelper.ComputeOperatorCost(tx.GasLimit, header, WorldState); - UInt256 operatorCostUsed = costHelper.ComputeOperatorCost(spentGas, header, WorldState); + UInt256 operatorCostMax = costHelper.ComputeOperatorCost((long)tx.GasLimit, header, WorldState); + UInt256 operatorCostUsed = costHelper.ComputeOperatorCost((long)spentGas, header, WorldState); if (operatorCostMax > operatorCostUsed) { @@ -173,7 +174,7 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec } protected override GasConsumed Refund(Transaction tx, BlockHeader header, IReleaseSpec spec, ExecutionOptions opts, - in TransactionSubstate substate, in EthereumGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in EthereumGasPolicy floorGas, in EthereumGasPolicy intrinsicGasStandard, long postIntrinsicStateReservoir) + in TransactionSubstate substate, in EthereumGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in EthereumGasPolicy floorGas, in EthereumGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) { // if deposit: skip refunds, skip tipping coinbase // Regolith changes this behaviour to report the actual gasUsed instead of always reporting all gas used. @@ -181,7 +182,7 @@ protected override GasConsumed Refund(Transaction tx, BlockHeader header, IRelea { // Record deposits as using all their gas // System Transactions are special & are not recorded as using any gas (anywhere) - long gas = tx.IsOPSystemTransaction ? 0 : tx.GasLimit; + ulong gas = tx.IsOPSystemTransaction ? 0UL : tx.GasLimit; return gas; } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTxDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismTxDecoder.cs index ef5148f56ba8..bcab56ccb262 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTxDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTxDecoder.cs @@ -25,8 +25,8 @@ protected override void DecodePayload(Transaction transaction, ref Rlp.ValueDeco transaction.SenderAddress = decoderContext.DecodeAddress(); transaction.To = decoderContext.DecodeAddress(); transaction.Mint = decoderContext.DecodeUInt256(); - transaction.Value = decoderContext.DecodeUInt256(); - transaction.GasLimit = decoderContext.DecodePositiveLong(); + transaction.Value = decoderContext.DecodeULong(); + transaction.GasLimit = decoderContext.DecodeULong(); transaction.IsOPSystemTransaction = decoderContext.DecodeBool(); transaction.Data = decoderContext.DecodeByteArray(); } @@ -41,7 +41,7 @@ protected override int GetPayloadLength(Transaction transaction) => + Rlp.LengthOf(transaction.SenderAddress) + Rlp.LengthOf(transaction.To) + Rlp.LengthOf(transaction.Mint) - + Rlp.LengthOf(in transaction.ValueRef) + + Rlp.LengthOf(transaction.ValueRef) + Rlp.LengthOf(transaction.GasLimit) + Rlp.LengthOf(transaction.IsOPSystemTransaction) + Rlp.LengthOf(transaction.Data); @@ -52,7 +52,7 @@ protected override void EncodePayload(Transaction transaction, RlpStream stream, stream.Encode(transaction.SenderAddress); stream.Encode(transaction.To); stream.Encode(transaction.Mint); - stream.Encode(in transaction.ValueRef); + stream.Encode(transaction.ValueRef); stream.Encode(transaction.GasLimit); stream.Encode(transaction.IsOPSystemTransaction); stream.Encode(transaction.Data); diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs b/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs index cca052dc04f4..e2fabc4884c1 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs @@ -15,7 +15,7 @@ public class OptimismTxPoolTxSource(ITxSource baseTxSource) : ITxSource public bool SupportsBlobs => _baseTxSource.SupportsBlobs; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes, bool filterSource) => payloadAttributes is OptimismPayloadAttributes { NoTxPool: true } ? [] : _baseTxSource.GetTransactions(parent, gasLimit, payloadAttributes, filterSource); diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs b/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs index 3324f7c19602..f4f3dd039561 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs @@ -65,7 +65,7 @@ public DepositTransactionForRpc(Transaction transaction, in TransactionForRpcCon DepositReceiptVersion = receipt?.DepositReceiptVersion; } - public override Result ToTransaction(bool validateUserInput = false, long? gasCap = null, IReleaseSpec? spec = null) + public override Result ToTransaction(bool validateUserInput = false, ulong? gasCap = null, IReleaseSpec? spec = null) { Result baseResult = base.ToTransaction(validateUserInput, gasCap, spec); if (baseResult.IsError) return baseResult; @@ -75,16 +75,16 @@ public override Result ToTransaction(bool validateUserInput = false tx.SenderAddress = From ?? throw new ArgumentNullException(nameof(From)); tx.To = To; tx.Mint = Mint ?? 0; - tx.Value = Value ?? throw new ArgumentNullException(nameof(Value)); + tx.Value = (ulong)(Value ?? throw new ArgumentNullException(nameof(Value))); tx.IsOPSystemTransaction = IsSystemTx ?? false; tx.Data = Input ?? throw new ArgumentNullException(nameof(Input)); // Deposit txs require an explicit Gas; the original EnsureDefaults granted a graceful fallback to // gasCap when the request omitted it, which we preserve. gasCap is null/0 mean "no cap" (matching // LegacyTransactionForRpc), so neither substitutes for a missing Gas — that case still throws. - long effectiveCap = gasCap is null or 0 ? long.MaxValue : gasCap.Value; - long? gasOrDefault = Gas ?? (effectiveCap == long.MaxValue ? null : effectiveCap); - tx.GasLimit = long.Min(gasOrDefault ?? throw new ArgumentNullException(nameof(Gas)), effectiveCap); + ulong effectiveCap = gasCap is null or 0 ? ulong.MaxValue : gasCap.Value; + ulong? gasOrDefault = Gas ?? (effectiveCap == ulong.MaxValue ? null : effectiveCap); + tx.GasLimit = ulong.Min(gasOrDefault ?? throw new ArgumentNullException(nameof(Gas)), effectiveCap); return tx; } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs index 903993302926..a5e5a5d36cea 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs @@ -29,8 +29,8 @@ public byte[][]? Transactions } } public bool NoTxPool { get; set; } - public long GasLimit { get; set; } - public override long? GetGasLimit() => GasLimit; + public ulong GasLimit { get; set; } + public override ulong? GetGasLimit() => GasLimit; /// /// See @@ -94,8 +94,8 @@ protected override int WritePayloadIdMembers(BlockHeader parentHeader, Span await _blockTree.Accept(blockTreeVisitor, cancellationToken); public ChainLevelInfo FindLevel(long number) => _blockTree.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => throw new NotImplementedException(); + public BlockInfo FindCanonicalBlockInfo(ulong blockNumber) => throw new NotImplementedException(); public AddBlockResult Insert(Block block) => _blockTree.Insert(block); @@ -107,15 +107,15 @@ public long? LowestInsertedBodyNumber public BlockHeader FindHeader(Keccak blockHash, BlockTreeLookupOptions options) => _blockTree.FindHeader(blockHash, options); - public Block FindBlock(long blockNumber, BlockTreeLookupOptions options) => _blockTree.FindBlock(blockNumber, options); + public Block FindBlock(ulong blockNumber, BlockTreeLookupOptions options) => _blockTree.FindBlock(blockNumber, options); - public BlockHeader FindHeader(long blockNumber, BlockTreeLookupOptions options) => _blockTree.FindHeader(blockNumber, options); + public BlockHeader FindHeader(ulong blockNumber, BlockTreeLookupOptions options) => _blockTree.FindHeader(blockNumber, options); - public Keccak FindBlockHash(long blockNumber) => _blockTree.FindBlockHash(blockNumber); + public Keccak FindBlockHash(ulong blockNumber) => _blockTree.FindBlockHash(blockNumber); public bool IsMainChain(BlockHeader blockHeader) => _blockTree.IsMainChain(blockHeader); - public Keccak FindHash(long blockNumber) => _blockTree.FindHash(blockNumber); + public Keccak FindHash(ulong blockNumber) => _blockTree.FindHash(blockNumber); public BlockHeader[] FindHeaders(Keccak hash, int numberOfBlocks, int skip, bool reverse) => _blockTree.FindHeaders(hash, numberOfBlocks, skip, reverse); diff --git a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs index 8ce52606fe9c..6f19684bdd40 100644 --- a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs @@ -203,15 +203,15 @@ public void Migrations_are_not_enabled_by_default(string configWildcard) Test(configWildcard, static c => c.MigrationStatistics, false); } - [TestCase("^mainnet ^gnosis ^sepolia", 0L)] - [TestCase("mainnet ^archive", 15537394L)] - [TestCase("gnosis ^archive", 25349537L)] - [TestCase("sepolia ^archive", 1450409L)] - [TestCase("archive", 0L)] - public void Barriers_defaults_are_correct(string configWildcard, long barrier) + [TestCase("^mainnet ^gnosis ^sepolia", 0UL)] + [TestCase("mainnet ^archive", 15537394UL)] + [TestCase("gnosis ^archive", 25349537UL)] + [TestCase("sepolia ^archive", 1450409UL)] + [TestCase("archive", 0UL)] + public void Barriers_defaults_are_correct(string configWildcard, ulong barrier) { - Test(configWildcard, static c => c.AncientBodiesBarrier, barrier); - Test(configWildcard, static c => c.AncientReceiptsBarrier, barrier); + Test(configWildcard, static c => c.AncientBodiesBarrier, barrier); + Test(configWildcard, static c => c.AncientReceiptsBarrier, barrier); } [TestCase("^spaceneth", "nethermind_db")] diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs index b64932e448f6..df0b4085ef2f 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs @@ -25,15 +25,15 @@ namespace Nethermind.Runner.Test.Ethereum.Steps.Migrations { public class ReceiptMigrationTests { - [TestCase(null, 0, false, false, false, false)] // No change to migrate - [TestCase(5, 5, false, false, false, true)] // Explicit command and partially migrated - [TestCase(null, 5, true, false, false, true)] // Partially migrated - [TestCase(5, 0, false, false, false, true)] // Explicit command - [TestCase(null, 0, true, false, false, true)] // Force reset - [TestCase(null, 0, false, false, true, true)] // Encoding mismatch - [TestCase(null, 0, false, true, false, true)] // Encoding mismatch - [TestCase(null, 0, false, true, true, false)] // Encoding match - public async Task RunMigration(int? commandStartBlockNumber, long currentMigratedBlockNumber, bool forceReset, bool receiptIsCompact, bool useCompactEncoding, bool wasMigrated) + [TestCase(null, 0UL, false, false, false, false)] // No change to migrate + [TestCase(5UL, 5UL, false, false, false, true)] // Explicit command and partially migrated + [TestCase(null, 5UL, true, false, false, true)] // Partially migrated + [TestCase(5UL, 0UL, false, false, false, true)] // Explicit command + [TestCase(null, 0UL, true, false, false, true)] // Force reset + [TestCase(null, 0UL, false, false, true, true)] // Encoding mismatch + [TestCase(null, 0UL, false, true, false, true)] // Encoding mismatch + [TestCase(null, 0UL, false, true, true, false)] // Encoding match + public async Task RunMigration(ulong? commandStartBlockNumber, ulong currentMigratedBlockNumber, bool forceReset, bool receiptIsCompact, bool useCompactEncoding, bool wasMigrated) { int chainLength = 10; IReceiptConfig receiptConfig = new ReceiptConfig() @@ -60,7 +60,8 @@ public async Task RunMigration(int? commandStartBlockNumber, long currentMigrate int txIndex = 0; for (int i = 1; i < chainLength; i++) { - Block block = blockTree.FindBlock(i); + // Safe: i is a loop counter in [1, chainLength), always a valid non-negative block number. + Block block = blockTree.FindBlock((ulong)i); inMemoryReceiptStorage.Insert(block, new[] { Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject, Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject @@ -73,7 +74,8 @@ public async Task RunMigration(int? commandStartBlockNumber, long currentMigrate TestMemDb defaultDb = (TestMemDb)receiptColumnDb.GetColumnDb(ReceiptsColumns.Default); // Put the last block receipt encoding - Block lastBlock = blockTree.FindBlock(chainLength - 1); + // Safe: chainLength - 1 is a small positive integer well within ulong range. + Block lastBlock = blockTree.FindBlock((ulong)(chainLength - 1)); TxReceipt[] receipts = inMemoryReceiptStorage.Get(lastBlock); using (NettyRlpStream nettyStream = receiptArrayStorageDecoder.EncodeToNewNettyStream(receipts, RlpBehaviors.Storage)) { @@ -104,7 +106,9 @@ public async Task RunMigration(int? commandStartBlockNumber, long currentMigrate if (wasMigrated) { - int blockNum = commandStartBlockNumber ?? (chainLength - 1); + // Safe: commandStartBlockNumber.Value fits in int for these test cases (max = chainLength = 10). + // chainLength - 1 is equally safe. + int blockNum = commandStartBlockNumber.HasValue ? (int)commandStartBlockNumber.Value : (chainLength - 1); int txCount = blockNum * 2; defaultDb.KeyWasWritten((item => item.Item2 is null), txCount); ((TestMemDb)receiptColumnDb.GetColumnDb(ReceiptsColumns.Blocks)).KeyWasRemoved((_ => true), blockNum); @@ -127,19 +131,19 @@ private class TestReceiptStorage(IReceiptStorage inStorage, IReceiptStorage outS public TxReceipt[] Get(Hash256 blockHash, bool recover = true) => _inStorage.Get(blockHash, recover); - public bool CanGetReceiptsByHash(long blockNumber) => _inStorage.CanGetReceiptsByHash(blockNumber); - public bool TryGetReceiptsIterator(long blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) => _inStorage.TryGetReceiptsIterator(blockNumber, blockHash, out iterator); + public bool CanGetReceiptsByHash(ulong blockNumber) => _inStorage.CanGetReceiptsByHash(blockNumber); + public bool TryGetReceiptsIterator(ulong blockNumber, Hash256 blockHash, out ReceiptsIterator iterator) => _inStorage.TryGetReceiptsIterator(blockNumber, blockHash, out iterator); - public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical, WriteFlags writeFlags, long? lastBlockNumber) => _outStorage.Insert(block, txReceipts, spec, ensureCanonical, writeFlags, lastBlockNumber); - public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical, WriteFlags writeFlags, long? lastBlockNumber) => _outStorage.Insert(block, txReceipts, ensureCanonical, writeFlags, lastBlockNumber); + public void Insert(Block block, TxReceipt[] txReceipts, IReleaseSpec spec, bool ensureCanonical, WriteFlags writeFlags, ulong? lastBlockNumber) => _outStorage.Insert(block, txReceipts, spec, ensureCanonical, writeFlags, lastBlockNumber); + public void Insert(Block block, TxReceipt[] txReceipts, bool ensureCanonical, WriteFlags writeFlags, ulong? lastBlockNumber) => _outStorage.Insert(block, txReceipts, ensureCanonical, writeFlags, lastBlockNumber); - public long MigratedBlockNumber + public ulong MigratedBlockNumber { get => _outStorage.MigratedBlockNumber; set => _outStorage.MigratedBlockNumber = value; } - public bool HasBlock(long blockNumber, Hash256 hash) => _outStorage.HasBlock(blockNumber, hash); + public bool HasBlock(ulong blockNumber, Hash256 hash) => _outStorage.HasBlock(blockNumber, hash); public void EnsureCanonical(Block block) { diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs index 3272c2bcd320..ff82a20f7f84 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs @@ -27,13 +27,13 @@ public class TotalDifficultyFixMigrationTest [TestCase(4, 1, -1)] public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, long expectedTd) { - long numberOfBlocks = 10; - long firstBlock = 3; + ulong numberOfBlocks = 10; + ulong firstBlock = 3; // Setup headers BlockHeader[] headers = new BlockHeader[numberOfBlocks]; Dictionary hashesToHeaders = []; headers[0] = Core.Test.Builders.Build.A.BlockHeader.WithDifficulty(1).TestObject; - for (int i = 1; i < numberOfBlocks; ++i) + for (ulong i = 1; i < numberOfBlocks; ++i) { headers[i] = Core.Test.Builders.Build.A.BlockHeader.WithParent(headers[i - 1]).WithDifficulty((UInt256)i + 1).TestObject; hashesToHeaders.Add(headers[i].Hash!, headers[i]); @@ -41,7 +41,7 @@ public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, l // Setup db ChainLevelInfo[] levels = new ChainLevelInfo[numberOfBlocks]; - for (int i = 0; i < numberOfBlocks; ++i) + for (ulong i = 0; i < numberOfBlocks; ++i) { levels[i] = new ChainLevelInfo(true, new BlockInfo(headers[i].Hash!, (UInt256)((i + 1) * (i + 2)) / 2)); } @@ -54,29 +54,41 @@ public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, l blockTree.BestKnownNumber.Returns(numberOfBlocks); IChainLevelInfoRepository chainLevelInfoRepository = Substitute.For(); - chainLevelInfoRepository.LoadLevel(Arg.Any()).Returns(info => levels[(long)info[0]]); + chainLevelInfoRepository.LoadLevel(Arg.Any()).Returns(info => levels[(ulong)info[0]]); chainLevelInfoRepository - .When(x => x.PersistLevel(Arg.Any(), Arg.Any())) - .Do(x => persistedLevels[(long)x[0]] = (ChainLevelInfo)x[1]); + .When(x => x.PersistLevel(Arg.Any(), Arg.Any())) + .Do(x => persistedLevels[(ulong)x[0]] = (ChainLevelInfo)x[1]); SyncConfig syncConfig = new() { FixTotalDifficulty = true, FixTotalDifficultyStartingBlock = firstBlock, - FixTotalDifficultyLastBlock = lastBlock + // lastBlock is long? from TestCase; null means "no upper bound", negative means sentinel for "broken level out of range" + // Safe cast: test cases only pass non-negative values or null here when meaningful + FixTotalDifficultyLastBlock = lastBlock.HasValue ? (ulong?)lastBlock.Value : null }; TotalDifficultyFixMigration migration = new(chainLevelInfoRepository, blockTree, syncConfig, new TestLogManager()); - // Break level - levels[brokenLevel].BlockInfos[0].TotalDifficulty = 9999; + // Break level — brokenLevel is long from TestCase; safe to cast since array is sized by ulong numberOfBlocks + // and brokenLevel is always within [0, numberOfBlocks) in valid test cases + ulong brokenLevelUlong = (ulong)brokenLevel; + levels[brokenLevelUlong].BlockInfos[0].TotalDifficulty = 9999; // Run await migration.Run(CancellationToken.None); // Check level fixed - for (long i = 0; i < numberOfBlocks; ++i) + for (ulong i = 0; i < numberOfBlocks; ++i) { - if (i == brokenLevel && firstBlock <= brokenLevel && brokenLevel <= (lastBlock ?? numberOfBlocks)) + // brokenLevel may be a sentinel negative value in some test cases (meaning "not in range"), + // so compare as long to handle that gracefully + ulong? lastBlockUlong = lastBlock.HasValue ? (ulong?)lastBlock.Value : null; + bool isBroken = brokenLevel >= 0 + && i == brokenLevelUlong + && firstBlock <= brokenLevelUlong + && brokenLevelUlong <= (lastBlockUlong ?? numberOfBlocks); + + if (isBroken) { Assert.That(persistedLevels[i].BlockInfos[0].TotalDifficulty, Is.EqualTo((UInt256)expectedTd)); } @@ -127,14 +139,14 @@ public async Task should_fix_non_canonical() // Setup mocks IBlockTree blockTree = Substitute.For(); blockTree.FindHeader(Arg.Any()).Returns(info => hashesToHeaders[(Hash256)info[0]]); - blockTree.BestKnownNumber.Returns(5); + blockTree.BestKnownNumber.Returns(5UL); ChainLevelInfo[] persistedLevels = new ChainLevelInfo[5]; IChainLevelInfoRepository chainLevelInfoRepository = Substitute.For(); - chainLevelInfoRepository.LoadLevel(Arg.Any()).Returns(info => levels[(long)info[0]]); + chainLevelInfoRepository.LoadLevel(Arg.Any()).Returns(info => levels[(ulong)info[0]]); chainLevelInfoRepository - .When(x => x.PersistLevel(Arg.Any(), Arg.Any())) - .Do(x => persistedLevels[(long)x[0]] = (ChainLevelInfo)x[1]); + .When(x => x.PersistLevel(Arg.Any(), Arg.Any())) + .Do(x => persistedLevels[(ulong)x[0]] = (ChainLevelInfo)x[1]); SyncConfig syncConfig = new() { diff --git a/src/Nethermind/Nethermind.Runner/Monitoring/DataFeed.cs b/src/Nethermind/Nethermind.Runner/Monitoring/DataFeed.cs index 8fbcbbceea3f..4ace532c3ee8 100644 --- a/src/Nethermind/Nethermind.Runner/Monitoring/DataFeed.cs +++ b/src/Nethermind/Nethermind.Runner/Monitoring/DataFeed.cs @@ -399,18 +399,18 @@ private void OnForkChoiceUpdated(IBlockTree.ForkChoiceUpdateEventArgs choice) private class ForkData { public BlockForWeb Head { get; set; } - public long Safe { get; set; } - public long Finalized { get; set; } + public ulong Safe { get; set; } + public ulong Finalized { get; set; } } private class BlockForWeb { public byte[] ExtraData { get; set; } - public long GasLimit { get; set; } - public long GasUsed { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } public Hash256 Hash { get; set; } public Address Beneficiary { get; set; } - public long Number { get; set; } + public ulong Number { get; set; } public int Size { get; set; } public ulong Timestamp { get; set; } public UInt256 BaseFeePerGas { get; set; } @@ -422,7 +422,7 @@ private class BlockForWeb } private class ReceiptForWeb { - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public UInt256 EffectiveGasPrice { get; set; } public Address? ContractAddress { get; set; } public LogEntryForWeb[] Logs { get; set; } @@ -445,7 +445,7 @@ private class TransactionForWeb public UInt256 MaxPriorityFeePerGas { get; set; } public UInt256 MaxFeePerGas { get; set; } public UInt256 GasPrice { get; set; } - public long GasLimit { get; set; } + public ulong GasLimit { get; set; } public UInt256 Nonce { get; set; } public UInt256 Value { get; set; } public int DataLength { get; set; } @@ -461,7 +461,7 @@ private class PeerForWeb public AllocationContexts Contexts { get; set; } public NodeClientType ClientType { get; set; } public int Version { get; set; } - public long Head { get; set; } + public ulong Head { get; set; } } private DataCompletion _log = new(TaskCreationOptions.RunContinuationsAsynchronously); diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index 17fcc6d19cb8..f02d73ca4eaa 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -15,13 +15,13 @@ namespace Nethermind.Serialization.Json; /// Shared helpers for numeric JSON converters to avoid duplicating hex parsing and /// write logic across int/long/ulong converters. /// -internal static class NumericConverterHelper +public static class NumericConverterHelper { /// /// Parse a UTF-8 span that may be hex ("0x...") or decimal into . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T Parse(ReadOnlySpan s) where T : struct, INumberBase + public static T Parse(ReadOnlySpan s) where T : struct, INumberBase { if (s.Length == 0) { diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index f52c8995f18f..5f0152c5a0e6 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; +using System.Globalization; namespace Nethermind.Serialization.Json; @@ -15,6 +16,31 @@ public class ULongConverter : JsonConverter { public static ulong FromString(ReadOnlySpan s) => NumericConverterHelper.Parse(s); + public static ulong FromString(string s) + { + ArgumentNullException.ThrowIfNull(s); + + if (s == Nethermind.Core.Extensions.Bytes.ZeroHexValue) + { + return 0UL; + } + + if (s.StartsWith("0x0")) + { + return ulong.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); + } + + if (s.StartsWith("0x")) + { + Span withZero = new(new char[s.Length - 1]); + withZero[0] = '0'; + s.AsSpan(2).CopyTo(withZero[1..]); + return ulong.Parse(withZero, NumberStyles.AllowHexSpecifier); + } + + return ulong.Parse(s, NumberStyles.Integer); + } + [SkipLocalsInit] public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/AccountDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/AccountDecoder.cs index 9a8ed7fd4bbd..e286b5a82747 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/AccountDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/AccountDecoder.cs @@ -146,7 +146,7 @@ public int GetContentLength(Account? item) return null; } - UInt256 nonce = decoderContext.DecodeUInt256(); + ulong nonce = decoderContext.DecodeULong(); UInt256 balance = decoderContext.DecodeUInt256(); Hash256 storageRoot = DecodeStorageRoot(ref decoderContext); Hash256 codeHash = DecodeCodeHash(ref decoderContext); @@ -231,7 +231,7 @@ public bool TryDecodeStruct(ref Rlp.ValueDecoderContext decoderContext, out Acco return false; } - UInt256 nonce = decoderContext.DecodeUInt256(); + ulong nonce = decoderContext.DecodeULong(); UInt256 balance = decoderContext.DecodeUInt256(); ValueHash256 storageRoot = DecodeStorageRootStruct(ref decoderContext); ValueHash256 codeHash = DecodeCodeHashStruct(ref decoderContext); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/CompactReceiptStorageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/CompactReceiptStorageDecoder.cs index 0317aa985ed7..d03f7308a616 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/CompactReceiptStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/CompactReceiptStorageDecoder.cs @@ -41,7 +41,7 @@ public sealed class CompactReceiptStorageDecoder() : RlpDecoder, IRec } txReceipt.Sender = decoderContext.DecodeAddress(); - txReceipt.GasUsedTotal = decoderContext.DecodePositiveLong(); + txReceipt.GasUsedTotal = decoderContext.DecodeULong(); int sequenceLength = decoderContext.ReadSequenceLength(); int lastCheck = sequenceLength + decoderContext.Position; @@ -100,7 +100,7 @@ public void DecodeStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, R } decoderContext.DecodeAddressStructRef(out item.Sender); - item.GasUsedTotal = decoderContext.DecodePositiveLong(); + item.GasUsedTotal = decoderContext.DecodeULong(); (int PrefixLength, int ContentLength) = decoderContext.PeekPrefixAndContentLength(); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index df7d6237b87a..dd75251bb3e0 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -38,9 +38,9 @@ public sealed class HeaderDecoder() : RlpDecoder, IHeaderDecoder Hash256? receiptsRoot = decoderContext.DecodeKeccak(); Bloom? bloom = decoderContext.DecodeBloom(); UInt256 difficulty = decoderContext.DecodeUInt256(); - long number = decoderContext.DecodeLong(); - long gasLimit = decoderContext.DecodeLong(); - long gasUsed = decoderContext.DecodeLong(); + ulong number = decoderContext.DecodeULong(); + ulong gasLimit = decoderContext.DecodeULong(); + ulong gasUsed = decoderContext.DecodeULong(); ulong timestamp = decoderContext.DecodeULong(); byte[]? extraData = decoderContext.DecodeByteArray(); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs b/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs index 92f3178e2512..721e14b08f54 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs @@ -13,8 +13,9 @@ namespace Nethermind.Serialization.Rlp; public static class KeyValueStoreRlpExtensions { + [SkipLocalsInit] - public static TItem? Get(this IReadOnlyKeyValueStore db, long blockNumber, ValueHash256 hash, IRlpDecoder decoder, + public static TItem? Get(this IReadOnlyKeyValueStore db, ulong blockNumber, ValueHash256 hash, IRlpDecoder decoder, ClockCache cache = null, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) where TItem : class { Span dbKey = stackalloc byte[40]; @@ -31,6 +32,12 @@ public static class KeyValueStoreRlpExtensions return Get(db, key, keyDb, decoder, cache, rlpBehaviors, shouldCache); } + public static TItem? Get(this IReadOnlyKeyValueStore db, ulong key, IRlpDecoder? decoder, ClockCache? cache = null, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) where TItem : class + { + ReadOnlySpan keyDb = key.ToBigEndianSpanWithoutLeadingZeros(out _); + return Get(db, key, keyDb, decoder, cache, rlpBehaviors, shouldCache); + } + public static TItem? Get( this IReadOnlyKeyValueStore db, TCacheKey cacheKey, @@ -56,7 +63,7 @@ public static class KeyValueStoreRlpExtensions } [SkipLocalsInit] - public static TItem? Get(this IReadOnlyKeyValueStore db, long blockNumber, ValueHash256 hash, IRlpDecoder decoder, + public static TItem? Get(this IReadOnlyKeyValueStore db, ulong blockNumber, ValueHash256 hash, IRlpDecoder decoder, AssociativeCache cache = null, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) where TItem : class { Span dbKey = stackalloc byte[40]; diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs index a79ecb87a316..8757306c10b3 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs @@ -38,16 +38,16 @@ protected override TxReceipt DecodeInternal(ref Rlp.ValueDecoderContext ctx, Rlp if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; - txReceipt.GasUsedTotal = ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } else if (firstItem.Length is >= 1 and <= 4) { - txReceipt.GasUsedTotal = firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Hash256(firstItem); - txReceipt.GasUsedTotal = ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } if (!skipBloom) diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptRecoveryBlock.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptRecoveryBlock.cs index 6cbed3c015d3..924deac9fc72 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptRecoveryBlock.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptRecoveryBlock.cs @@ -63,7 +63,7 @@ public Transaction GetNextTransaction() } public readonly Hash256? Hash => Header.Hash; // do not add setter here - public readonly long Number => Header.Number; // do not add setter here + public readonly ulong Number => Header.Number; // do not add setter here public readonly void Dispose() => ((IMemoryOwner?)_memoryOwner)?.Dispose(); } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs index f72bbbd141a7..809bb9bbc89c 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs @@ -52,13 +52,13 @@ public ReceiptStorageDecoder() : this(true) } if (isStorage) txReceipt.BlockHash = decoderContext.DecodeKeccak(); - if (isStorage) txReceipt.BlockNumber = (long)decoderContext.DecodeUInt256(); + if (isStorage) txReceipt.BlockNumber = decoderContext.DecodeULong(); if (isStorage) txReceipt.Index = decoderContext.DecodePositiveInt(); if (isStorage) txReceipt.Sender = decoderContext.DecodeAddress(); if (isStorage) txReceipt.Recipient = decoderContext.DecodeAddress(); if (isStorage) txReceipt.ContractAddress = decoderContext.DecodeAddress(); - if (isStorage) txReceipt.GasUsed = decoderContext.DecodePositiveLong(); - txReceipt.GasUsedTotal = decoderContext.DecodePositiveLong(); + if (isStorage) txReceipt.GasUsed = decoderContext.DecodeULong(); + txReceipt.GasUsedTotal = decoderContext.DecodeULong(); txReceipt.Bloom = decoderContext.DecodeBloom(); int lastCheck = decoderContext.ReadSequenceLength() + decoderContext.Position; @@ -284,14 +284,14 @@ public void DecodeStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, R if (isStorage) { decoderContext.DecodeKeccakStructRef(out item.BlockHash); - item.BlockNumber = (long)decoderContext.DecodeUInt256(); + item.BlockNumber = decoderContext.DecodeULong(); item.Index = decoderContext.DecodePositiveInt(); decoderContext.DecodeAddressStructRef(out item.Sender); decoderContext.DecodeAddressStructRef(out item.Recipient); decoderContext.DecodeAddressStructRef(out item.ContractAddress); - item.GasUsed = decoderContext.DecodePositiveLong(); + item.GasUsed = decoderContext.DecodeULong(); } - item.GasUsedTotal = decoderContext.DecodePositiveLong(); + item.GasUsedTotal = decoderContext.DecodeULong(); decoderContext.DecodeBloomStructRef(out item.Bloom); (int PrefixLength, int ContentLength) = diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/BaseTxDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/BaseTxDecoder.cs index 8749ad6c4b7a..18321f7ec70f 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/BaseTxDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/BaseTxDecoder.cs @@ -88,9 +88,9 @@ public virtual int GetLength(Transaction transaction, RlpBehaviors rlpBehaviors, protected virtual void DecodePayload(Transaction transaction, ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { - transaction.Nonce = decoderContext.DecodeUInt256(); + transaction.Nonce = decoderContext.DecodeULong(); DecodeGasPrice(transaction, ref decoderContext); - transaction.GasLimit = decoderContext.DecodePositiveLong(); + transaction.GasLimit = decoderContext.DecodeULong(); transaction.To = decoderContext.DecodeAddress(); transaction.Value = decoderContext.DecodeUInt256(); transaction.Data = decoderContext.DecodeByteArrayMemory(_dataRlpLimit); @@ -115,7 +115,7 @@ protected virtual void EncodePayload(Transaction transaction, RlpStream stream, EncodeGasPrice(transaction, stream); stream.Encode(transaction.GasLimit); stream.Encode(transaction.To); - stream.Encode(in transaction.ValueRef); + stream.Encode(transaction.ValueRef); stream.Encode(transaction.Data); } @@ -129,7 +129,7 @@ protected virtual int GetPayloadLength(Transaction transaction) => + Rlp.LengthOf(transaction.GasPrice) + Rlp.LengthOf(transaction.GasLimit) + Rlp.LengthOf(transaction.To) - + Rlp.LengthOf(in transaction.ValueRef) + + Rlp.LengthOf(transaction.ValueRef) + Rlp.LengthOf(transaction.Data); protected virtual int GetSignatureLength(Signature? signature, bool forSigning, bool isEip155Enabled = false, ulong chainId = 0) diff --git a/src/Nethermind/Nethermind.Shutter/ShutterEon.cs b/src/Nethermind/Nethermind.Shutter/ShutterEon.cs index fe4fdcdc1f10..75d82a59bc27 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterEon.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterEon.cs @@ -34,7 +34,7 @@ public void Update(BlockHeader header) try { KeyperSetManagerContract keyperSetManagerContract = new(processor, abiEncoder, _keyperSetManagerContractAddress); - ulong eon = keyperSetManagerContract.GetKeyperSetIndexByBlock(header, (ulong)header.Number + 1); + ulong eon = keyperSetManagerContract.GetKeyperSetIndexByBlock(header, header.Number + 1); if (_currentInfo is null || _currentInfo.Value.Eon != eon) { diff --git a/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs b/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs index 0a6ae98877a7..9f19fcc8643b 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterTxLoader.cs @@ -197,7 +197,7 @@ private Transaction DecodeTransaction(ReadOnlySpan encoded) return tx; } - private IEnumerable GetNextTransactions(ulong eon, ulong txPointer, long headBlockNumber) + private IEnumerable GetNextTransactions(ulong eon, ulong txPointer, ulong headBlockNumber) { lock (_events) { @@ -242,7 +242,7 @@ private static SequencedTransaction EventToSequencedTransaction(ISequencerContra }; } - private void LoadFromScanningLogs(ulong eon, ulong txPointer, long headBlockNumber) + private void LoadFromScanningLogs(ulong eon, ulong txPointer, ulong headBlockNumber) { _txPointer = txPointer; diff --git a/src/Nethermind/Nethermind.Shutter/ShutterTxSource.cs b/src/Nethermind/Nethermind.Shutter/ShutterTxSource.cs index 4153466a52a8..f6e815feaae6 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterTxSource.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterTxSource.cs @@ -30,7 +30,7 @@ public class ShutterTxSource( public bool SupportsBlobs => false; - public IEnumerable GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) + public IEnumerable GetTransactions(BlockHeader parent, ulong gasLimit, PayloadAttributes? payloadAttributes = null, bool filterSource = false) { if (!shutterConfig.Validator) { diff --git a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs index 3babb6ea3da3..d422afa7eb74 100644 --- a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs @@ -80,16 +80,16 @@ private static ChainSpec LoadGethGenesisWithBlobSchedule(string forkTimestamps, return LoadGethGenesisFromString(genesisJson); } - [TestCase(0, null, false)] - [TestCase(0, 0ul, false)] - [TestCase(0, 4660ul, false)] - [TestCase(1, 4660ul, false)] - [TestCase(1, 4661ul, false)] - [TestCase(4, 4672ul, true)] - [TestCase(4, 4673ul, true)] - [TestCase(5, 4680ul, true)] + [TestCase(0ul, null, false)] + [TestCase(0ul, 0ul, false)] + [TestCase(0ul, 4660ul, false)] + [TestCase(1ul, 4660ul, false)] + [TestCase(1ul, 4661ul, false)] + [TestCase(4ul, 4672ul, true)] + [TestCase(4ul, 4673ul, true)] + [TestCase(5ul, 4680ul, true)] [NonParallelizable] - public void Timestamp_activation_equal_to_genesis_timestamp_loads_correctly(long blockNumber, ulong? timestamp, bool isEip3855Enabled) + public void Timestamp_activation_equal_to_genesis_timestamp_loads_correctly(ulong blockNumber, ulong? timestamp, bool isEip3855Enabled) { ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); string path = Path.Combine(TestContext.CurrentContext.WorkDirectory, @@ -133,20 +133,20 @@ public void Missing_dependent_property() } - [TestCase(0, null, false, false, false)] - [TestCase(0, 0ul, false, false, false)] - [TestCase(0, 4660ul, false, false, false)] - [TestCase(1, 4660ul, false, false, false)] - [TestCase(1, 4661ul, false, false, false)] - [TestCase(1, 4672ul, false, false, false)] - [TestCase(2, 4673ul, false, false, true)] - [TestCase(3, 4680ul, false, false, true)] - [TestCase(4, 4672ul, false, true, false)] - [TestCase(5, 4672ul, true, true, false)] - [TestCase(5, 4673ul, true, true, false)] - [TestCase(6, 4680ul, true, true, false)] + [TestCase(0ul, null, false, false, false)] + [TestCase(0ul, 0ul, false, false, false)] + [TestCase(0ul, 4660ul, false, false, false)] + [TestCase(1ul, 4660ul, false, false, false)] + [TestCase(1ul, 4661ul, false, false, false)] + [TestCase(1ul, 4672ul, false, false, false)] + [TestCase(2ul, 4673ul, false, false, true)] + [TestCase(3ul, 4680ul, false, false, true)] + [TestCase(4ul, 4672ul, false, true, false)] + [TestCase(5ul, 4672ul, true, true, false)] + [TestCase(5ul, 4673ul, true, true, false)] + [TestCase(6ul, 4680ul, true, true, false)] [NonParallelizable] - public void Logs_warning_when_timestampActivation_happens_before_blockActivation(long blockNumber, ulong? timestamp, bool isEip3855Enabled, bool isEip3198Enabled, bool receivesWarning) + public void Logs_warning_when_timestampActivation_happens_before_blockActivation(ulong blockNumber, ulong? timestamp, bool isEip3855Enabled, bool isEip3198Enabled, bool receivesWarning) { ChainSpecFileLoader loader = new(new EthereumJsonSerializer(), LimboLogs.Instance); string path = Path.Combine(TestContext.CurrentContext.WorkDirectory, @@ -673,7 +673,7 @@ private static void CompareSpecs( { IReleaseSpec oldSpec = oldSpecProvider.GetSpec(activation); IReleaseSpec newSpec = newSpecProvider.GetSpec(activation); - long? daoBlockNumber = newSpecProvider.DaoBlockNumber; + ulong? daoBlockNumber = newSpecProvider.DaoBlockNumber; bool isMainnet = daoBlockNumber is not null; if (isMainnet) @@ -1255,11 +1255,11 @@ public static IEnumerable BlobScheduleActivationsTestCaseSource { const int NoneAllowed = 0; const int Default = 6; - static TestCaseData MakeTestCase(string testName, int eip4844Timestamp, int eip7002Timestamp, (int timestamp, int max)[] settings, ulong[] expectedActivationSettings) + static TestCaseData MakeTestCase(string testName, ulong eip4844Timestamp, ulong eip7002Timestamp, (ulong timestamp, ulong max)[] settings, ulong[] expectedActivationSettings) => new([ - (ulong)eip4844Timestamp, - (ulong)eip7002Timestamp, - settings.Select(s => new BlobScheduleSettings { Timestamp = (ulong)s.timestamp, Max = (ulong)s.max }).ToArray(), + eip4844Timestamp, + eip7002Timestamp, + settings.Select(s => new BlobScheduleSettings { Timestamp = s.timestamp, Max = s.max }).ToArray(), expectedActivationSettings]) { TestName = $"BlobScheduleActivations: {testName}" }; diff --git a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/GethGenesisLoaderTests.cs b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/GethGenesisLoaderTests.cs index 6e95fe28b038..7deeb2158880 100644 --- a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/GethGenesisLoaderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/GethGenesisLoaderTests.cs @@ -313,7 +313,7 @@ public void Can_load_genesis_with_account_storage_and_code() ChainSpecAllocation allocation = chainSpec.Allocations[address]; Assert.That(allocation.Balance, Is.EqualTo(UInt256.Parse("1000000000000000000"))); // 1 ETH in wei - Assert.That(allocation.Nonce, Is.EqualTo(UInt256.One)); + Assert.That(allocation.Nonce, Is.EqualTo(1UL)); Assert.That(allocation.Code, Is.EqualTo(new byte[] { 0x60, 0x80, 0x60, 0x40, 0x52 })); Assert.That(allocation.Storage!.Count, Is.EqualTo(1)); } diff --git a/src/Nethermind/Nethermind.Specs.Test/CustomSpecProvider.cs b/src/Nethermind/Nethermind.Specs.Test/CustomSpecProvider.cs index af02f334a6fc..a2a2fdf29770 100644 --- a/src/Nethermind/Nethermind.Specs.Test/CustomSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs.Test/CustomSpecProvider.cs @@ -33,10 +33,10 @@ public CustomSpecProvider(ulong networkId, ulong chainId, params (ForkActivation TransitionActivations = orderedTransitions.Select(static t => t.Activation).ToArray(); } - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) - _theMergeBlock = (ForkActivation)blockNumber; + _theMergeBlock = (ForkActivation)blockNumber.Value; if (terminalTotalDifficulty is not null) TerminalTotalDifficulty = terminalTotalDifficulty; } @@ -46,7 +46,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public ulong TimestampFork { get; set; } = ISpecProvider.TimestampForkNever; public UInt256? TerminalTotalDifficulty { get; set; } - public long? DaoBlockNumber + public ulong? DaoBlockNumber { get { diff --git a/src/Nethermind/Nethermind.Specs.Test/CustomSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/CustomSpecProviderTests.cs index 3a6915d7bc72..f94ab10578b9 100644 --- a/src/Nethermind/Nethermind.Specs.Test/CustomSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/CustomSpecProviderTests.cs @@ -27,7 +27,7 @@ public void When_only_one_release_is_specified_then_returns_that_release() [Test] public void Can_find_dao_block_number() { - long daoBlockNumber = 100; + ulong daoBlockNumber = 100; CustomSpecProvider specProvider = new( ((ForkActivation)0L, Frontier.Instance), ((ForkActivation)daoBlockNumber, Dao.Instance)); diff --git a/src/Nethermind/Nethermind.Specs.Test/ForkScheduleSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/ForkScheduleSpecProviderTests.cs index 6ca1dcda63c4..a79773275684 100644 --- a/src/Nethermind/Nethermind.Specs.Test/ForkScheduleSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/ForkScheduleSpecProviderTests.cs @@ -19,12 +19,12 @@ public void Fork_schedule_is_in_ascending_activation_order(ForkScheduleSpecProvi { ForkSpec[] schedule = provider.ForkSchedule; - long previousBlock = long.MinValue; + ulong previousBlock = 0UL; ulong? previousTimestamp = null; foreach (ForkSpec fork in schedule) { - if (fork.Block is long block) + if (fork.Block is ulong block) { Assert.That(previousTimestamp, Is.Null, "block-keyed forks must come before any timestamp-keyed fork"); diff --git a/src/Nethermind/Nethermind.Specs.Test/MainnetSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/MainnetSpecProviderTests.cs index 760007dd89f0..56f041d55fe3 100644 --- a/src/Nethermind/Nethermind.Specs.Test/MainnetSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/MainnetSpecProviderTests.cs @@ -12,9 +12,9 @@ public class MainnetSpecProviderTests { private readonly ISpecProvider _specProvider = MainnetSpecProvider.Instance; - [TestCase(12_243_999, false)] - [TestCase(12_244_000, true)] - public void Berlin_eips(long blockNumber, bool isEnabled) + [TestCase(12_243_999ul, false)] + [TestCase(12_244_000ul, true)] + public void Berlin_eips(ulong blockNumber, bool isEnabled) { Assert.That(_specProvider.GetSpec((ForkActivation)blockNumber).IsEip2537Enabled, Is.EqualTo(false)); Assert.That(_specProvider.GetSpec((ForkActivation)blockNumber).IsEip2565Enabled, Is.EqualTo(isEnabled)); @@ -22,9 +22,9 @@ public void Berlin_eips(long blockNumber, bool isEnabled) Assert.That(_specProvider.GetSpec((ForkActivation)blockNumber).IsEip2930Enabled, Is.EqualTo(isEnabled)); } - [TestCase(12_964_999, false)] - [TestCase(12_965_000, true)] - public void London_eips(long blockNumber, bool isEnabled) + [TestCase(12_964_999ul, false)] + [TestCase(12_965_000ul, true)] + public void London_eips(ulong blockNumber, bool isEnabled) { if (isEnabled) Assert.That(_specProvider.GetSpec((ForkActivation)blockNumber).DifficultyBombDelay, Is.EqualTo(London.Instance.DifficultyBombDelay)); @@ -39,7 +39,7 @@ public void London_eips(long blockNumber, bool isEnabled) [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.ShanghaiBlockTimestamp, false)] [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.CancunBlockTimestamp, true)] - public void Cancun_eips(long blockNumber, ulong timestamp, bool isEnabled) + public void Cancun_eips(ulong blockNumber, ulong timestamp, bool isEnabled) { Assert.That(_specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)).IsEip1153Enabled, Is.EqualTo(isEnabled)); Assert.That(_specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)).IsEip4844Enabled, Is.EqualTo(isEnabled)); @@ -57,7 +57,7 @@ public void Cancun_eips(long blockNumber, ulong timestamp, bool isEnabled) [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.CancunBlockTimestamp, false)] [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.PragueBlockTimestamp, true)] - public void Prague_eips(long blockNumber, ulong timestamp, bool isEnabled) + public void Prague_eips(ulong blockNumber, ulong timestamp, bool isEnabled) { Assert.That(_specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)).IsEip2935Enabled, Is.EqualTo(isEnabled)); if (isEnabled) @@ -72,7 +72,7 @@ public void Prague_eips(long blockNumber, ulong timestamp, bool isEnabled) [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.PragueBlockTimestamp, false)] [TestCase(MainnetSpecProvider.ParisBlockNumber, MainnetSpecProvider.OsakaBlockTimestamp, true)] - public void Osaka_eips(long blockNumber, ulong timestamp, bool isEnabled) + public void Osaka_eips(ulong blockNumber, ulong timestamp, bool isEnabled) { Assert.That(_specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)).IsEip7594Enabled, Is.EqualTo(isEnabled)); Assert.That(_specProvider.GetSpec(new ForkActivation(blockNumber, timestamp)).IsEip7823Enabled, Is.EqualTo(isEnabled)); @@ -85,6 +85,6 @@ public void Osaka_eips(long blockNumber, ulong timestamp, bool isEnabled) } [Test] - public void Dao_block_number_is_correct() => Assert.That(_specProvider.DaoBlockNumber, Is.EqualTo(1920000L)); + public void Dao_block_number_is_correct() => Assert.That(_specProvider.DaoBlockNumber, Is.EqualTo(1920000UL)); } } diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index c2e63f31ece3..74c2672d7a03 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -18,14 +18,14 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public string Name => "OverridableReleaseSpec"; public long MaximumExtraDataSize { get; set; } = spec.MaximumExtraDataSize; public long MaxCodeSize { get; set; } = spec.MaxCodeSize; - public long MinGasLimit { get; set; } = spec.MinGasLimit; + public ulong MinGasLimit { get; set; } = spec.MinGasLimit; public long MinHistoryRetentionEpochs { get; set; } = spec.MinHistoryRetentionEpochs; public long MinBalRetentionEpochs { get; set; } = spec.MinBalRetentionEpochs; - public long GasLimitBoundDivisor { get; set; } = spec.GasLimitBoundDivisor; + public ulong GasLimitBoundDivisor { get; set; } = spec.GasLimitBoundDivisor; public UInt256 BlockReward { get; set; } = spec.BlockReward; - public long DifficultyBombDelay { get; set; } = spec.DifficultyBombDelay; - public long DifficultyBoundDivisor { get; set; } = spec.DifficultyBoundDivisor; - public long? FixedDifficulty { get; set; } = spec.FixedDifficulty; + public ulong DifficultyBombDelay { get; set; } = spec.DifficultyBombDelay; + public ulong DifficultyBoundDivisor { get; set; } = spec.DifficultyBoundDivisor; + public ulong? FixedDifficulty { get; set; } = spec.FixedDifficulty; public int MaximumUncleCount { get; set; } = spec.MaximumUncleCount; public bool IsTimeAdjustmentPostOlympic { get; set; } = spec.IsTimeAdjustmentPostOlympic; public bool IsEip2Enabled { get; set; } = spec.IsEip2Enabled; @@ -82,7 +82,7 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public UInt256? Eip1559BaseFeeMinValue { get; set; } = spec.Eip1559BaseFeeMinValue; public bool IsEip3607Enabled { get; set; } = spec.IsEip3607Enabled; public Address? Eip158IgnoredAccount { get; set; } = spec.Eip158IgnoredAccount; - public long Eip1559TransitionBlock { get; set; } = spec.Eip1559TransitionBlock; + public ulong Eip1559TransitionBlock { get; set; } = spec.Eip1559TransitionBlock; public Address? FeeCollector { get; set; } = spec.FeeCollector; public ulong Eip4844TransitionTimestamp { get; set; } = spec.Eip4844TransitionTimestamp; public ulong TargetBlobCount { get; set; } = spec.TargetBlobCount; @@ -96,7 +96,7 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public bool IsEip4895Enabled { get; set; } = spec.IsEip4895Enabled; public ulong WithdrawalTimestamp { get; set; } = spec.WithdrawalTimestamp; public bool IsEip5656Enabled { get; set; } = spec.IsEip5656Enabled; - public long Eip2935RingBufferSize { get; set; } = spec.Eip2935RingBufferSize; + public ulong Eip2935RingBufferSize { get; set; } = spec.Eip2935RingBufferSize; public bool IsEip6780Enabled { get; set; } = spec.IsEip6780Enabled; public bool IsEip4788Enabled { get; set; } = spec.IsEip4788Enabled; public bool IsEip4844FeeCollectorEnabled { get; set; } = spec.IsEip4844FeeCollectorEnabled; diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableSpecProvider.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableSpecProvider.cs index 64af5d2d5b66..a1088b2f3980 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableSpecProvider.cs @@ -24,7 +24,7 @@ public OverridableSpecProvider(ISpecProvider specProvider, Func SpecProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => SpecProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public ForkActivation? MergeBlockNumber => SpecProvider.MergeBlockNumber; @@ -36,7 +36,7 @@ public OverridableSpecProvider(ISpecProvider specProvider, Func _overrideAction(SpecProvider.GetSpec(forkActivation), forkActivation); - public long? DaoBlockNumber => SpecProvider.DaoBlockNumber; + public ulong? DaoBlockNumber => SpecProvider.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => SpecProvider.BeaconChainGenesisTimestamp; public ulong NetworkId => SpecProvider.NetworkId; public ulong ChainId => SpecProvider.ChainId; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs index c42d9f609ad8..cd61ee71558f 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs @@ -12,51 +12,51 @@ namespace Nethermind.Specs.ChainSpecStyle; public class ChainParameters { public long? MaxCodeSize { get; set; } - public long? MaxCodeSizeTransition { get; set; } + public ulong? MaxCodeSizeTransition { get; set; } public ulong? MaxCodeSizeTransitionTimestamp { get; set; } - public long GasLimitBoundDivisor { get; set; } + public ulong GasLimitBoundDivisor { get; set; } public Address Registrar { get; set; } public long MaximumExtraDataSize { get; set; } - public long MinGasLimit { get; set; } + public ulong MinGasLimit { get; set; } public long MinHistoryRetentionEpochs { get; set; } public long MinBalRetentionEpochs { get; set; } public Hash256 ForkCanonHash { get; set; } - public long? ForkBlock { get; set; } - public long? Eip7Transition { get; set; } - public long? Eip150Transition { get; set; } - public long? Eip152Transition { get; set; } - public long? Eip160Transition { get; set; } - public long? Eip161abcTransition { get; set; } - public long? Eip161dTransition { get; set; } - public long? Eip155Transition { get; set; } - public long? Eip140Transition { get; set; } - public long? Eip211Transition { get; set; } - public long? Eip214Transition { get; set; } - public long? Eip658Transition { get; set; } - public long? Eip145Transition { get; set; } - public long? Eip1014Transition { get; set; } - public long? Eip1052Transition { get; set; } - public long? Eip1108Transition { get; set; } - public long? Eip1283Transition { get; set; } - public long? Eip1283DisableTransition { get; set; } - public long? Eip1283ReenableTransition { get; set; } - public long? Eip1344Transition { get; set; } - public long? Eip1706Transition { get; set; } - public long? Eip1884Transition { get; set; } - public long? Eip2028Transition { get; set; } - public long? Eip2200Transition { get; set; } - public long? Eip1559Transition { get; set; } - public long? Eip2315Transition { get; set; } - public long? Eip2537Transition { get; set; } + public ulong? ForkBlock { get; set; } + public ulong? Eip7Transition { get; set; } + public ulong? Eip150Transition { get; set; } + public ulong? Eip152Transition { get; set; } + public ulong? Eip160Transition { get; set; } + public ulong? Eip161abcTransition { get; set; } + public ulong? Eip161dTransition { get; set; } + public ulong? Eip155Transition { get; set; } + public ulong? Eip140Transition { get; set; } + public ulong? Eip211Transition { get; set; } + public ulong? Eip214Transition { get; set; } + public ulong? Eip658Transition { get; set; } + public ulong? Eip145Transition { get; set; } + public ulong? Eip1014Transition { get; set; } + public ulong? Eip1052Transition { get; set; } + public ulong? Eip1108Transition { get; set; } + public ulong? Eip1283Transition { get; set; } + public ulong? Eip1283DisableTransition { get; set; } + public ulong? Eip1283ReenableTransition { get; set; } + public ulong? Eip1344Transition { get; set; } + public ulong? Eip1706Transition { get; set; } + public ulong? Eip1884Transition { get; set; } + public ulong? Eip2028Transition { get; set; } + public ulong? Eip2200Transition { get; set; } + public ulong? Eip1559Transition { get; set; } + public ulong? Eip2315Transition { get; set; } + public ulong? Eip2537Transition { get; set; } public ulong? Eip2537TransitionTimestamp { get; set; } - public long? Eip2565Transition { get; set; } - public long? Eip2929Transition { get; set; } - public long? Eip2930Transition { get; set; } - public long? Eip3198Transition { get; set; } - public long? Eip3529Transition { get; set; } + public ulong? Eip2565Transition { get; set; } + public ulong? Eip2929Transition { get; set; } + public ulong? Eip2930Transition { get; set; } + public ulong? Eip3198Transition { get; set; } + public ulong? Eip3529Transition { get; set; } - public long? Eip3541Transition { get; set; } - public long? Eip3607Transition { get; set; } + public ulong? Eip3541Transition { get; set; } + public ulong? Eip3607Transition { get; set; } public UInt256? Eip1559BaseFeeInitialValue { get; set; } @@ -71,25 +71,25 @@ public class ChainParameters /// /// Block at which the transaction permission contract should start being used. /// - public long? TransactionPermissionContractTransition { get; set; } + public ulong? TransactionPermissionContractTransition { get; set; } /// /// Optional, will be included for block 0 by default - Block before which any chain_id in the signature of a replay-protected transaction is accepted. - /// After this transition block, the transactions’ chain_id must match with the spec chain_id to be considered valid. + /// After this transition block, the transactions' chain_id must match with the spec chain_id to be considered valid. /// /// Backward compatibility for early Kovan blocks. - public long? ValidateChainIdTransition { get; set; } + public ulong? ValidateChainIdTransition { get; set; } /// - /// Optional, will be included for block 0 by default - Transition block before which the state root in transaction’s receipt can be stripped. + /// Optional, will be included for block 0 by default - Transition block before which the state root in transaction's receipt can be stripped. /// /// - public long? ValidateReceiptsTransition { get; set; } + public ulong? ValidateReceiptsTransition { get; set; } /// /// Block from which burnt EIP-1559 fees will go to /// - public long? Eip1559FeeCollectorTransition { get; set; } + public ulong? Eip1559FeeCollectorTransition { get; set; } /// /// Optional, address where burnt EIP-1559 fees will go @@ -99,33 +99,33 @@ public class ChainParameters /// /// Block from which EIP1559 base fee cannot drop below /// - public long? Eip1559BaseFeeMinValueTransition { get; set; } + public ulong? Eip1559BaseFeeMinValueTransition { get; set; } /// /// Optional, minimal value of EIP1559 base fee /// public UInt256? Eip1559BaseFeeMinValue { get; set; } - public long? MergeForkIdTransition { get; set; } + public ulong? MergeForkIdTransition { get; set; } - public long? TerminalPoWBlockNumber { get; set; } + public ulong? TerminalPoWBlockNumber { get; set; } public UInt256? TerminalTotalDifficulty { get; set; } public ulong? BeaconChainGenesisTimestamp { get; set; } - public long? Eip3651Transition { get; set; } + public ulong? Eip3651Transition { get; set; } public ulong? Eip3651TransitionTimestamp { get; set; } - public long? Eip3855Transition { get; set; } + public ulong? Eip3855Transition { get; set; } public ulong? Eip3855TransitionTimestamp { get; set; } - public long? Eip3860Transition { get; set; } + public ulong? Eip3860Transition { get; set; } public ulong? Eip3860TransitionTimestamp { get; set; } public ulong? Eip4895TransitionTimestamp { get; set; } public ulong? Eip4844TransitionTimestamp { get; set; } - public long? Eip4844Transition { get; set; } - public long? Eip1153Transition { get; set; } + public ulong? Eip4844Transition { get; set; } + public ulong? Eip1153Transition { get; set; } public ulong? Eip1153TransitionTimestamp { get; set; } - public long? Eip5656Transition { get; set; } + public ulong? Eip5656Transition { get; set; } public ulong? Eip5656TransitionTimestamp { get; set; } - public long? Eip6780Transition { get; set; } + public ulong? Eip6780Transition { get; set; } public ulong? Eip6780TransitionTimestamp { get; set; } public ulong? Eip4788TransitionTimestamp { get; set; } public Address Eip4788ContractAddress { get; set; } @@ -137,7 +137,7 @@ public class ChainParameters public Address Eip7251ContractAddress { get; set; } public ulong? Eip2935TransitionTimestamp { get; set; } public Address Eip2935ContractAddress { get; set; } - public long Eip2935RingBufferSize { get; set; } = Eip2935Constants.RingBufferSize; + public ulong Eip2935RingBufferSize { get; set; } = Eip2935Constants.RingBufferSize; public ulong? Eip7951TransitionTimestamp { get; set; } public ulong? Rip7212TransitionTimestamp { get; set; } public ulong? Eip7702TransitionTimestamp { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs index ee3133cf23fd..bdfebddc157b 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs @@ -42,35 +42,35 @@ public class ChainSpec public long? FixedDifficulty { get; set; } - public long? DaoForkBlockNumber { get; set; } + public ulong? DaoForkBlockNumber { get; set; } - public long? HomesteadBlockNumber { get; set; } + public ulong? HomesteadBlockNumber { get; set; } - public long? TangerineWhistleBlockNumber { get; set; } + public ulong? TangerineWhistleBlockNumber { get; set; } - public long? SpuriousDragonBlockNumber { get; set; } + public ulong? SpuriousDragonBlockNumber { get; set; } - public long? ByzantiumBlockNumber { get; set; } + public ulong? ByzantiumBlockNumber { get; set; } - public long? ConstantinopleBlockNumber { get; set; } + public ulong? ConstantinopleBlockNumber { get; set; } - public long? ConstantinopleFixBlockNumber { get; set; } + public ulong? ConstantinopleFixBlockNumber { get; set; } - public long? IstanbulBlockNumber { get; set; } + public ulong? IstanbulBlockNumber { get; set; } - public long? MuirGlacierNumber { get; set; } + public ulong? MuirGlacierNumber { get; set; } - public long? BerlinBlockNumber { get; set; } + public ulong? BerlinBlockNumber { get; set; } - public long? LondonBlockNumber { get; set; } + public ulong? LondonBlockNumber { get; set; } - public long? ArrowGlacierBlockNumber { get; set; } + public ulong? ArrowGlacierBlockNumber { get; set; } - public long? GrayGlacierBlockNumber { get; set; } + public ulong? GrayGlacierBlockNumber { get; set; } - public long? MergeForkIdBlockNumber { get; set; } + public ulong? MergeForkIdBlockNumber { get; set; } - public long? TerminalPoWBlockNumber { get; set; } + public ulong? TerminalPoWBlockNumber { get; set; } public UInt256? TerminalTotalDifficulty { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecAllocation.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecAllocation.cs index 2a0e1f787496..e8348450f1cb 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecAllocation.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecAllocation.cs @@ -14,7 +14,7 @@ public ChainSpecAllocation() public ChainSpecAllocation(UInt256 allocationValue) => Balance = allocationValue; - public ChainSpecAllocation(UInt256 allocationValue, UInt256 nonce, byte[]? code, byte[]? constructor, Dictionary? storage) + public ChainSpecAllocation(UInt256 allocationValue, ulong nonce, byte[]? code, byte[]? constructor, Dictionary? storage) { Balance = allocationValue; Nonce = nonce; @@ -25,7 +25,7 @@ public ChainSpecAllocation(UInt256 allocationValue, UInt256 nonce, byte[]? code, public UInt256 Balance { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public byte[]? Code { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs index 95893bc8e2ea..b85cdd91d7b0 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs @@ -33,9 +33,9 @@ public ChainSpecBasedSpecProvider(ChainSpec chainSpec, ILogManager? logManager = private void BuildTransitions() { - SortedSet transitionBlockNumbers = []; + SortedSet transitionBlockNumbers = []; SortedSet transitionTimestamps = []; - transitionBlockNumbers.Add(0L); + transitionBlockNumbers.Add(0); foreach (IChainSpecEngineParameters item in _chainSpec.EngineChainSpecParametersProvider .AllChainSpecParameters) @@ -43,12 +43,14 @@ private void BuildTransitions() item.AddTransitions(transitionBlockNumbers, transitionTimestamps); } + // All block-number properties on ChainSpec and ChainParameters are now ulong?. AddTransitions(transitionBlockNumbers, _chainSpec, static n => n.EndsWith("BlockNumber") && n != "TerminalPoWBlockNumber"); AddTransitions(transitionBlockNumbers, _chainSpec.Parameters, static n => n.EndsWith("Transition")); AddTransitions(transitionTimestamps, _chainSpec.Parameters, static n => n.EndsWith("TransitionTimestamp"), _chainSpec.Genesis?.Timestamp ?? 0); AddBlobScheduleTransitions(transitionTimestamps, _chainSpec); TimestampFork = transitionTimestamps.Count > 0 ? transitionTimestamps.Min : ISpecProvider.TimestampForkNever; + // Scans properties of type T / T? on value whose names pass the filter. static void AddTransitions( SortedSet transitions, object value, @@ -130,7 +132,7 @@ static void AddBlobScheduleTransitions(SortedSet transitions, ChainSpec c if (_chainSpec.Parameters.TerminalPoWBlockNumber is not null) { - MergeBlockNumber = (ForkActivation)(_chainSpec.Parameters.TerminalPoWBlockNumber + 1); + MergeBlockNumber = (ForkActivation)(_chainSpec.Parameters.TerminalPoWBlockNumber.Value + 1); } TerminalTotalDifficulty = _chainSpec.Parameters.TerminalTotalDifficulty; @@ -170,14 +172,14 @@ public static void RegisterProvider(IForkAwareSpecProvider provider) private (ForkActivation, IReleaseSpec Spec)[] CreateTransitions( ChainSpec chainSpec, - SortedSet transitionBlockNumbers, + SortedSet transitionBlockNumbers, SortedSet transitionTimestamps) { (ForkActivation Activation, IReleaseSpec Spec)[] transitions = new (ForkActivation, IReleaseSpec Spec)[transitionBlockNumbers.Count + transitionTimestamps.Count]; - long biggestBlockTransition = transitionBlockNumbers.Max; + ulong biggestBlockTransition = transitionBlockNumbers.Max; int index = 0; - foreach (long releaseStartBlock in transitionBlockNumbers) + foreach (ulong releaseStartBlock in transitionBlockNumbers) { IReleaseSpec releaseSpec = CreateReleaseSpec(chainSpec, releaseStartBlock, chainSpec.Genesis?.Timestamp ?? 0); transitions[index++] = ((ForkActivation)releaseStartBlock, releaseSpec); @@ -185,23 +187,22 @@ public static void RegisterProvider(IForkAwareSpecProvider provider) foreach (ulong releaseStartTimestamp in transitionTimestamps) { - long activationBlockNumber = biggestBlockTransition; - ForkActivation forkActivation = (activationBlockNumber, releaseStartTimestamp); - IReleaseSpec releaseSpec = CreateReleaseSpec(chainSpec, activationBlockNumber, releaseStartTimestamp); + ForkActivation forkActivation = (biggestBlockTransition, releaseStartTimestamp); + IReleaseSpec releaseSpec = CreateReleaseSpec(chainSpec, biggestBlockTransition, releaseStartTimestamp); transitions[index++] = (forkActivation, releaseSpec); } return transitions; } - private static ForkActivation[] CreateTransitionActivations(SortedSet transitionBlockNumbers, SortedSet transitionTimestamps) + private static ForkActivation[] CreateTransitionActivations(SortedSet transitionBlockNumbers, SortedSet transitionTimestamps) { - long biggestBlockTransition = transitionBlockNumbers.Max; + ulong biggestBlockTransition = transitionBlockNumbers.Max; ForkActivation[] transitionActivations = new ForkActivation[transitionBlockNumbers.Count - 1 + transitionTimestamps.Count]; int index = 0; - foreach (long blockNumber in transitionBlockNumbers.Skip(1)) + foreach (ulong blockNumber in transitionBlockNumbers.Skip(1)) { transitionActivations[index++] = new ForkActivation(blockNumber); } @@ -214,10 +215,17 @@ private static ForkActivation[] CreateTransitionActivations(SortedSet tran return transitionActivations; } - protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releaseStartBlock, ulong? releaseStartTimestamp = null) + // Returns the activation block number for a ChainParameters ulong? transition field, + // or the sentinel when the field is null. + // "never" sentinel: ulong.MaxValue (all callers use <= so ulong.MaxValue is never reached). + // "from genesis" sentinel: 0 (used for EIPs that activate at block 0 when present). + private static ulong BlockOf(ulong? transition, ulong nullSentinel = ulong.MaxValue) => + transition ?? nullSentinel; + + protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, ulong releaseStartBlock, ulong? releaseStartTimestamp = null) { + ulong block = releaseStartBlock; ReleaseSpec releaseSpec = CreateEmptyReleaseSpec(); - // EIP-3675: zero uncles post-merge. Runtime fallback is MergeHeaderValidator. releaseSpec.MaximumUncleCount = IsPostMergeRelease(chainSpec, releaseStartBlock, releaseStartTimestamp) ? 0 : 2; releaseSpec.DifficultyBoundDivisor = 1; releaseSpec.IsTimeAdjustmentPostOlympic = true; // TODO: this is Duration, review @@ -226,65 +234,74 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas releaseSpec.MinHistoryRetentionEpochs = chainSpec.Parameters.MinHistoryRetentionEpochs; releaseSpec.MinBalRetentionEpochs = chainSpec.Parameters.MinBalRetentionEpochs; releaseSpec.GasLimitBoundDivisor = chainSpec.Parameters.GasLimitBoundDivisor; - releaseSpec.IsEip170Enabled = (chainSpec.Parameters.MaxCodeSizeTransition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip170Enabled = BlockOf(chainSpec.Parameters.MaxCodeSizeTransition) <= block || (chainSpec.Parameters.MaxCodeSizeTransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.MaxCodeSize = releaseSpec.IsEip170Enabled ? (chainSpec.Parameters.MaxCodeSize ?? long.MaxValue) : long.MaxValue; releaseSpec.IsEip2Enabled = true; releaseSpec.IsEip100Enabled = true; - releaseSpec.IsEip7Enabled = (chainSpec.Parameters.Eip7Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip140Enabled = (chainSpec.Parameters.Eip140Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip145Enabled = (chainSpec.Parameters.Eip145Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip150Enabled = (chainSpec.Parameters.Eip150Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip152Enabled = (chainSpec.Parameters.Eip152Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip155Enabled = (chainSpec.Parameters.Eip155Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip160Enabled = (chainSpec.Parameters.Eip160Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip158Enabled = (chainSpec.Parameters.Eip161abcTransition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip196Enabled = (chainSpec.ByzantiumBlockNumber ?? 0) <= releaseStartBlock; - releaseSpec.IsEip197Enabled = (chainSpec.ByzantiumBlockNumber ?? 0) <= releaseStartBlock; - releaseSpec.IsEip198Enabled = (chainSpec.ByzantiumBlockNumber ?? 0) <= releaseStartBlock; - releaseSpec.IsEip211Enabled = (chainSpec.Parameters.Eip211Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip214Enabled = (chainSpec.Parameters.Eip214Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip658Enabled = (chainSpec.Parameters.Eip658Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip649Enabled = (chainSpec.ByzantiumBlockNumber ?? 0) <= releaseStartBlock; - releaseSpec.IsEip1014Enabled = (chainSpec.Parameters.Eip1014Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip1052Enabled = (chainSpec.Parameters.Eip1052Transition ?? 0) <= releaseStartBlock; - releaseSpec.IsEip1108Enabled = (chainSpec.Parameters.Eip1108Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip1234Enabled = (chainSpec.ConstantinopleBlockNumber ?? chainSpec.ConstantinopleFixBlockNumber ?? 0) <= releaseStartBlock; - releaseSpec.IsEip1283Enabled = (chainSpec.Parameters.Eip1283Transition ?? long.MaxValue) <= releaseStartBlock && ((chainSpec.Parameters.Eip1283DisableTransition ?? long.MaxValue) > releaseStartBlock || (chainSpec.Parameters.Eip1283ReenableTransition ?? long.MaxValue) <= releaseStartBlock); - releaseSpec.IsEip1344Enabled = (chainSpec.Parameters.Eip1344Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip1884Enabled = (chainSpec.Parameters.Eip1884Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip2028Enabled = (chainSpec.Parameters.Eip2028Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip2200Enabled = (chainSpec.Parameters.Eip2200Transition ?? long.MaxValue) <= releaseStartBlock || (chainSpec.Parameters.Eip1706Transition ?? long.MaxValue) <= releaseStartBlock && releaseSpec.IsEip1283Enabled; - releaseSpec.IsEip1559Enabled = (chainSpec.Parameters.Eip1559Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.Eip1559TransitionBlock = chainSpec.Parameters.Eip1559Transition ?? long.MaxValue; - releaseSpec.IsEip2537Enabled = (chainSpec.Parameters.Eip2537Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip7Enabled = BlockOf(chainSpec.Parameters.Eip7Transition, 0) <= block; + releaseSpec.IsEip140Enabled = BlockOf(chainSpec.Parameters.Eip140Transition, 0) <= block; + releaseSpec.IsEip145Enabled = BlockOf(chainSpec.Parameters.Eip145Transition, 0) <= block; + releaseSpec.IsEip150Enabled = BlockOf(chainSpec.Parameters.Eip150Transition, 0) <= block; + releaseSpec.IsEip152Enabled = BlockOf(chainSpec.Parameters.Eip152Transition) <= block; + releaseSpec.IsEip155Enabled = BlockOf(chainSpec.Parameters.Eip155Transition, 0) <= block; + releaseSpec.IsEip160Enabled = BlockOf(chainSpec.Parameters.Eip160Transition, 0) <= block; + releaseSpec.IsEip158Enabled = BlockOf(chainSpec.Parameters.Eip161abcTransition, 0) <= block; + releaseSpec.IsEip196Enabled = (chainSpec.ByzantiumBlockNumber ?? 0UL) <= block; + releaseSpec.IsEip197Enabled = (chainSpec.ByzantiumBlockNumber ?? 0UL) <= block; + releaseSpec.IsEip198Enabled = (chainSpec.ByzantiumBlockNumber ?? 0UL) <= block; + releaseSpec.IsEip211Enabled = BlockOf(chainSpec.Parameters.Eip211Transition, 0) <= block; + releaseSpec.IsEip214Enabled = BlockOf(chainSpec.Parameters.Eip214Transition, 0) <= block; + releaseSpec.IsEip658Enabled = BlockOf(chainSpec.Parameters.Eip658Transition, 0) <= block; + releaseSpec.IsEip649Enabled = (chainSpec.ByzantiumBlockNumber ?? 0UL) <= block; + releaseSpec.IsEip1014Enabled = BlockOf(chainSpec.Parameters.Eip1014Transition, 0) <= block; + releaseSpec.IsEip1052Enabled = BlockOf(chainSpec.Parameters.Eip1052Transition, 0) <= block; + releaseSpec.IsEip1108Enabled = BlockOf(chainSpec.Parameters.Eip1108Transition) <= block; + releaseSpec.IsEip1234Enabled = (chainSpec.ConstantinopleBlockNumber ?? chainSpec.ConstantinopleFixBlockNumber ?? 0UL) <= block; + releaseSpec.IsEip1283Enabled = BlockOf(chainSpec.Parameters.Eip1283Transition) <= block + && (BlockOf(chainSpec.Parameters.Eip1283DisableTransition) > block + || BlockOf(chainSpec.Parameters.Eip1283ReenableTransition) <= block); + releaseSpec.IsEip1344Enabled = BlockOf(chainSpec.Parameters.Eip1344Transition) <= block; + releaseSpec.IsEip1884Enabled = BlockOf(chainSpec.Parameters.Eip1884Transition) <= block; + releaseSpec.IsEip2028Enabled = BlockOf(chainSpec.Parameters.Eip2028Transition) <= block; + releaseSpec.IsEip2200Enabled = BlockOf(chainSpec.Parameters.Eip2200Transition) <= block + || BlockOf(chainSpec.Parameters.Eip1706Transition) <= block && releaseSpec.IsEip1283Enabled; + releaseSpec.IsEip1559Enabled = BlockOf(chainSpec.Parameters.Eip1559Transition) <= block; + releaseSpec.Eip1559TransitionBlock = BlockOf(chainSpec.Parameters.Eip1559Transition); + releaseSpec.IsEip2537Enabled = BlockOf(chainSpec.Parameters.Eip2537Transition) <= block || (chainSpec.Parameters.Eip2537TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - releaseSpec.IsEip2565Enabled = (chainSpec.Parameters.Eip2565Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip2929Enabled = (chainSpec.Parameters.Eip2929Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip2930Enabled = (chainSpec.Parameters.Eip2930Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip3198Enabled = (chainSpec.Parameters.Eip3198Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip3541Enabled = (chainSpec.Parameters.Eip3541Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip3529Enabled = (chainSpec.Parameters.Eip3529Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsEip3607Enabled = (chainSpec.Parameters.Eip3607Transition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.ValidateChainId = (chainSpec.Parameters.ValidateChainIdTransition ?? 0) <= releaseStartBlock; - releaseSpec.ValidateReceipts = ((chainSpec.Parameters.ValidateReceiptsTransition > 0) ? Math.Max(chainSpec.Parameters.ValidateReceiptsTransition ?? 0, chainSpec.Parameters.Eip658Transition ?? 0) : 0) <= releaseStartBlock; - releaseSpec.Eip1559BaseFeeMinValue = releaseSpec.IsEip1559Enabled && (chainSpec.Parameters.Eip1559BaseFeeMinValueTransition ?? long.MaxValue) <= releaseStartBlock ? chainSpec.Parameters.Eip1559BaseFeeMinValue : null; + releaseSpec.IsEip2565Enabled = BlockOf(chainSpec.Parameters.Eip2565Transition) <= block; + releaseSpec.IsEip2929Enabled = BlockOf(chainSpec.Parameters.Eip2929Transition) <= block; + releaseSpec.IsEip2930Enabled = BlockOf(chainSpec.Parameters.Eip2930Transition) <= block; + releaseSpec.IsEip3198Enabled = BlockOf(chainSpec.Parameters.Eip3198Transition) <= block; + releaseSpec.IsEip3541Enabled = BlockOf(chainSpec.Parameters.Eip3541Transition) <= block; + releaseSpec.IsEip3529Enabled = BlockOf(chainSpec.Parameters.Eip3529Transition) <= block; + releaseSpec.IsEip3607Enabled = BlockOf(chainSpec.Parameters.Eip3607Transition) <= block; + releaseSpec.ValidateChainId = BlockOf(chainSpec.Parameters.ValidateChainIdTransition, 0) <= block; + releaseSpec.ValidateReceipts = ((chainSpec.Parameters.ValidateReceiptsTransition > 0) + ? Math.Max(BlockOf(chainSpec.Parameters.ValidateReceiptsTransition, 0), + BlockOf(chainSpec.Parameters.Eip658Transition, 0)) + : 0UL) <= block; + releaseSpec.Eip1559BaseFeeMinValue = releaseSpec.IsEip1559Enabled + && BlockOf(chainSpec.Parameters.Eip1559BaseFeeMinValueTransition) <= block + ? chainSpec.Parameters.Eip1559BaseFeeMinValue + : null; releaseSpec.ElasticityMultiplier = chainSpec.Parameters.Eip1559ElasticityMultiplier ?? Eip1559Constants.DefaultElasticityMultiplier; releaseSpec.ForkBaseFee = chainSpec.Parameters.Eip1559BaseFeeInitialValue ?? Eip1559Constants.DefaultForkBaseFee; releaseSpec.BaseFeeMaxChangeDenominator = chainSpec.Parameters.Eip1559BaseFeeMaxChangeDenominator ?? Eip1559Constants.DefaultBaseFeeMaxChangeDenominator; - releaseSpec.IsEip1153Enabled = (chainSpec.Parameters.Eip1153Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip1153Enabled = BlockOf(chainSpec.Parameters.Eip1153Transition) <= block || (chainSpec.Parameters.Eip1153TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - releaseSpec.IsEip3651Enabled = (chainSpec.Parameters.Eip3651Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip3651Enabled = BlockOf(chainSpec.Parameters.Eip3651Transition) <= block || (chainSpec.Parameters.Eip3651TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - releaseSpec.IsEip3855Enabled = (chainSpec.Parameters.Eip3855Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip3855Enabled = BlockOf(chainSpec.Parameters.Eip3855Transition) <= block || (chainSpec.Parameters.Eip3855TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - releaseSpec.IsEip3860Enabled = (chainSpec.Parameters.Eip3860Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip3860Enabled = BlockOf(chainSpec.Parameters.Eip3860Transition) <= block || (chainSpec.Parameters.Eip3860TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip4895Enabled = (chainSpec.Parameters.Eip4895TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.WithdrawalTimestamp = chainSpec.Parameters.Eip4895TransitionTimestamp ?? ulong.MaxValue; - releaseSpec.IsEip4844Enabled = (chainSpec.Parameters.Eip4844Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip4844Enabled = BlockOf(chainSpec.Parameters.Eip4844Transition) <= block || (chainSpec.Parameters.Eip4844TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip7951Enabled = (chainSpec.Parameters.Eip7951TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsRip7212Enabled = (chainSpec.Parameters.Rip7212TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; @@ -292,9 +309,9 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas releaseSpec.IsOpHoloceneEnabled = (chainSpec.Parameters.OpHoloceneTransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsOpIsthmusEnabled = (chainSpec.Parameters.OpIsthmusTransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.Eip4844TransitionTimestamp = chainSpec.Parameters.Eip4844TransitionTimestamp ?? ulong.MaxValue; - releaseSpec.IsEip5656Enabled = (chainSpec.Parameters.Eip5656Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip5656Enabled = BlockOf(chainSpec.Parameters.Eip5656Transition) <= block || (chainSpec.Parameters.Eip5656TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - releaseSpec.IsEip6780Enabled = (chainSpec.Parameters.Eip6780Transition ?? long.MaxValue) <= releaseStartBlock || + releaseSpec.IsEip6780Enabled = BlockOf(chainSpec.Parameters.Eip6780Transition) <= block || (chainSpec.Parameters.Eip6780TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip4788Enabled = (chainSpec.Parameters.Eip4788TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.Eip4788ContractAddress = chainSpec.Parameters.Eip4788ContractAddress; @@ -314,10 +331,6 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas releaseSpec.IsEip7251Enabled = (chainSpec.Parameters.Eip7251TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.Eip7251ContractAddress = chainSpec.Parameters.Eip7251ContractAddress; releaseSpec.IsEip7623Enabled = (chainSpec.Parameters.Eip7623TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - // EIP-7976 and EIP-7981 are the "Amsterdam floor pricing" bundle: they activate - // automatically when the Amsterdam timestamp fires, even if the chainspec omits - // their individual transition fields. Other Amsterdam-fork EIPs require explicit - // per-EIP transitions in the chainspec. releaseSpec.IsEip7976Enabled = (chainSpec.Parameters.Eip7976TransitionTimestamp ?? chainSpec.AmsterdamTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip7981Enabled = (chainSpec.Parameters.Eip7981TransitionTimestamp ?? chainSpec.AmsterdamTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip7883Enabled = (chainSpec.Parameters.Eip7883TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; @@ -327,8 +340,8 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas releaseSpec.IsEip7918Enabled = (chainSpec.Parameters.Eip7918TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip8024Enabled = (chainSpec.Parameters.Eip8024TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; - bool eip1559FeeCollector = releaseSpec.IsEip1559Enabled && (chainSpec.Parameters.Eip1559FeeCollectorTransition ?? long.MaxValue) <= releaseStartBlock; - bool eip4844FeeCollector = releaseSpec.IsEip4844Enabled && (chainSpec.Parameters.Eip4844FeeCollectorTransitionTimestamp ?? long.MaxValue) <= releaseStartTimestamp; + bool eip1559FeeCollector = releaseSpec.IsEip1559Enabled && BlockOf(chainSpec.Parameters.Eip1559FeeCollectorTransition) <= block; + bool eip4844FeeCollector = releaseSpec.IsEip4844Enabled && (chainSpec.Parameters.Eip4844FeeCollectorTransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.FeeCollector = (eip1559FeeCollector || eip4844FeeCollector) ? chainSpec.Parameters.FeeCollector : null; releaseSpec.IsEip4844FeeCollectorEnabled = eip4844FeeCollector; @@ -354,7 +367,7 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas foreach (IChainSpecEngineParameters item in _chainSpec.EngineChainSpecParametersProvider .AllChainSpecParameters) { - item.ApplyToReleaseSpec(releaseSpec, releaseStartBlock, releaseStartTimestamp); + item.ApplyToReleaseSpec(releaseSpec, block, releaseStartTimestamp); } SetBlobScheduleParameters(); @@ -385,20 +398,12 @@ void SetBlobScheduleParameters() } } - // Shanghai (EIP-4895) is the first post-Paris timestamp-activated fork, so TTD-driven - // chains like mainnet cross into post-merge once they reach it - that's the only - // non-obvious branch below. TTD=0 covers PoS-from-genesis. TerminalPoWBlockNumber - // fires only when releaseStartBlock advances past it, which requires the chainspec to - // carry post-merge block-number transitions (TerminalPoWBlockNumber is excluded from - // AddTransitions above, so it creates no spec boundary of its own). Paris-era blocks - // on TTD-driven chains with no such later transitions are not detected here - runtime - // MergeHeaderValidator (UnclesHash == empty via PoSSwitcher) is the safety net. - private static bool IsPostMergeRelease(ChainSpec chainSpec, long releaseStartBlock, ulong? releaseStartTimestamp) => + private static bool IsPostMergeRelease(ChainSpec chainSpec, ulong releaseStartBlock, ulong? releaseStartTimestamp) => chainSpec.Parameters.TerminalTotalDifficulty?.IsZero == true - || releaseStartBlock > (chainSpec.Parameters.TerminalPoWBlockNumber ?? long.MaxValue) + || releaseStartBlock > (chainSpec.Parameters.TerminalPoWBlockNumber ?? ulong.MaxValue) || (chainSpec.Parameters.Eip4895TransitionTimestamp ?? ulong.MaxValue) <= (releaseStartTimestamp ?? 0); - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) { @@ -416,7 +421,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public UInt256? TerminalTotalDifficulty { get; private set; } - public long? DaoBlockNumber => _chainSpec.DaoForkBlockNumber; + public ulong? DaoBlockNumber => _chainSpec.DaoForkBlockNumber; public ulong? BeaconChainGenesisTimestamp => _chainSpec.Parameters.BeaconChainGenesisTimestamp; public ulong NetworkId => _chainSpec.NetworkId; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs index c3a3e6895df1..5f81e523ed12 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs @@ -64,7 +64,7 @@ private ChainSpec InitChainSpecFrom(ChainSpecJson chainSpecJson) private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec) { - long? GetTransitions(string builtInName, Predicate> predicate) + ulong? GetTransitions(string builtInName, Predicate> predicate) { AllocationJson? allocation = chainSpecJson.Accounts?.Values.FirstOrDefault(v => v.BuiltIn?.Name.Equals(builtInName, StringComparison.OrdinalIgnoreCase) == true); if (allocation is null) return null; @@ -72,13 +72,15 @@ private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec) if (pricing?.Length > 0) { string key = pricing[0].Key; - return long.TryParse(key, out long transition) ? transition : Convert.ToInt64(key, 16); + // Block numbers in built-in pricing keys are always non-negative; parse as ulong + // directly. Hex keys are parsed via Convert then cast — safe for any valid block number. + return ulong.TryParse(key, out ulong transition) ? transition : (ulong)Convert.ToInt64(key, 16); } return null; } - long? GetTransitionForExpectedPricing(string builtInName, string innerPath, long expectedValue) + ulong? GetTransitionForExpectedPricing(string builtInName, string innerPath, long expectedValue) { bool GetForExpectedPricing(KeyValuePair o) => o.Value.TryGetSubProperty(innerPath, out JsonElement value) && value.GetInt64() == expectedValue; @@ -86,7 +88,7 @@ bool GetForExpectedPricing(KeyValuePair o) => return GetTransitions(builtInName, GetForExpectedPricing); } - long? GetTransitionIfInnerPathExists(string builtInName, string innerPath) + ulong? GetTransitionIfInnerPathExists(string builtInName, string innerPath) { bool GetForInnerPathExistence(KeyValuePair o) => o.Value.TryGetSubProperty(innerPath, out _); @@ -96,9 +98,9 @@ bool GetForInnerPathExistence(KeyValuePair o) => chainSpec.Parameters = new ChainParameters { - GasLimitBoundDivisor = chainSpecJson.Params.GasLimitBoundDivisor ?? 0x0400, + GasLimitBoundDivisor = chainSpecJson.Params.GasLimitBoundDivisor ?? 0x0400UL, MaximumExtraDataSize = chainSpecJson.Params.MaximumExtraDataSize ?? 32, - MinGasLimit = chainSpecJson.Params.MinGasLimit ?? 5000, + MinGasLimit = chainSpecJson.Params.MinGasLimit ?? 5000UL, MinHistoryRetentionEpochs = chainSpecJson.Params.MinHistoryRetentionEpochs ?? 82125, MinBalRetentionEpochs = chainSpecJson.Params.MinBalRetentionEpochs ?? 3533, MaxCodeSize = chainSpecJson.Params.MaxCodeSize, @@ -276,6 +278,7 @@ private static void LoadTransitions(ChainSpecJson chainSpecJson, ChainSpec chain chainSpec.TangerineWhistleBlockNumber = chainSpec.Parameters.Eip150Transition; chainSpec.SpuriousDragonBlockNumber = chainSpec.Parameters.Eip160Transition; chainSpec.ByzantiumBlockNumber = chainSpec.Parameters.Eip140Transition; + // null when Eip1283DisableTransition is absent (chain never had a Constantinople/fix split). chainSpec.ConstantinopleBlockNumber = chainSpec.Parameters.Eip1283DisableTransition is null ? null @@ -296,7 +299,6 @@ chainSpec.Parameters.Eip1283DisableTransition is null chainSpec.TerminalPoWBlockNumber = chainSpec.Parameters.TerminalPoWBlockNumber; chainSpec.TerminalTotalDifficulty = chainSpec.Parameters.TerminalTotalDifficulty; - if (chainSpec.EngineChainSpecParametersProvider is not null) { foreach (IChainSpecEngineParameters chainSpecEngineParameters in chainSpec.EngineChainSpecParametersProvider @@ -332,7 +334,7 @@ private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec return; } - UInt256 nonce = chainSpecJson.Genesis.Seal?.Ethereum?.Nonce ?? 0; + ulong nonce = chainSpecJson.Genesis.Seal?.Ethereum?.Nonce ?? 0UL; Hash256 mixHash = chainSpecJson.Genesis.Seal?.Ethereum?.MixHash ?? Keccak.Zero; byte[] auRaSignature = chainSpecJson.Genesis.Seal?.AuthorityRound?.Signature; @@ -342,7 +344,7 @@ private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec ulong timestamp = chainSpecJson.Genesis.Timestamp; UInt256 difficulty = chainSpecJson.Genesis.Difficulty; byte[] extraData = chainSpecJson.Genesis.ExtraData ?? []; - UInt256 gasLimit = chainSpecJson.Genesis.GasLimit; + ulong gasLimit = chainSpecJson.Genesis.GasLimit; Address beneficiary = chainSpecJson.Genesis.Author ?? Address.Zero; ChainParameters parameters = chainSpec.Parameters; UInt256 baseFee = parameters.Eip1559Transition switch @@ -362,7 +364,7 @@ private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec beneficiary, difficulty, 0, - (long)gasLimit, + gasLimit, timestamp, extraData) { @@ -370,7 +372,7 @@ private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec Hash = Keccak.Zero, // need to run the block to know the actual hash Bloom = Bloom.Empty, MixHash = mixHash, - Nonce = (ulong)nonce, + Nonce = nonce, ReceiptsRoot = Keccak.EmptyTreeHash, StateRoot = stateRoot, TxRoot = Keccak.EmptyTreeHash, @@ -470,7 +472,7 @@ private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chain if (chainSpecJson.CodeHashes is null || !chainSpecJson.CodeHashes.TryGetValue(codeHashString, out byte[] codeHash)) throw new ArgumentException($"CodeHash {account.Value.CodeHash} is not found"); chainSpec.Allocations[address] = new ChainSpecAllocation( account.Value.Balance ?? UInt256.Zero, - account.Value.Nonce, + (ulong)account.Value.Nonce, codeHash, account.Value.Constructor, account.Value.GetConvertedStorage()); @@ -479,7 +481,7 @@ private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chain { chainSpec.Allocations[address] = new ChainSpecAllocation( account.Value.Balance ?? UInt256.Zero, - account.Value.Nonce, + (ulong)account.Value.Nonce, account.Value.Code, account.Value.Constructor, account.Value.GetConvertedStorage()); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs index bf274253b21b..f4d6941bd36c 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs @@ -190,12 +190,12 @@ private void LoadParameters(GethGenesisJson gethGenesis, ChainSpec chainSpec) private static void LoadGenesis(GethGenesisJson gethGenesisJson, ChainSpec chainSpec) { - UInt256 nonce = gethGenesisJson.Nonce; + ulong nonce = gethGenesisJson.Nonce; Hash256 mixHash = gethGenesisJson.MixHash ?? Keccak.Zero; ulong timestamp = gethGenesisJson.Timestamp ?? 0; UInt256 difficulty = gethGenesisJson.Difficulty; byte[] extraData = gethGenesisJson.ExtraData ?? []; - UInt256 gasLimit = gethGenesisJson.GasLimit ?? 0; + ulong gasLimit = gethGenesisJson.GasLimit ?? 0; Address beneficiary = gethGenesisJson.Coinbase ?? Address.Zero; UInt256 baseFee = gethGenesisJson.Config.LondonBlock switch { @@ -210,7 +210,9 @@ private static void LoadGenesis(GethGenesisJson gethGenesisJson, ChainSpec chain beneficiary, difficulty, 0, - (long)gasLimit, + // Pre-existing cast: UInt256 -> ulong. Safe for any valid genesis gas limit + // (would only overflow above ~1.8x10^19, which is physically impossible). + gasLimit, timestamp, extraData) { @@ -218,7 +220,7 @@ private static void LoadGenesis(GethGenesisJson gethGenesisJson, ChainSpec chain Hash = Keccak.Zero, // need to run the block to know the actual hash Bloom = Bloom.Empty, MixHash = mixHash, - Nonce = (ulong)nonce, + Nonce = nonce, ReceiptsRoot = Keccak.EmptyTreeHash, StateRoot = Keccak.EmptyTreeHash, TxRoot = Keccak.EmptyTreeHash, @@ -361,29 +363,29 @@ private sealed class GethEthashChainSpecEngineParameters(GethGenesisConfigJson c private static readonly UInt256 FiveEth = new(5_000_000_000_000_000_000ul); private static readonly UInt256 ThreeEth = new(3_000_000_000_000_000_000ul); private static readonly UInt256 TwoEth = new(2_000_000_000_000_000_000ul); - private readonly long? _arrowGlacierTransition = config.ArrowGlacierBlock; - private readonly long? _grayGlacierTransition = config.GrayGlacierBlock; - private readonly long? _muirGlacierTransition = config.MuirGlacierBlock; public string? EngineName => SealEngineType; public string? SealEngineType => Core.SealEngineType.Ethash; - public long HomesteadTransition { get; } = config.HomesteadBlock ?? 0; - public long? DaoHardforkTransition { get; } = config.DaoForkSupport == false ? null : config.DaoForkBlock; + + public ulong HomesteadTransition { get; } = config.HomesteadBlock ?? 0; + public ulong? DaoHardforkTransition { get; } = config.DaoForkSupport == false ? null : config.DaoForkBlock; public Address? DaoHardforkBeneficiary { get; } public Address[] DaoHardforkAccounts { get; } = []; - public long? Eip100bTransition { get; } = config.ByzantiumBlock; - public long? FixedDifficulty { get; } - public long DifficultyBoundDivisor => 0x0800; + public ulong? Eip100bTransition { get; } = config.ByzantiumBlock; + public ulong? FixedDifficulty { get; } + public ulong DifficultyBoundDivisor => 0x0800; public long DurationLimit => 13; public UInt256 MinimumDifficulty => UInt256.Zero; - public SortedDictionary? BlockReward { get; } = BuildBlockRewardSchedule(config); - public IDictionary? DifficultyBombDelays { get; } = BuildDifficultyBombDelays(config); + public SortedDictionary? BlockReward { get; } = BuildBlockRewardSchedule(config); + public IDictionary? DifficultyBombDelays { get; } = BuildDifficultyBombDelays(config); - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) + // NOTE: IChainSpecEngineParameters.AddTransitions and ApplyToReleaseSpec signatures must + // also be updated to ulong as part of this migration. + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { if (DifficultyBombDelays is not null) { - foreach ((long blockNumber, _) in DifficultyBombDelays) + foreach ((ulong blockNumber, _) in DifficultyBombDelays) { blockNumbers.Add(blockNumber); } @@ -391,7 +393,7 @@ public void AddTransitions(SortedSet blockNumbers, SortedSet timest if (BlockReward is not null) { - foreach ((long blockNumber, _) in BlockReward) + foreach ((ulong blockNumber, _) in BlockReward) { blockNumbers.Add(blockNumber); } @@ -409,11 +411,11 @@ public void AddTransitions(SortedSet blockNumbers, SortedSet timest } } - public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) + public void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) { if (BlockReward is not null) { - foreach ((long blockNumber, UInt256 blockReward) in BlockReward) + foreach ((ulong blockNumber, UInt256 blockReward) in BlockReward) { if (blockNumber <= startBlock) { @@ -424,7 +426,7 @@ public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTi if (DifficultyBombDelays is not null) { - foreach ((long blockNumber, long bombDelay) in DifficultyBombDelays) + foreach ((ulong blockNumber, ulong bombDelay) in DifficultyBombDelays) { if (blockNumber <= startBlock) { @@ -444,15 +446,15 @@ public void ApplyToChainSpec(ChainSpec chainSpec) { chainSpec.HomesteadBlockNumber = HomesteadTransition; chainSpec.DaoForkBlockNumber = DaoHardforkTransition; - chainSpec.MuirGlacierNumber = _muirGlacierTransition; - chainSpec.ArrowGlacierBlockNumber = _arrowGlacierTransition; - chainSpec.GrayGlacierBlockNumber = _grayGlacierTransition; + chainSpec.MuirGlacierNumber = config.MuirGlacierBlock; + chainSpec.ArrowGlacierBlockNumber = config.ArrowGlacierBlock; + chainSpec.GrayGlacierBlockNumber = config.GrayGlacierBlock; } - private static SortedDictionary BuildBlockRewardSchedule(GethGenesisConfigJson config) + private static SortedDictionary BuildBlockRewardSchedule(GethGenesisConfigJson config) { - SortedDictionary blockReward = []; - long? constantinopleTransition = GetConstantinopleTransition(config); + SortedDictionary blockReward = []; + ulong? constantinopleTransition = GetConstantinopleTransition(config); blockReward[0] = constantinopleTransition == 0 ? TwoEth : config.ByzantiumBlock == 0 ? ThreeEth @@ -471,14 +473,14 @@ private static SortedDictionary BuildBlockRewardSchedule(GethGene return blockReward; } - private static SortedDictionary? BuildDifficultyBombDelays(GethGenesisConfigJson config) + private static SortedDictionary? BuildDifficultyBombDelays(GethGenesisConfigJson config) { if (config.TerminalTotalDifficulty is not null && config.TerminalTotalDifficulty.Value == UInt256.Zero) { return null; } - SortedDictionary bombDelays = []; + SortedDictionary bombDelays = []; AddBombDelay(bombDelays, config.ByzantiumBlock, 3_000_000); AddBombDelay(bombDelays, GetConstantinopleTransition(config), 2_000_000); AddBombDelay(bombDelays, config.MuirGlacierBlock, 4_000_000); @@ -488,19 +490,21 @@ private static SortedDictionary BuildBlockRewardSchedule(GethGene return bombDelays.Count == 0 ? null : bombDelays; } - private static void AddBombDelay(SortedDictionary bombDelays, long? transition, long delay) + private static void AddBombDelay(SortedDictionary bombDelays, ulong? transition, ulong delay) { if (transition is not null) { - bombDelays[transition.Value] = !bombDelays.TryGetValue(transition.Value, out long existingDelay) + bombDelays[transition.Value] = !bombDelays.TryGetValue(transition.Value, out ulong existingDelay) ? delay : existingDelay + delay; } } - private static long? GetConstantinopleTransition(GethGenesisConfigJson config) => - config.ConstantinopleBlock is null ? config.PetersburgBlock - : config.PetersburgBlock is null ? config.ConstantinopleBlock - : Math.Min(config.ConstantinopleBlock.Value, config.PetersburgBlock.Value); + private static ulong? GetConstantinopleTransition(GethGenesisConfigJson config) + { + if (config.ConstantinopleBlock is null) return config.PetersburgBlock; + if (config.PetersburgBlock is null) return config.ConstantinopleBlock; + return Math.Min(config.ConstantinopleBlock.Value, config.PetersburgBlock.Value); + } } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/HardforkLabels.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/HardforkLabels.cs index 783534f5410a..87026987b04d 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/HardforkLabels.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/HardforkLabels.cs @@ -15,7 +15,7 @@ namespace Nethermind.Specs.ChainSpecStyle; /// /// Shorthand hardfork labels for the Parity-style chainspec JSON and the EIP-7949 Geth-style /// genesis. Each label is a single activation value — a block number for pre-Shanghai forks -/// (long?) and a timestamp for post-merge forks (ulong?) — that fans out at load +/// (ulong?) and a timestamp for post-merge forks (ulong?) — that fans out at load /// time to the full set of per-EIP transition fields that make up that fork. /// /// @@ -56,12 +56,12 @@ public static void ExpandAll(this ChainParameters target, IHasNamedForks source) foreach (IHardforkLabel label in All) label.Apply(target, source); } - /// Fork class name (e.g. Cancun); the JSON wire key is its camelCase form. - internal static HardforkLabel Block( + /// Fork class name (e.g. Homestead); the JSON wire key is its camelCase form. + internal static HardforkLabel Block( string name, - params Expression>[] eips) => + params Expression>[] eips) => new(name, HardforkLabelKind.Block, - (s, k) => s.NamedForkBlocks is { } d && d.TryGetValue(k, out long v) ? v : null, + (s, k) => s.NamedForkBlocks is { } d && d.TryGetValue(k, out ulong v) ? v : null, eips); /// @@ -81,7 +81,7 @@ internal static HardforkLabel Time( public interface IHasNamedForks { /// Pre-merge fork → activation block number. Case-insensitive lookup. - IReadOnlyDictionary? NamedForkBlocks { get; } + IReadOnlyDictionary? NamedForkBlocks { get; } /// Post-merge fork → activation timestamp. Case-insensitive lookup. IReadOnlyDictionary? NamedForkTimestamps { get; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/IChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/IChainSpecEngineParameters.cs index 877e97eeb6d1..70428984e846 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/IChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/IChainSpecEngineParameters.cs @@ -10,6 +10,6 @@ public interface IChainSpecEngineParameters string? EngineName { get; } string? SealEngineType { get; } void ApplyToChainSpec(ChainSpec chainSpec) { } - void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { } - void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) { } + void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { } + void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) { } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs index e4cef9e9fbff..3a41759b7efd 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs @@ -11,15 +11,15 @@ namespace Nethermind.Specs.ChainSpecStyle.Json; -public class BlockRewardConverter : JsonConverter> +public class BlockRewardConverter : JsonConverter> { - public override void Write(Utf8JsonWriter writer, SortedDictionary value, + public override void Write(Utf8JsonWriter writer, SortedDictionary value, JsonSerializerOptions options) => throw new NotSupportedException(); - public override SortedDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, + public override SortedDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - SortedDictionary value = []; + SortedDictionary value = []; if (reader.TokenType == JsonTokenType.String) { UInt256 blockReward = JsonSerializer.Deserialize(ref reader, options); @@ -41,7 +41,7 @@ public override SortedDictionary Read(ref Utf8JsonReader reader, UInt256 property = UInt256Converter.ReadHex(reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan); - long key = (long)property; + ulong key = (ulong)property; reader.Read(); if (reader.TokenType != JsonTokenType.String) { diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs index e6721dfdf30e..195c896b9708 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core.Crypto; -using Nethermind.Int256; namespace Nethermind.Specs.ChainSpecStyle.Json { public class ChainSpecEthereumSealJson { - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public Hash256 MixHash { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecGenesisJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecGenesisJson.cs index f3ea886eca31..41f336ab84de 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecGenesisJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecGenesisJson.cs @@ -17,7 +17,7 @@ public class ChainSpecGenesisJson public ulong Timestamp { get; set; } public Hash256 ParentHash { get; set; } public byte[] ExtraData { get; set; } - public UInt256 GasLimit { get; set; } + public ulong GasLimit { get; set; } public UInt256? BaseFeePerGas { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs index 1f7fb82c259a..4fc3ef8a19ba 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs @@ -22,93 +22,93 @@ public class ChainSpecParamsJson : IHasNamedForks public Address Registrar { get; set; } - public long? GasLimitBoundDivisor { get; set; } + public ulong? GasLimitBoundDivisor { get; set; } public long? MaximumExtraDataSize { get; set; } - public long? MinGasLimit { get; set; } + public ulong? MinGasLimit { get; set; } public long? MinHistoryRetentionEpochs { get; set; } public long? MinBalRetentionEpochs { get; set; } - public long? ForkBlock { get; set; } + public ulong? ForkBlock { get; set; } public Hash256 ForkCanonHash { get; set; } - public long? Eip7Transition { get; set; } + public ulong? Eip7Transition { get; set; } - public long? Eip150Transition { get; set; } + public ulong? Eip150Transition { get; set; } - public long? Eip152Transition { get; set; } + public ulong? Eip152Transition { get; set; } - public long? Eip160Transition { get; set; } + public ulong? Eip160Transition { get; set; } - public long? Eip161abcTransition { get; set; } + public ulong? Eip161abcTransition { get; set; } - public long? Eip161dTransition { get; set; } + public ulong? Eip161dTransition { get; set; } - public long? Eip155Transition { get; set; } + public ulong? Eip155Transition { get; set; } public long? MaxCodeSize { get; set; } - public long? MaxCodeSizeTransition { get; set; } + public ulong? MaxCodeSizeTransition { get; set; } public ulong? MaxCodeSizeTransitionTimestamp { get; set; } - public long? Eip140Transition { get; set; } + public ulong? Eip140Transition { get; set; } - public long? Eip211Transition { get; set; } + public ulong? Eip211Transition { get; set; } - public long? Eip214Transition { get; set; } + public ulong? Eip214Transition { get; set; } - public long? Eip658Transition { get; set; } + public ulong? Eip658Transition { get; set; } - public long? Eip145Transition { get; set; } + public ulong? Eip145Transition { get; set; } - public long? Eip1014Transition { get; set; } + public ulong? Eip1014Transition { get; set; } - public long? Eip1052Transition { get; set; } + public ulong? Eip1052Transition { get; set; } - public long? Eip1108Transition { get; set; } + public ulong? Eip1108Transition { get; set; } - public long? Eip1283Transition { get; set; } + public ulong? Eip1283Transition { get; set; } - public long? Eip1283DisableTransition { get; set; } + public ulong? Eip1283DisableTransition { get; set; } - public long? Eip1283ReenableTransition { get; set; } + public ulong? Eip1283ReenableTransition { get; set; } - public long? Eip1344Transition { get; set; } + public ulong? Eip1344Transition { get; set; } - public long? Eip1706Transition { get; set; } + public ulong? Eip1706Transition { get; set; } - public long? Eip1884Transition { get; set; } + public ulong? Eip1884Transition { get; set; } - public long? Eip2028Transition { get; set; } + public ulong? Eip2028Transition { get; set; } - public long? Eip2200Transition { get; set; } + public ulong? Eip2200Transition { get; set; } - public long? Eip1559Transition { get; set; } + public ulong? Eip1559Transition { get; set; } - public long? Eip2315Transition { get; set; } + public ulong? Eip2315Transition { get; set; } - public long? Eip2537Transition { get; set; } + public ulong? Eip2537Transition { get; set; } - public long? Eip2565Transition { get; set; } + public ulong? Eip2565Transition { get; set; } - public long? Eip2929Transition { get; set; } + public ulong? Eip2929Transition { get; set; } - public long? Eip2930Transition { get; set; } + public ulong? Eip2930Transition { get; set; } - public long? Eip3198Transition { get; set; } + public ulong? Eip3198Transition { get; set; } - public long? Eip3529Transition { get; set; } + public ulong? Eip3529Transition { get; set; } - public long? Eip3541Transition { get; set; } + public ulong? Eip3541Transition { get; set; } // We explicitly want this to be enabled by default on all the networks // we can disable it if needed, but its expected not to cause issues - public long? Eip3607Transition { get; set; } = 0; + public ulong? Eip3607Transition { get; set; } = 0; public UInt256? Eip1559BaseFeeInitialValue { get; set; } @@ -118,48 +118,48 @@ public class ChainSpecParamsJson : IHasNamedForks public Address TransactionPermissionContract { get; set; } - public long? TransactionPermissionContractTransition { get; set; } + public ulong? TransactionPermissionContractTransition { get; set; } - public long? ValidateChainIdTransition { get; set; } + public ulong? ValidateChainIdTransition { get; set; } - public long? ValidateReceiptsTransition { get; set; } + public ulong? ValidateReceiptsTransition { get; set; } - public long? Eip1559FeeCollectorTransition { get; set; } + public ulong? Eip1559FeeCollectorTransition { get; set; } public Address FeeCollector { get; set; } - public long? Eip1559BaseFeeMinValueTransition { get; set; } + public ulong? Eip1559BaseFeeMinValueTransition { get; set; } public UInt256? Eip1559BaseFeeMinValue { get; set; } - public long? MergeForkIdTransition { get; set; } + public ulong? MergeForkIdTransition { get; set; } public UInt256? TerminalTotalDifficulty { get; set; } - public long? TerminalPoWBlockNumber { get; set; } + public ulong? TerminalPoWBlockNumber { get; set; } public ulong? BeaconChainGenesisTimestamp { get; set; } - public long? Eip1153Transition { get; set; } + public ulong? Eip1153Transition { get; set; } public ulong? Eip1153TransitionTimestamp { get; set; } - public long? Eip3651Transition { get; set; } + public ulong? Eip3651Transition { get; set; } public ulong? Eip3651TransitionTimestamp { get; set; } - public long? Eip3855Transition { get; set; } + public ulong? Eip3855Transition { get; set; } public ulong? Eip3855TransitionTimestamp { get; set; } - public long? Eip3860Transition { get; set; } + public ulong? Eip3860Transition { get; set; } public ulong? Eip3860TransitionTimestamp { get; set; } public ulong? Eip4895TransitionTimestamp { get; set; } - public long? Eip4844Transition { get; set; } + public ulong? Eip4844Transition { get; set; } public ulong? Eip4844TransitionTimestamp { get; set; } public ulong? Eip2537TransitionTimestamp { get; set; } - public long? Eip5656Transition { get; set; } + public ulong? Eip5656Transition { get; set; } public ulong? Eip5656TransitionTimestamp { get; set; } - public long? Eip6780Transition { get; set; } + public ulong? Eip6780Transition { get; set; } public ulong? Eip6780TransitionTimestamp { get; set; } public ulong? Eip4788TransitionTimestamp { get; set; } public Address Eip4788ContractAddress { get; set; } public ulong? Eip2935TransitionTimestamp { get; set; } public Address Eip2935ContractAddress { get; set; } - public long? Eip2935RingBufferSize { get; set; } + public ulong? Eip2935RingBufferSize { get; set; } public UInt256? Eip4844BlobGasPriceUpdateFraction { get; set; } public UInt256? Eip4844MinBlobGasPrice { get; set; } public ulong? Eip4844FeeCollectorTransitionTimestamp { get; set; } @@ -210,13 +210,13 @@ public class ChainSpecParamsJson : IHasNamedForks public Dictionary? NamedForks { get; set; } = new(StringComparer.OrdinalIgnoreCase); [JsonIgnore] - private Dictionary? _namedForkBlocks; + private Dictionary? _namedForkBlocks; [JsonIgnore] private Dictionary? _namedForkTimestamps; - IReadOnlyDictionary? IHasNamedForks.NamedForkBlocks - => _namedForkBlocks ??= Project(HardforkLabelKind.Block); + IReadOnlyDictionary? IHasNamedForks.NamedForkBlocks + => _namedForkBlocks ??= Project(HardforkLabelKind.Block); IReadOnlyDictionary? IHasNamedForks.NamedForkTimestamps => _namedForkTimestamps ??= Project(HardforkLabelKind.Timestamp); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs new file mode 100644 index 000000000000..d5f666794767 --- /dev/null +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using Nethermind.Serialization.Json; + +namespace Nethermind.Specs.ChainSpecStyle.Json; + +public class DifficultyBombDelaysConverter : JsonConverter> +{ + public override void Write(Utf8JsonWriter writer, IDictionary value, + JsonSerializerOptions options) => throw new NotSupportedException(); + + public override IDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, + JsonSerializerOptions options) + { + Dictionary value = []; + if (reader.TokenType == JsonTokenType.StartObject) + { + reader.Read(); + while (reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + ReadOnlySpan keySpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + ulong key = NumericConverterHelper.Parse(keySpan); + + reader.Read(); + + ulong delay; + if (reader.TokenType == JsonTokenType.String) + { + ReadOnlySpan valSpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + delay = NumericConverterHelper.Parse(valSpan); + } + else if (reader.TokenType == JsonTokenType.Number) + { + delay = reader.GetUInt64(); + } + else + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + value.Add(key, delay); + + reader.Read(); + } + } + else + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + return value; + } +} diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisConfigJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisConfigJson.cs index 9b0c278b6e20..2252b8786722 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisConfigJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisConfigJson.cs @@ -28,32 +28,32 @@ namespace Nethermind.Specs.ChainSpecStyle.Json; /// public class GethGenesisConfigJson : IHasNamedForks { - private readonly Dictionary _blocks = new(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _blocks = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _timestamps = new(StringComparer.OrdinalIgnoreCase); public ulong ChainId { get; set; } - public long? HomesteadBlock { get => GetBlock(); set => SetBlock(value); } - public long? DaoForkBlock { get => GetBlock(nameof(Dao)); set => SetBlock(value, nameof(Dao)); } + public ulong? HomesteadBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? DaoForkBlock { get => GetBlock(nameof(Dao)); set => SetBlock(value, nameof(Dao)); } public bool? DaoForkSupport { get; set; } // EIP-level overrides — not fork labels, kept as plain typed properties. - public long? Eip150Block { get; set; } - public long? Eip155Block { get; set; } - public long? Eip158Block { get; set; } - - public long? TangerineWhistleBlock { get => GetBlock(); set => SetBlock(value); } - public long? SpuriousDragonBlock { get => GetBlock(); set => SetBlock(value); } - public long? ByzantiumBlock { get => GetBlock(); set => SetBlock(value); } - public long? ConstantinopleBlock { get => GetBlock(); set => SetBlock(value); } - public long? PetersburgBlock { get => GetBlock(nameof(ConstantinopleFix)); set => SetBlock(value, nameof(ConstantinopleFix)); } - public long? IstanbulBlock { get => GetBlock(); set => SetBlock(value); } - public long? MuirGlacierBlock { get => GetBlock(); set => SetBlock(value); } - public long? BerlinBlock { get => GetBlock(); set => SetBlock(value); } - public long? LondonBlock { get => GetBlock(); set => SetBlock(value); } - public long? ArrowGlacierBlock { get => GetBlock(); set => SetBlock(value); } - public long? GrayGlacierBlock { get => GetBlock(); set => SetBlock(value); } - public long? MergeNetsplitBlock { get => GetBlock(nameof(Paris)); set => SetBlock(value, nameof(Paris)); } + public ulong? Eip150Block { get; set; } + public ulong? Eip155Block { get; set; } + public ulong? Eip158Block { get; set; } + + public ulong? TangerineWhistleBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? SpuriousDragonBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? ByzantiumBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? ConstantinopleBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? PetersburgBlock { get => GetBlock(nameof(ConstantinopleFix)); set => SetBlock(value, nameof(ConstantinopleFix)); } + public ulong? IstanbulBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? MuirGlacierBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? BerlinBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? LondonBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? ArrowGlacierBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? GrayGlacierBlock { get => GetBlock(); set => SetBlock(value); } + public ulong? MergeNetsplitBlock { get => GetBlock(nameof(Paris)); set => SetBlock(value, nameof(Paris)); } public ulong? ShanghaiTime { get => GetTime(); set => SetTime(value); } public ulong? CancunTime { get => GetTime(); set => SetTime(value); } @@ -73,13 +73,13 @@ public class GethGenesisConfigJson : IHasNamedForks public Address? DepositContractAddress { get; set; } public Dictionary? BlobSchedule { get; set; } - IReadOnlyDictionary? IHasNamedForks.NamedForkBlocks => _blocks; + IReadOnlyDictionary? IHasNamedForks.NamedForkBlocks => _blocks; IReadOnlyDictionary? IHasNamedForks.NamedForkTimestamps => _timestamps; - private long? GetBlock([CallerMemberName] string propertyOrForkName = "") - => _blocks.TryGetValue(StripSuffix(propertyOrForkName, "Block"), out long v) ? v : null; + private ulong? GetBlock([CallerMemberName] string propertyOrForkName = "") + => _blocks.TryGetValue(StripSuffix(propertyOrForkName, "Block"), out ulong v) ? v : null; - private void SetBlock(long? value, [CallerMemberName] string propertyOrForkName = "") + private void SetBlock(ulong? value, [CallerMemberName] string propertyOrForkName = "") { string forkName = StripSuffix(propertyOrForkName, "Block"); if (value is null) _blocks.Remove(forkName); diff --git a/src/Nethermind/Nethermind.Specs/ForkSchedule.cs b/src/Nethermind/Nethermind.Specs/ForkSchedule.cs index f3003af01149..16043d3a2db8 100644 --- a/src/Nethermind/Nethermind.Specs/ForkSchedule.cs +++ b/src/Nethermind/Nethermind.Specs/ForkSchedule.cs @@ -38,8 +38,8 @@ public sealed class ForkSchedule : IEnumerable { set => _entries.Add(kind switch { - ForkActivationKind.Block => new ForkSpec(key, value), - ForkActivationKind.Timestamp => new ForkSpec((ulong)key, value), + ForkActivationKind.Block => ForkSpec.AtBlock((ulong)key, value), + ForkActivationKind.Timestamp => ForkSpec.AtTimestamp((ulong)key, value), _ => throw new ArgumentOutOfRangeException(nameof(kind)), }); } @@ -48,8 +48,8 @@ public sealed class ForkSchedule : IEnumerable { set => _entries.Add(kind switch { - ForkActivationKind.Block => new ForkSpec((long)key, value), - ForkActivationKind.Timestamp => new ForkSpec(key, value), + ForkActivationKind.Block => ForkSpec.AtBlock(key, value), + ForkActivationKind.Timestamp => ForkSpec.AtTimestamp(key, value), _ => throw new ArgumentOutOfRangeException(nameof(kind)), }); } @@ -82,9 +82,9 @@ _ when keyExpression.EndsWith("BlockNumber", StringComparison.Ordinal) => ForkAc /// Activations to emit before iterating the schedule (e.g. Sepolia's merge-block /// boundary, which has no corresponding schedule entry). public ForkActivation[] ToTransitionActivations( - long postMergeBlock = 0L, + ulong postMergeBlock = 0, bool incrementBlockPerTimestampFork = true, - ReadOnlySpan excludeBlocks = default, + ReadOnlySpan excludeBlocks = default, ReadOnlySpan prepend = default) { int count = prepend.Length; @@ -115,8 +115,8 @@ public ForkActivation[] ToTransitionActivations( } else if (fork.Timestamp is { } timestamp) { - long blockForTimestamp = incrementBlockPerTimestampFork - ? postMergeBlock + timestampIndex + ulong blockForTimestamp = incrementBlockPerTimestampFork + ? postMergeBlock + (ulong)timestampIndex : postMergeBlock; result[index++] = (blockForTimestamp, timestamp); timestampIndex++; diff --git a/src/Nethermind/Nethermind.Specs/ForkScheduleSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ForkScheduleSpecProvider.cs index d3a5c5161047..f3352b891797 100644 --- a/src/Nethermind/Nethermind.Specs/ForkScheduleSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/ForkScheduleSpecProvider.cs @@ -12,7 +12,7 @@ namespace Nethermind.Specs; public abstract class ForkScheduleSpecProvider : IForkAwareSpecProvider { - public const long GenesisBlockNumber = 0L; + public const ulong GenesisBlockNumber = 0; public const ulong GenesisTimestamp = 0UL; private readonly Lazy _schedule; @@ -61,12 +61,12 @@ public IReleaseSpec GetSpec(ForkActivation forkActivation) /// private readonly struct Index { - private readonly long[] _blockKeys; + private readonly ulong[] _blockKeys; private readonly IReleaseSpec[] _blockSpecs; private readonly ulong[] _timestampKeys; private readonly IReleaseSpec[] _timestampSpecs; - private Index(long[] blockKeys, IReleaseSpec[] blockSpecs, ulong[] timestampKeys, IReleaseSpec[] timestampSpecs) + private Index(ulong[] blockKeys, IReleaseSpec[] blockSpecs, ulong[] timestampKeys, IReleaseSpec[] timestampSpecs) { _blockKeys = blockKeys; _blockSpecs = blockSpecs; @@ -74,7 +74,7 @@ private Index(long[] blockKeys, IReleaseSpec[] blockSpecs, ulong[] timestampKeys _timestampSpecs = timestampSpecs; } - public long LastBlockKey => _blockKeys[^1]; + public ulong LastBlockKey => _blockKeys[^1]; public static Index Build(ForkSpec[] schedule) { @@ -86,7 +86,7 @@ public static Index Build(ForkSpec[] schedule) else if (fork.Timestamp.HasValue) timestampCount++; } - long[] blockKeys = new long[blockCount]; + ulong[] blockKeys = new ulong[blockCount]; IReleaseSpec[] blockSpecs = new IReleaseSpec[blockCount]; ulong[] timestampKeys = new ulong[timestampCount]; IReleaseSpec[] timestampSpecs = new IReleaseSpec[timestampCount]; @@ -95,7 +95,7 @@ public static Index Build(ForkSpec[] schedule) int ti = 0; foreach (ForkSpec fork in schedule) { - if (fork.Block is long b) { blockKeys[bi] = b; blockSpecs[bi] = fork.Spec; bi++; } + if (fork.Block is ulong b) { blockKeys[bi] = b; blockSpecs[bi] = fork.Spec; bi++; } else if (fork.Timestamp is ulong t) { timestampKeys[ti] = t; timestampSpecs[ti] = fork.Spec; ti++; } } @@ -103,7 +103,7 @@ public static Index Build(ForkSpec[] schedule) } // Schedule always has a genesis (block 0) entry, so idx >= 0 for any non-negative block number. - public IReleaseSpec LookupBlock(long blockNumber) => + public IReleaseSpec LookupBlock(ulong blockNumber) => _blockSpecs[FindLastAtMost(_blockKeys, blockNumber)]; public IReleaseSpec? LookupTimestamp(ulong timestamp) @@ -126,7 +126,7 @@ private static int FindLastAtMost(ReadOnlySpan sortedKeys, T value) where } } - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) MergeBlockNumber = (ForkActivation)blockNumber; @@ -137,7 +137,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public ForkActivation? MergeBlockNumber { get; private set; } public UInt256? TerminalTotalDifficulty { get; private set; } public IReleaseSpec GenesisSpec => ForkSchedule[0].Spec; - public virtual long? DaoBlockNumber => null; + public virtual ulong? DaoBlockNumber => null; public virtual ulong ChainId => NetworkId; public ForkActivation[] TransitionActivations { get; protected set; } = []; diff --git a/src/Nethermind/Nethermind.Specs/ForkSpec.cs b/src/Nethermind/Nethermind.Specs/ForkSpec.cs index 17ee4c0ab764..6606d59821b5 100644 --- a/src/Nethermind/Nethermind.Specs/ForkSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ForkSpec.cs @@ -5,8 +5,8 @@ namespace Nethermind.Specs; -public readonly record struct ForkSpec(long? Block, ulong? Timestamp, IReleaseSpec Spec) +public readonly record struct ForkSpec(ulong? Block, ulong? Timestamp, IReleaseSpec Spec) { - public ForkSpec(ulong timestamp, IReleaseSpec spec) : this(null, timestamp, spec) { } - public ForkSpec(long block, IReleaseSpec spec) : this(block, null, spec) { } + public static ForkSpec AtTimestamp(ulong timestamp, IReleaseSpec spec) => new(null, timestamp, spec); + public static ForkSpec AtBlock(ulong block, IReleaseSpec spec) => new(block, null, spec); } diff --git a/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs b/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs index 4a78cd57b988..8526ee8104cb 100644 --- a/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs +++ b/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs @@ -13,8 +13,8 @@ public override void Apply(NamedReleaseSpec spec) spec.Name = "Olympic"; spec.MaximumExtraDataSize = 32; spec.MaxCodeSize = long.MaxValue; - spec.MinGasLimit = 5000; - spec.GasLimitBoundDivisor = 0x0400; + spec.MinGasLimit = 5000UL; + spec.GasLimitBoundDivisor = 0x0400UL; spec.BlockReward = new UInt256(5000000000000000000ul); spec.DifficultyBoundDivisor = 0x0800; spec.IsEip3607Enabled = true; diff --git a/src/Nethermind/Nethermind.Specs/FrontierSpecProvider.cs b/src/Nethermind/Nethermind.Specs/FrontierSpecProvider.cs index f172aba8b0e4..ae1442c1cb79 100644 --- a/src/Nethermind/Nethermind.Specs/FrontierSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/FrontierSpecProvider.cs @@ -12,7 +12,7 @@ public class FrontierSpecProvider : ISpecProvider { private ForkActivation? _theMergeBlock = null; - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) _theMergeBlock = (ForkActivation)blockNumber; @@ -27,7 +27,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public IReleaseSpec GetSpec(ForkActivation forkActivation) => Frontier.Instance; - public long? DaoBlockNumber { get; } = null; + public ulong? DaoBlockNumber { get; } = null; public ulong? BeaconChainGenesisTimestamp => null; public ulong NetworkId => Core.BlockchainIds.Mainnet; diff --git a/src/Nethermind/Nethermind.Specs/GnosisSpecProvider.cs b/src/Nethermind/Nethermind.Specs/GnosisSpecProvider.cs index dd34213316bf..8f84ba49782c 100644 --- a/src/Nethermind/Nethermind.Specs/GnosisSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/GnosisSpecProvider.cs @@ -11,12 +11,12 @@ namespace Nethermind.Specs; public class GnosisSpecProvider : ForkScheduleSpecProvider { - public const long ConstantinopleBlockNumber = 1_604_400; - public const long ConstantinopleFixBlockNumber = 2_508_800; - public const long IstanbulBlockNumber = 7_298_030; - public const long PosdaoTransitionBlockNumber = 9_186_425; // does not alter EVM specs, fork-id boundary only - public const long BerlinBlockNumber = 16_101_500; - public const long LondonBlockNumber = 19_040_000; + public const ulong ConstantinopleBlockNumber = 1_604_400; + public const ulong ConstantinopleFixBlockNumber = 2_508_800; + public const ulong IstanbulBlockNumber = 7_298_030; + public const ulong PosdaoTransitionBlockNumber = 9_186_425; // does not alter EVM specs, fork-id boundary only + public const ulong BerlinBlockNumber = 16_101_500; + public const ulong LondonBlockNumber = 19_040_000; public const ulong BeaconChainGenesisTimestampConst = 0x61b10dbc; public const ulong ShanghaiTimestamp = 0x64c8edbc; public const ulong CancunTimestamp = 0x65ef4dbc; @@ -63,7 +63,7 @@ private GnosisSpecProvider() : base( public override ulong NetworkId => BlockchainIds.Gnosis; public override ulong ChainId => BlockchainIds.Gnosis; public override ulong? BeaconChainGenesisTimestamp => BeaconChainGenesisTimestampConst; - public override long? DaoBlockNumber => null; + public override ulong? DaoBlockNumber => null; public string SealEngine => SealEngineType.AuRa; public static GnosisSpecProvider Instance { get; } = new(); diff --git a/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs b/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs index 174ef2c91e8a..65eb08296c0b 100644 --- a/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs @@ -9,19 +9,19 @@ namespace Nethermind.Specs; public class MainnetSpecProvider : ForkScheduleSpecProvider { - public const long HomesteadBlockNumber = 1_150_000; - public const long DaoForkBlockNumber = 1_920_000; - public const long TangerineWhistleBlockNumber = 2_463_000; - public const long SpuriousDragonBlockNumber = 2_675_000; - public const long ByzantiumBlockNumber = 4_370_000; - public const long ConstantinopleFixBlockNumber = 7_280_000; - public const long IstanbulBlockNumber = 9_069_000; - public const long MuirGlacierBlockNumber = 9_200_000; - public const long BerlinBlockNumber = 12_244_000; - public const long LondonBlockNumber = 12_965_000; - public const long ArrowGlacierBlockNumber = 13_773_000; - public const long GrayGlacierBlockNumber = 15_050_000; - public const long ParisBlockNumber = 15_537_393; + public const ulong HomesteadBlockNumber = 1_150_000; + public const ulong DaoForkBlockNumber = 1_920_000; + public const ulong TangerineWhistleBlockNumber = 2_463_000; + public const ulong SpuriousDragonBlockNumber = 2_675_000; + public const ulong ByzantiumBlockNumber = 4_370_000; + public const ulong ConstantinopleFixBlockNumber = 7_280_000; + public const ulong IstanbulBlockNumber = 9_069_000; + public const ulong MuirGlacierBlockNumber = 9_200_000; + public const ulong BerlinBlockNumber = 12_244_000; + public const ulong LondonBlockNumber = 12_965_000; + public const ulong ArrowGlacierBlockNumber = 13_773_000; + public const ulong GrayGlacierBlockNumber = 15_050_000; + public const ulong ParisBlockNumber = 15_537_393; public const ulong GenesisBlockTimestamp = 0x55ba4215; public const ulong BeaconChainGenesisTimestampConst = 0x5fc63057; public const ulong ShanghaiBlockTimestamp = 0x64373057; @@ -73,7 +73,7 @@ private MainnetSpecProvider(ForkSchedule schedule) : base(schedule, excludeBlocks: [ParisBlockNumber]); public override ulong NetworkId => Core.BlockchainIds.Mainnet; - public override long? DaoBlockNumber => DaoForkBlockNumber; + public override ulong? DaoBlockNumber => DaoForkBlockNumber; public override ulong? BeaconChainGenesisTimestamp => BeaconChainGenesisTimestampConst; public override ulong TimestampFork => ShanghaiBlockTimestamp; diff --git a/src/Nethermind/Nethermind.Specs/MordenSpecProvider.cs b/src/Nethermind/Nethermind.Specs/MordenSpecProvider.cs index 3f9edd47dbd6..b7abc7ca388e 100644 --- a/src/Nethermind/Nethermind.Specs/MordenSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/MordenSpecProvider.cs @@ -9,8 +9,8 @@ namespace Nethermind.Specs; public class MordenSpecProvider : ForkScheduleSpecProvider { - public const long HomesteadBlockNumber = 494_000; - public const long SpuriousDragonBlockNumber = 1_885_000; + public const ulong HomesteadBlockNumber = 494_000; + public const ulong SpuriousDragonBlockNumber = 1_885_000; private MordenSpecProvider() : this(new ForkSchedule { diff --git a/src/Nethermind/Nethermind.Specs/OlympicSpecProvider.cs b/src/Nethermind/Nethermind.Specs/OlympicSpecProvider.cs index b3556fa01aac..1b5737fd712c 100644 --- a/src/Nethermind/Nethermind.Specs/OlympicSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/OlympicSpecProvider.cs @@ -11,7 +11,7 @@ public class OlympicSpecProvider : ISpecProvider { private ForkActivation? _theMergeBlock = null; - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) _theMergeBlock = (ForkActivation)blockNumber; @@ -26,7 +26,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public IReleaseSpec GetSpec(ForkActivation forkActivation) => Olympic.Instance; - public long? DaoBlockNumber => 0L; + public ulong? DaoBlockNumber => 0UL; public ulong? BeaconChainGenesisTimestamp => null; public ulong NetworkId => Core.BlockchainIds.Olympic; diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs index 7f2cfd47e2f0..314a3c2d9ffc 100644 --- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs @@ -17,14 +17,14 @@ public class ReleaseSpec : IReleaseSpec public string Name { get; set; } = "Custom"; public long MaximumExtraDataSize { get; set; } public long MaxCodeSize { get; set; } - public long MinGasLimit { get; set; } + public ulong MinGasLimit { get; set; } public long MinHistoryRetentionEpochs { get; set; } public long MinBalRetentionEpochs { get; set; } - public long GasLimitBoundDivisor { get; set; } + public ulong GasLimitBoundDivisor { get; set; } public UInt256 BlockReward { get; set; } - public long DifficultyBombDelay { get; set; } - public long DifficultyBoundDivisor { get; set; } - public long? FixedDifficulty { get; set; } + public ulong DifficultyBombDelay { get; set; } + public ulong DifficultyBoundDivisor { get; set; } + public ulong? FixedDifficulty { get; set; } public int MaximumUncleCount { get; set; } public bool IsTimeAdjustmentPostOlympic { get; set; } public bool IsEip2Enabled { get; set; } @@ -66,7 +66,7 @@ public class ReleaseSpec : IReleaseSpec public bool IsEip3541Enabled { get; set; } public bool ValidateChainId { get; set; } public bool ValidateReceipts { get; set; } - public long Eip1559TransitionBlock { get; set; } + public ulong Eip1559TransitionBlock { get; set; } public ulong WithdrawalTimestamp { get; set; } public ulong Eip4844TransitionTimestamp { get; set; } public Address? FeeCollector { get; set; } @@ -129,7 +129,7 @@ public class ReleaseSpec : IReleaseSpec FrozenSet IReleaseSpec.Precompiles => _precompiles ??= BuildPrecompilesCache(); private SpecGasCosts? _gasCosts; public SpecGasCosts GasCosts => _gasCosts ??= new SpecGasCosts(this); - public long Eip2935RingBufferSize { get; set; } = Eip2935Constants.RingBufferSize; + public ulong Eip2935RingBufferSize { get; set; } = Eip2935Constants.RingBufferSize; public virtual FrozenSet BuildPrecompilesCache() { HashSet cache = diff --git a/src/Nethermind/Nethermind.Specs/SepoliaSpecProvider.cs b/src/Nethermind/Nethermind.Specs/SepoliaSpecProvider.cs index adaaa0dffe40..e79f9e557079 100644 --- a/src/Nethermind/Nethermind.Specs/SepoliaSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/SepoliaSpecProvider.cs @@ -10,7 +10,7 @@ namespace Nethermind.Specs; public class SepoliaSpecProvider : ForkScheduleSpecProvider { - public const long MergeForkIdBlockNumber = 1735371; + public const ulong MergeForkIdBlockNumber = 1735371; public const ulong BeaconChainGenesisTimestampConst = 0x62b07d60; public const ulong ShanghaiTimestamp = 0x63fd7d60; public const ulong CancunTimestamp = 0x65B97D60; diff --git a/src/Nethermind/Nethermind.Specs/SingleReleaseSpecProvider.cs b/src/Nethermind/Nethermind.Specs/SingleReleaseSpecProvider.cs index 75fb5a087fde..7e3a4b8d69a9 100644 --- a/src/Nethermind/Nethermind.Specs/SingleReleaseSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/SingleReleaseSpecProvider.cs @@ -12,7 +12,7 @@ public class SingleReleaseSpecProvider : ISpecProvider { private ForkActivation? _theMergeBlock = null; - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) _theMergeBlock = (ForkActivation)blockNumber; @@ -44,7 +44,7 @@ public SingleReleaseSpecProvider(IReleaseSpec releaseSpec, ulong networkId, ulon public IReleaseSpec GetSpec(ForkActivation forkActivation) => _releaseSpec; - public long? DaoBlockNumber { get; } + public ulong? DaoBlockNumber { get; } public ulong? BeaconChainGenesisTimestamp { get; } public string SealEngine { get; set; } = SealEngineType.Ethash; diff --git a/src/Nethermind/Nethermind.Specs/TestSpecProvider.cs b/src/Nethermind/Nethermind.Specs/TestSpecProvider.cs index 2e8e199c9130..dbb184ad972a 100644 --- a/src/Nethermind/Nethermind.Specs/TestSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/TestSpecProvider.cs @@ -15,7 +15,7 @@ public TestSpecProvider(IReleaseSpec initialSpecToReturn) NextForkSpec = initialSpecToReturn; } - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) { if (blockNumber is not null) MergeBlockNumber = (ForkActivation)blockNumber; @@ -33,9 +33,9 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public IReleaseSpec GetSpec(ForkActivation forkActivation) => forkActivation.BlockNumber == 0 || forkActivation.BlockNumber < ForkOnBlockNumber ? GenesisSpec : NextForkSpec; public IReleaseSpec NextForkSpec { get; set; } - public long? ForkOnBlockNumber { get; set; } + public ulong? ForkOnBlockNumber { get; set; } - public long? DaoBlockNumber { get; set; } + public ulong? DaoBlockNumber { get; set; } public ulong? BeaconChainGenesisTimestamp { get; set; } public ulong? _networkId; public ulong NetworkId { get { return _networkId ?? TestBlockchainIds.NetworkId; } set { _networkId = value; } } diff --git a/src/Nethermind/Nethermind.State.Flat.Test/CompactionScheduleTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/CompactionScheduleTests.cs index 4de31d81c55f..c9e1dc6dec45 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/CompactionScheduleTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/CompactionScheduleTests.cs @@ -23,7 +23,7 @@ public void Constructor_NoStoredValue_GeneratesPersistsAndReturnsValueInRange() CompactionSchedule schedule = new(metadataDb, config, LimboLogs.Instance); - Assert.That(schedule.Offset, Is.InRange(0L, (long)int.MaxValue - 1)); + Assert.That(schedule.Offset, Is.InRange(0UL, (ulong)int.MaxValue - 1)); byte[]? stored = metadataDb.Get(MetadataDbKeys.FlatDbCompactionOffset); Assert.That(stored, Is.Not.Null); Assert.That(stored.AsRlpValueContext().DecodeLong(), Is.EqualTo(schedule.Offset)); @@ -66,7 +66,7 @@ public void Constructor_RegenerateFlagTrue_OverwritesStoredOffset() CompactionSchedule schedule = new(metadataDb, config, LimboLogs.Instance); - Assert.That(schedule.Offset, Is.InRange(0L, (long)int.MaxValue - 1)); + Assert.That(schedule.Offset, Is.InRange(0UL, (ulong)int.MaxValue - 1)); long stored = metadataDb.Get(MetadataDbKeys.FlatDbCompactionOffset)!.AsRlpValueContext().DecodeLong(); Assert.That(stored, Is.EqualTo(schedule.Offset)); } @@ -81,7 +81,7 @@ public void Constructor_StoredNegative_Regenerates(long badStored) CompactionSchedule schedule = new(metadataDb, config, LimboLogs.Instance); - Assert.That(schedule.Offset, Is.InRange(0L, (long)int.MaxValue - 1)); + Assert.That(schedule.Offset, Is.InRange(0UL, (ulong)int.MaxValue - 1)); long stored = metadataDb.Get(MetadataDbKeys.FlatDbCompactionOffset)!.AsRlpValueContext().DecodeLong(); Assert.That(stored, Is.EqualTo(schedule.Offset)); } @@ -98,17 +98,17 @@ public void Constructor_CompactSizeDisabled_OffsetIsZeroAndDbUntouched() Assert.That(metadataDb.Get(MetadataDbKeys.FlatDbCompactionOffset), Is.Null); } - [TestCase(1, 1)] // odd block: 1 & -1 = 1 - [TestCase(2, 2)] - [TestCase(4, 4)] - [TestCase(6, 2)] - [TestCase(8, 8)] - [TestCase(10, 2)] - [TestCase(12, 4)] - [TestCase(14, 2)] - [TestCase(16, 16)] - [TestCase(32, 16)] // capped at CompactSize=16 - public void GetCompactSize_OffsetZero_MatchesBitTrick(long blockNumber, int expected) + [TestCase(1UL, 1)] // odd block: 1 & -1 = 1 + [TestCase(2UL, 2)] + [TestCase(4UL, 4)] + [TestCase(6UL, 2)] + [TestCase(8UL, 8)] + [TestCase(10UL, 2)] + [TestCase(12UL, 4)] + [TestCase(14UL, 2)] + [TestCase(16UL, 16)] + [TestCase(32UL, 16)] // capped at CompactSize=16 + public void GetCompactSize_OffsetZero_MatchesBitTrick(ulong blockNumber, int expected) { FlatDbConfig config = new() { CompactSize = 16 }; CompactionSchedule schedule = ScheduleHelper.CreateWithOffset(config, 0); @@ -116,12 +116,12 @@ public void GetCompactSize_OffsetZero_MatchesBitTrick(long blockNumber, int expe Assert.That(schedule.GetCompactSize(blockNumber), Is.EqualTo(expected)); } - [TestCase(0, 1)] // block 0 always 1 - [TestCase(13, 16)] // 13+3 = 16 -> full - [TestCase(16, 1)] // 16+3 = 19 -> 19 & -19 = 1 (caller treats as no compaction) - [TestCase(5, 8)] // 5+3 = 8 - [TestCase(29, 16)] // 29+3 = 32 -> 32 & -32 = 32, capped at 16 - public void GetCompactSize_WithOffset3_ShiftsBoundaries(long blockNumber, int expected) + [TestCase(0UL, 1)] // block 0 always 1 + [TestCase(13UL, 16)] // 13+3 = 16 -> full + [TestCase(16UL, 1)] // 16+3 = 19 -> 19 & -19 = 1 (caller treats as no compaction) + [TestCase(5UL, 8)] // 5+3 = 8 + [TestCase(29UL, 16)] // 29+3 = 32 -> 32 & -32 = 32, capped at 16 + public void GetCompactSize_WithOffset3_ShiftsBoundaries(ulong blockNumber, int expected) { FlatDbConfig config = new() { CompactSize = 16 }; CompactionSchedule schedule = ScheduleHelper.CreateWithOffset(config, 3); @@ -138,7 +138,7 @@ public void GetCompactSize_OffsetLargerThanCompactSize_EquivalentToOffsetModComp CompactionSchedule small = ScheduleHelper.CreateWithOffset(config, smallOffset); CompactionSchedule large = ScheduleHelper.CreateWithOffset(config, largeOffset); - for (long block = 1; block <= 64; block++) + for (ulong block = 1UL; block <= 64UL; block++) { Assert.That(large.GetCompactSize(block), Is.EqualTo(small.GetCompactSize(block)), $"Tier mismatch at block {block} between offset {smallOffset} and {largeOffset}"); @@ -147,13 +147,13 @@ public void GetCompactSize_OffsetLargerThanCompactSize_EquivalentToOffsetModComp } } - [TestCase(0, 0, 16)] // from 0, offset 0 -> next full at 16 - [TestCase(16, 0, 32)] // from boundary, advance by CompactSize - [TestCase(15, 0, 16)] - [TestCase(0, 3, 13)] // from 0, offset 3 -> 0+(16-3) = 13 - [TestCase(13, 3, 29)] // from boundary 13, advance by 16 - [TestCase(7, 5, 11)] // from 7, offset 5 -> (7+5)%16=12, next at 7+(16-12)=11 - public void NextFullCompactionAfter_VariousOffsets(long from, int offset, long expected) + [TestCase(0UL, 0, 16UL)] // from 0, offset 0 -> next full at 16 + [TestCase(16UL, 0, 32UL)] // from boundary, advance by CompactSize + [TestCase(15UL, 0, 16UL)] + [TestCase(0UL, 3, 13UL)] // from 0, offset 3 -> 0+(16-3) = 13 + [TestCase(13UL, 3, 29UL)] // from boundary 13, advance by 16 + [TestCase(7UL, 5, 11UL)] // from 7, offset 5 -> (7+5)%16=12, next at 7+(16-12)=11 + public void NextFullCompactionAfter_VariousOffsets(ulong from, int offset, ulong expected) { FlatDbConfig config = new() { CompactSize = 16 }; CompactionSchedule schedule = ScheduleHelper.CreateWithOffset(config, offset); @@ -167,7 +167,7 @@ public void NextFullCompactionAfter_CompactSizeDisabled_ReturnsLongMaxValue() FlatDbConfig config = new() { CompactSize = 1 }; CompactionSchedule schedule = new(new MemDb(), config, LimboLogs.Instance); - Assert.That(schedule.NextFullCompactionAfter(0), Is.EqualTo(long.MaxValue)); + Assert.That(schedule.NextFullCompactionAfter(0), Is.EqualTo(ulong.MaxValue)); } [Test] diff --git a/src/Nethermind/Nethermind.State.Flat.Test/FlatDbManagerTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/FlatDbManagerTests.cs index d780153c54f2..f00ac7cc8b83 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/FlatDbManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/FlatDbManagerTests.cs @@ -62,7 +62,7 @@ public void TearDown() LimboLogs.Instance, enableDetailedMetrics: false); - private static StateId CreateStateId(long blockNumber, byte rootByte = 0) + private static StateId CreateStateId(ulong blockNumber, byte rootByte = 0) { byte[] bytes = new byte[32]; bytes[0] = rootByte; diff --git a/src/Nethermind/Nethermind.State.Flat.Test/Persistence/BloomFilter/BloomFilterTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/Persistence/BloomFilter/BloomFilterTests.cs index 4d1e4e1e29f2..bad24f21c94c 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/Persistence/BloomFilter/BloomFilterTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/Persistence/BloomFilter/BloomFilterTests.cs @@ -110,7 +110,7 @@ public void Add_LargeNumberOfItems_ShouldWork() const int totalItems = 500; using Bloom bloom = NewBloom(capacity: totalItems); - for (ulong i = 0; i < (ulong)totalItems; i++) bloom.Add(i); + for (ulong i = 0; i < totalItems; i++) bloom.Add(i); Assert.That(bloom.Count, Is.EqualTo(totalItems)); for (ulong i = 0; i < 50; i++) diff --git a/src/Nethermind/Nethermind.State.Flat.Test/PersistenceManagerTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/PersistenceManagerTests.cs index 905ac06c34d3..e2b97c160f36 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/PersistenceManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/PersistenceManagerTests.cs @@ -60,7 +60,7 @@ public void TearDown() { } - private StateId CreateStateId(long blockNumber, byte rootByte = 0) + private StateId CreateStateId(ulong blockNumber, byte rootByte = 0) { byte[] bytes = new byte[32]; bytes[0] = rootByte; @@ -118,7 +118,7 @@ public void DetermineSnapshotToPersist_SufficientDepthAndFinalized(bool useCompa StateId latest = CreateStateId(100); // Vary target block and compaction based on parameter - int targetBlock = useCompacted ? 16 : 1; // compacted uses 16, fallback uses 1 + ulong targetBlock = useCompacted ? 16UL : 1UL; // compacted uses 16, fallback uses 1 StateId target = CreateStateId(targetBlock); _finalizedStateProvider.SetFinalizedBlockNumber(100); @@ -165,7 +165,7 @@ public void DetermineSnapshotToPersist_UnfinalizedAndAboveForceLimit(bool useCom StateId latest = CreateStateId(300); // Vary target block and compaction based on parameter - int targetBlock = useCompacted ? 16 : 1; // compacted uses 16, fallback uses 1 + ulong targetBlock = useCompacted ? 16UL : 1UL; // compacted uses 16, fallback uses 1 StateId target = CreateStateId(targetBlock); _finalizedStateProvider.SetFinalizedBlockNumber(10); @@ -390,10 +390,10 @@ public void AddToPersistence_WithAvailableSnapshot_PersistsAndUpdatesState() #region Offset Behavior - [TestCase(3, 13)] - [TestCase(5, 11)] - [TestCase(0, 16)] - public void DetermineSnapshotToPersist_WithOffset_FirstBoundaryShifted(int offset, int expectedTargetBlock) + [TestCase(3, 13UL)] + [TestCase(5, 11UL)] + [TestCase(0, 16UL)] + public void DetermineSnapshotToPersist_WithOffset_FirstBoundaryShifted(int offset, ulong expectedTargetBlock) { // Fresh DB: currentPersistedState = Block0 (block 0). // With CompactSize=16 and offset=N, the next full compaction boundary is at block 16-N. @@ -543,16 +543,16 @@ public void FlushToPersistence_PersistsMultipleSnapshots_InOrder() private class TestFinalizedStateProvider : IFinalizedStateProvider { - private long _finalizedBlockNumber; - private readonly Dictionary _finalizedStateRoots = []; + private ulong _finalizedBlockNumber; + private readonly Dictionary _finalizedStateRoots = []; - public long FinalizedBlockNumber => _finalizedBlockNumber; + public ulong FinalizedBlockNumber => _finalizedBlockNumber; - public void SetFinalizedBlockNumber(long blockNumber) => _finalizedBlockNumber = blockNumber; + public void SetFinalizedBlockNumber(ulong blockNumber) => _finalizedBlockNumber = blockNumber; - public void SetFinalizedStateRootAt(long blockNumber, Hash256 stateRoot) => _finalizedStateRoots[blockNumber] = stateRoot; + public void SetFinalizedStateRootAt(ulong blockNumber, Hash256 stateRoot) => _finalizedStateRoots[blockNumber] = stateRoot; - public Hash256? GetFinalizedStateRootAt(long blockNumber) => + public Hash256? GetFinalizedStateRootAt(ulong blockNumber) => _finalizedStateRoots.TryGetValue(blockNumber, out Hash256? root) ? root : null; } diff --git a/src/Nethermind/Nethermind.State.Flat.Test/SnapshotCompactorTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/SnapshotCompactorTests.cs index 3b89ece9484b..9c9e20a76659 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/SnapshotCompactorTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/SnapshotCompactorTests.cs @@ -31,16 +31,16 @@ public void SetUp() _compactor = new SnapshotCompactor(_config, ScheduleHelper.CreateWithOffset(_config, 0), _resourcePool, _snapshotRepository, LimboLogs.Instance); } - private static StateId CreateStateId(long blockNumber, byte rootByte = 0) + private static StateId CreateStateId(ulong blockNumber, byte rootByte = 0) { byte[] bytes = new byte[32]; bytes[0] = rootByte; return new StateId(blockNumber, new ValueHash256(bytes)); } - private void BuildSnapshotChain(long startBlock, long endBlock) + private void BuildSnapshotChain(ulong startBlock, ulong endBlock) { - for (long i = startBlock; i < endBlock; i++) + for (ulong i = startBlock; i < endBlock; i++) { StateId from = CreateStateId(i); StateId to = CreateStateId(i + 1); @@ -414,10 +414,10 @@ public void GetSnapshotsToCompact_FullCompaction_ReturnsMultipleSnapshots() Assert.That(snapshots.Count, Is.EqualTo(16)); } - [TestCase(4, 4)] // 4 & -4 = 4, compact size 4, blocks 0->4 - [TestCase(8, 8)] // 8 & -8 = 8, compact size 8, blocks 0->8 - [TestCase(12, 4)] // 12 & -12 = 4, compact size 4, blocks 8->12 - public void GetSnapshotsToCompact_PowerOf2Compaction_ReturnsCorrectCount(long blockNumber, int expectedCount) + [TestCase(4UL, 4)] // 4 & -4 = 4, compact size 4, blocks 0->4 + [TestCase(8UL, 8)] // 8 & -8 = 8, compact size 8, blocks 0->8 + [TestCase(12UL, 4)] // 12 & -12 = 4, compact size 4, blocks 8->12 + public void GetSnapshotsToCompact_PowerOf2Compaction_ReturnsCorrectCount(ulong blockNumber, int expectedCount) { BuildSnapshotChain(0, blockNumber); @@ -450,7 +450,7 @@ public void GetSnapshotsToCompact_SingleSnapshot_ReturnsEmpty() public void GetSnapshotsToCompact_IncompleteChain_ReturnsEmpty() { // Missing 1 - for (long i = 2; i < 16; i++) + for (ulong i = 2; i < 16; i++) { StateId from = new(i, Keccak.Zero); StateId to = new(i + 1, Keccak.Zero); @@ -478,7 +478,7 @@ public void DoCompactSnapshot_ValidChain_CreatesCompactedSnapshot() StateId targetFrom = CreateStateId(15); StateId targetTo = CreateStateId(16); Snapshot targetSnapshot = _resourcePool.CreateSnapshot(targetFrom, targetTo, ResourcePool.Usage.ReadOnlyProcessingEnv); - targetSnapshot.Content.Accounts[TestItem.AddressB] = new Account((UInt256)20, (UInt256)2000); + targetSnapshot.Content.Accounts[TestItem.AddressB] = new Account(20UL, 2000UL); _snapshotRepository.TryAddSnapshot(targetSnapshot); _snapshotRepository.AddStateId(targetTo); @@ -499,7 +499,7 @@ public void GetSnapshotsToCompact_Size2Compaction_AllowedByDefault() SnapshotRepository repo = new(LimboLogs.Instance); SnapshotCompactor compactor = new(config, ScheduleHelper.CreateWithOffset(config, 0), _resourcePool, repo, LimboLogs.Instance); - for (long i = 0; i < 2; i++) + for (ulong i = 0; i < 2; i++) { StateId from = CreateStateId(i); StateId to = CreateStateId(i + 1); @@ -517,12 +517,12 @@ public void GetSnapshotsToCompact_Size2Compaction_AllowedByDefault() targetSnapshot!.Dispose(); } - [TestCase(1)] - [TestCase(3)] - [TestCase(5)] - [TestCase(7)] - [TestCase(9)] - public void GetSnapshotsToCompact_OddBlock_ReturnsEmpty(long blockNumber) + [TestCase(1UL)] + [TestCase(3UL)] + [TestCase(5UL)] + [TestCase(7UL)] + [TestCase(9UL)] + public void GetSnapshotsToCompact_OddBlock_ReturnsEmpty(ulong blockNumber) { BuildSnapshotChain(0, blockNumber); @@ -535,17 +535,17 @@ public void GetSnapshotsToCompact_OddBlock_ReturnsEmpty(long blockNumber) Assert.That(snapshots.Count, Is.EqualTo(0)); } - [TestCase(2, 2)] // blockNumber & -blockNumber = 2 - [TestCase(4, 4)] - [TestCase(6, 2)] - [TestCase(8, 8)] - [TestCase(10, 2)] - [TestCase(12, 4)] - [TestCase(14, 2)] - [TestCase(16, 16)] - public void GetSnapshotsToCompact_PowerOf2_CompactSizeMatchesBlockAlignment(long blockNumber, int expectedCompactSize) + [TestCase(2UL, 2)] // blockNumber & -blockNumber = 2 + [TestCase(4UL, 4)] + [TestCase(6UL, 2)] + [TestCase(8UL, 8)] + [TestCase(10UL, 2)] + [TestCase(12UL, 4)] + [TestCase(14UL, 2)] + [TestCase(16UL, 16)] + public void GetSnapshotsToCompact_PowerOf2_CompactSizeMatchesBlockAlignment(ulong blockNumber, int expectedCompactSize) { - int actualCompactSize = (int)Math.Min(blockNumber & -blockNumber, 16); + int actualCompactSize = (int)Math.Min(blockNumber & (~blockNumber + 1UL), 16UL); Assert.That(actualCompactSize, Is.EqualTo(expectedCompactSize)); } @@ -558,7 +558,7 @@ public void GetSnapshotsToCompact_WithOffset_FullCompactionShiftedFromBoundary() SnapshotRepository repo = new(LimboLogs.Instance); SnapshotCompactor compactor = new(config, ScheduleHelper.CreateWithOffset(config, 3), _resourcePool, repo, LimboLogs.Instance); - for (long i = 0; i < 29; i++) + for (ulong i = 0; i < 29; i++) { StateId from = CreateStateId(i); StateId to = CreateStateId(i + 1); diff --git a/src/Nethermind/Nethermind.State.Flat.Test/SnapshotRepositoryTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/SnapshotRepositoryTests.cs index fb65c4e7ad04..20c4f120d432 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/SnapshotRepositoryTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/SnapshotRepositoryTests.cs @@ -27,7 +27,7 @@ public void SetUp() _repository = new SnapshotRepository(LimboLogs.Instance); } - private StateId CreateStateId(long blockNumber, byte rootByte = 0) + private StateId CreateStateId(ulong blockNumber, byte rootByte = 0) { byte[] bytes = new byte[32]; bytes[0] = rootByte; @@ -44,7 +44,7 @@ private Snapshot CreateSnapshot(StateId from, StateId to, bool withData = false) return snapshot; } - private Snapshot AddSnapshotToRepository(long fromBlock, long toBlock, bool compacted = false, bool withData = false) + private Snapshot AddSnapshotToRepository(ulong fromBlock, ulong toBlock, bool compacted = false, bool withData = false) { StateId from = CreateStateId(fromBlock); StateId to = CreateStateId(toBlock); @@ -64,10 +64,10 @@ private Snapshot AddSnapshotToRepository(long fromBlock, long toBlock, bool comp return snapshot; } - private List BuildSnapshotChain(long startBlock, long endBlock) + private List BuildSnapshotChain(ulong startBlock, ulong endBlock) { List snapshots = []; - for (long i = startBlock; i < endBlock; i++) + for (ulong i = startBlock; i < endBlock; i++) { snapshots.Add(AddSnapshotToRepository(i, i + 1)); } @@ -290,9 +290,9 @@ public void GetSnapshotBeforeStateId_StatesBeforeTarget() states.Dispose(); } - [TestCase(-1)] - [TestCase(long.MinValue)] - public void GetSnapshotBeforeStateId_NegativeBlockNumber_ReturnsEmpty(long blockNumber) + [TestCase(ulong.MaxValue)] + [TestCase(ulong.MinValue)] + public void GetSnapshotBeforeStateId_BoundaryBlockNumber_ReturnsEmpty(ulong blockNumber) { _repository.AddStateId(CreateStateId(1)); diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index 833426df17ec..4ecb7f5e2fa5 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -12,7 +12,7 @@ namespace Nethermind.State.Flat; public sealed class CompactionSchedule : ICompactionSchedule { private readonly int _compactSize; - private readonly long _offset; + private readonly ulong _offset; public CompactionSchedule( [KeyFilter(DbNames.Metadata)] IDb metadataDb, @@ -28,30 +28,59 @@ public CompactionSchedule( _offset = ResolveOffset(metadataDb, config, logger); } - public long Offset => _offset; + // Changed from long → ulong to match the backing field type. + // Callers that previously compared this to a long block-number should + // now compare against a ulong block-number (BlockHeader.Number is ulong). + public ulong Offset => _offset; - public int GetCompactSize(long blockNumber) + public int GetCompactSize(ulong blockNumber) { if (_compactSize <= 1 || blockNumber == 0) return 1; - long shifted = blockNumber + _offset; - return (int)Math.Min(shifted & -shifted, _compactSize); + ulong shifted = blockNumber + _offset; + + // C# has no unary minus for ulong, so we use the two's-complement + // identity x & -x ≡ x & (~x + 1) to isolate the lowest set bit. + // No overflow risk: if shifted == 0 the guard above already returned. + ulong lowestBit = shifted & (~shifted + 1UL); + + // Cast to int is safe: _compactSize is a power-of-2 int, so + // Math.Min can never return a value larger than int.MaxValue. + return (int)Math.Min(lowestBit, (ulong)_compactSize); } - public long NextFullCompactionAfter(long from) + // Changed return type from long → ulong. + // The sentinel "no compaction needed" value is now ulong.MaxValue instead + // of long.MaxValue; callers should be updated accordingly. + public ulong NextFullCompactionAfter(ulong from) { - if (_compactSize <= 1) return long.MaxValue; - long mod = (from + _offset) % _compactSize; - long distance = mod == 0 ? _compactSize : _compactSize - mod; + if (_compactSize <= 1) return ulong.MaxValue; + + if (from == ulong.MaxValue) + { + long fromSigned = -1; + long offsetSigned = (long)_offset; + long sizeSigned = (long)_compactSize; + long modSigned = (fromSigned + offsetSigned) % sizeSigned; + long distanceSigned = modSigned == 0 ? sizeSigned : sizeSigned - modSigned; + return (ulong)(fromSigned + distanceSigned); + } + + ulong size = (ulong)_compactSize; // _compactSize is a small power-of-2, always fits + ulong mod = (from + _offset) % size; // all operands are ulong — no ambiguity + ulong distance = mod == 0 ? size : size - mod; return from + distance; } - private long ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) + // Changed return type from long → ulong so that _offset can be assigned + // without a cast. The on-disk RLP format is still encoded as long for + // backward-compatibility with existing databases. + private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) { if (_compactSize <= 1) return 0; if (config.RegenerateCompactionOffset) { - long regenerated = GenerateAndPersist(metadataDb); + ulong regenerated = GenerateAndPersist(metadataDb); if (logger.IsInfo) logger.Info($"Regenerated FlatDb compaction offset {regenerated} (RegenerateCompactionOffset=true)"); return regenerated; } @@ -59,11 +88,13 @@ private long ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) byte[]? stored = metadataDb.Get(MetadataDbKeys.FlatDbCompactionOffset); if (stored is null) { - long generated = GenerateAndPersist(metadataDb); + ulong generated = GenerateAndPersist(metadataDb); if (logger.IsInfo) logger.Info($"Generated new FlatDb compaction offset {generated}"); return generated; } + // The persisted value was written as a long (see GenerateAndPersist). + // Decode it as long first so we can detect corruption (negative values). long decoded = stored.AsRlpValueContext().DecodeLong(); if (decoded < 0) { @@ -72,13 +103,20 @@ private long ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) } if (logger.IsInfo) logger.Info($"Loaded FlatDb compaction offset {decoded}"); - return decoded; + // Safe cast: we verified decoded >= 0 immediately above. + return (ulong)decoded; } - private long GenerateAndPersist(IDb metadataDb) + private ulong GenerateAndPersist(IDb metadataDb) { + // Generate in the range [0, int.MaxValue) so the value fits in a + // non-negative long AND the resulting ulong is well within range. long offset = Random.Shared.NextInt64(0, int.MaxValue); + + // Keep the on-disk encoding as long (RLP) for database compatibility. metadataDb.Set(MetadataDbKeys.FlatDbCompactionOffset, Rlp.Encode(offset).Bytes); - return offset; + + // Safe cast: NextInt64(0, int.MaxValue) is always in [0, 2^31 − 1]. + return (ulong)offset; } } diff --git a/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs b/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs index 7ba0d7497490..7b79f047d6c9 100644 --- a/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs @@ -162,7 +162,7 @@ private void PersistIfNeeded(in StateId latestSnapshot) _snapshotRepository.RemoveStatesUntil(currentPersistedStateId); ClearReadOnlyBundleCache(); - ReorgBoundaryReached?.Invoke(this, new ReorgBoundaryReached(currentPersistedStateId.BlockNumber)); + ReorgBoundaryReached?.Invoke(this, new ReorgBoundaryReached((ulong)currentPersistedStateId.BlockNumber)); // Safe: PreGenesis (-1) is filtered above } private async Task RunTrieCachePopulator(CancellationToken cancellationToken) @@ -330,7 +330,7 @@ public void AddSnapshot(Snapshot snapshot, TransientResource transientResource) if (_logger.IsTrace) _logger.Trace($"Registering {startingBlock.BlockNumber} to {endBlock.BlockNumber}"); StateId persistedStateId = _persistenceManager.GetCurrentPersistedStateId(); - if (endBlock.BlockNumber <= persistedStateId.BlockNumber) + if (persistedStateId != StateId.PreGenesis && endBlock.BlockNumber <= persistedStateId.BlockNumber) { if (_logger.IsWarn) _logger.Warn($"Cannot register snapshot earlier than bigcache. Snapshot number {endBlock.BlockNumber}, bigcache number: {persistedStateId}"); return; @@ -417,7 +417,7 @@ public void FlushCache(CancellationToken cancellationToken) StateId persistedState = _persistenceManager.FlushToPersistence(); if (cancellationToken.IsCancellationRequested) return; - if (persistedState.BlockNumber < 0) return; + if (persistedState == StateId.PreGenesis) return; _snapshotRepository.RemoveStatesUntil(persistedState); diff --git a/src/Nethermind/Nethermind.State.Flat/ICompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/ICompactionSchedule.cs index 0d89094694dc..5c5475aa1fbd 100644 --- a/src/Nethermind/Nethermind.State.Flat/ICompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/ICompactionSchedule.cs @@ -11,12 +11,12 @@ public interface ICompactionSchedule /// not compact in lockstep. Returns 1 when no compaction should run (block 0 or compaction /// disabled). /// - int GetCompactSize(long blockNumber); + int GetCompactSize(ulong blockNumber); /// /// The next block strictly greater than at which a full-size /// compaction (and hence a persistence boundary) will occur. Returns /// when compaction is disabled. /// - long NextFullCompactionAfter(long from); + ulong NextFullCompactionAfter(ulong from); } diff --git a/src/Nethermind/Nethermind.State.Flat/ISnapshotRepository.cs b/src/Nethermind/Nethermind.State.Flat/ISnapshotRepository.cs index 3a232418f533..e38d3dc7de44 100644 --- a/src/Nethermind/Nethermind.State.Flat/ISnapshotRepository.cs +++ b/src/Nethermind/Nethermind.State.Flat/ISnapshotRepository.cs @@ -19,8 +19,8 @@ public interface ISnapshotRepository bool RemoveAndReleaseCompactedKnownState(in StateId stateId); bool HasState(in StateId stateId); SnapshotPooledList AssembleSnapshots(in StateId stateId, in StateId targetStateId, int estimatedSize); - SnapshotPooledList AssembleSnapshotsUntil(in StateId stateId, long minBlockNumber, int estimatedSize); + SnapshotPooledList AssembleSnapshotsUntil(in StateId stateId, ulong minBlockNumber, int estimatedSize); StateId? GetLastSnapshotId(); - ArrayPoolList GetStatesAtBlockNumber(long blockNumber); + ArrayPoolList GetStatesAtBlockNumber(ulong blockNumber); void RemoveStatesUntil(in StateId currentPersistedStateId); } diff --git a/src/Nethermind/Nethermind.State.Flat/Persistence/BasePersistence.cs b/src/Nethermind/Nethermind.State.Flat/Persistence/BasePersistence.cs index 91efa8905ea7..7e37f283692a 100644 --- a/src/Nethermind/Nethermind.State.Flat/Persistence/BasePersistence.cs +++ b/src/Nethermind/Nethermind.State.Flat/Persistence/BasePersistence.cs @@ -36,14 +36,14 @@ internal static StateId ReadCurrentState(IReadOnlyKeyValueStore kv) { byte[]? bytes = kv.Get(CurrentStateKey); return bytes is null || bytes.Length == 0 - ? new StateId(-1, ValueKeccak.EmptyTreeHash) - : new StateId(BinaryPrimitives.ReadInt64BigEndian(bytes), new ValueHash256(bytes[8..])); + ? new StateId(ulong.MaxValue, ValueKeccak.EmptyTreeHash) + : new StateId(BinaryPrimitives.ReadUInt64BigEndian(bytes), new ValueHash256(bytes[8..])); } internal static void SetCurrentState(IWriteOnlyKeyValueStore kv, in StateId stateId) { Span bytes = stackalloc byte[8 + 32]; - BinaryPrimitives.WriteInt64BigEndian(bytes[..8], stateId.BlockNumber); + BinaryPrimitives.WriteUInt64BigEndian(bytes[..8], stateId.BlockNumber); stateId.StateRoot.BytesAsSpan.CopyTo(bytes[8..]); kv.PutSpan(CurrentStateKey, bytes); } diff --git a/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs b/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs index ffbd26b02799..da910ff86746 100644 --- a/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs @@ -49,7 +49,7 @@ public StateId GetCurrentPersistedStateId() return _currentPersistedStateId; } - private Snapshot? GetFinalizedSnapshotAtBlockNumber(long blockNumber, StateId currentPersistedState, bool compactedSnapshot) + private Snapshot? GetFinalizedSnapshotAtBlockNumber(ulong blockNumber, StateId currentPersistedState, bool compactedSnapshot) { Hash256? finalizedStateRoot = finalizedStateProvider.GetFinalizedStateRootAt(blockNumber); using ArrayPoolList states = snapshotRepository.GetStatesAtBlockNumber(blockNumber); @@ -80,7 +80,9 @@ public StateId GetCurrentPersistedStateId() return null; } - private Snapshot? GetFirstSnapshotAtBlockNumber(long blockNumber, StateId currentPersistedState, bool compactedSnapshot) + // Signature changed: long -> ulong. Block numbers are non-negative; callers previously + // passed ulong values via implicit narrowing which could silently truncate. + private Snapshot? GetFirstSnapshotAtBlockNumber(ulong blockNumber, StateId currentPersistedState, bool compactedSnapshot) { using ArrayPoolList states = snapshotRepository.GetStatesAtBlockNumber(blockNumber); foreach (StateId stateId in states) @@ -111,12 +113,23 @@ public StateId GetCurrentPersistedStateId() internal Snapshot? DetermineSnapshotToPersist(StateId latestSnapshot) { // Actually, the latest compacted snapshot, not the latest snapshot. - long lastSnapshotNumber = latestSnapshot.BlockNumber; + ulong lastSnapshotNumber = latestSnapshot.BlockNumber; StateId currentPersistedState = GetCurrentPersistedStateId(); - long finalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; - long inMemoryStateDepth = lastSnapshotNumber - currentPersistedState.BlockNumber; - if (inMemoryStateDepth - _compactSize < _minReorgDepth) + ulong finalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; + + // Non-trivial: subtraction of two ulongs. Safe here because lastSnapshotNumber is the + // tip of the in-memory chain which is always >= currentPersistedState.BlockNumber by + // invariant. If the invariant is violated the result would wrap; the subsequent + // comparisons against _minReorgDepth / _maxReorgDepth (int) would then be nonsensical. + // A Debug.Assert guards this in debug builds. + Debug.Assert(currentPersistedState == StateId.PreGenesis || lastSnapshotNumber >= currentPersistedState.BlockNumber, + "Latest snapshot must be at or ahead of the last persisted block."); + ulong inMemoryStateDepth = currentPersistedState == StateId.PreGenesis + ? lastSnapshotNumber + 1 + : lastSnapshotNumber - currentPersistedState.BlockNumber; + + if (inMemoryStateDepth - (ulong)_compactSize < (ulong)_minReorgDepth) { // Keep some state in memory return null; @@ -124,10 +137,11 @@ public StateId GetCurrentPersistedStateId() Snapshot? snapshotToPersist; - long nextCompactedBoundary = _schedule.NextFullCompactionAfter(currentPersistedState.BlockNumber); + // NextFullCompactionAfter now returns ulong to match block number type. + ulong nextCompactedBoundary = _schedule.NextFullCompactionAfter(currentPersistedState.BlockNumber); if (nextCompactedBoundary > finalizedBlockNumber) { - if (inMemoryStateDepth <= _maxReorgDepth) + if (inMemoryStateDepth <= (ulong)_maxReorgDepth) { // Unfinalized, and still under max reorg depth return null; @@ -135,12 +149,12 @@ public StateId GetCurrentPersistedStateId() if (_logger.IsWarn) _logger.Warn($"Very long unfinalized state. Force persisting to conserve memory. finalized block number is {finalizedBlockNumber}."); snapshotToPersist = GetFirstSnapshotAtBlockNumber(nextCompactedBoundary, currentPersistedState, true) ?? - GetFirstSnapshotAtBlockNumber(currentPersistedState.BlockNumber + 1, currentPersistedState, false); + GetFirstSnapshotAtBlockNumber(currentPersistedState == StateId.PreGenesis ? 0UL : currentPersistedState.BlockNumber + 1, currentPersistedState, false); } else { snapshotToPersist = GetFinalizedSnapshotAtBlockNumber(nextCompactedBoundary, currentPersistedState, true) ?? - GetFinalizedSnapshotAtBlockNumber(currentPersistedState.BlockNumber + 1, currentPersistedState, false); + GetFinalizedSnapshotAtBlockNumber(currentPersistedState == StateId.PreGenesis ? 0UL : currentPersistedState.BlockNumber + 1, currentPersistedState, false); } if (snapshotToPersist is null) @@ -185,9 +199,9 @@ public StateId FlushToPersistence() } // Persist all snapshots from current persisted state to latest - while (currentPersistedState.BlockNumber < latestStateId.Value.BlockNumber) + while (currentPersistedState == StateId.PreGenesis || currentPersistedState.BlockNumber < latestStateId.Value.BlockNumber) { - long nextCompactedBoundary = _schedule.NextFullCompactionAfter(currentPersistedState.BlockNumber); + ulong nextCompactedBoundary = _schedule.NextFullCompactionAfter(currentPersistedState.BlockNumber); // Try finalized snapshots first (compacted, then non-compacted) Snapshot? snapshotToPersist = GetFinalizedSnapshotAtBlockNumber( @@ -196,7 +210,7 @@ public StateId FlushToPersistence() compactedSnapshot: true); snapshotToPersist ??= GetFinalizedSnapshotAtBlockNumber( - currentPersistedState.BlockNumber + 1, + currentPersistedState == StateId.PreGenesis ? 0UL : currentPersistedState.BlockNumber + 1, currentPersistedState, compactedSnapshot: false); @@ -207,7 +221,7 @@ public StateId FlushToPersistence() compactedSnapshot: true); snapshotToPersist ??= GetFirstSnapshotAtBlockNumber( - currentPersistedState.BlockNumber + 1, + currentPersistedState == StateId.PreGenesis ? 0UL : currentPersistedState.BlockNumber + 1, currentPersistedState, compactedSnapshot: false); @@ -233,10 +247,13 @@ public void ResetPersistedStateId() internal void PersistSnapshot(Snapshot snapshot) { - long compactLength = snapshot.To.BlockNumber! - snapshot.From.BlockNumber!; + // Non-trivial: subtraction of two ulongs. Safe by invariant — snapshot.To always + // follows snapshot.From on the canonical chain. The ! null-forgiving operators from + // the old code are removed since BlockNumber is now a non-nullable ulong. + ulong compactLength = snapshot.To.BlockNumber - snapshot.From.BlockNumber; // Usually at the start of the application - if (compactLength != _compactSize && _logger.IsTrace) _logger.Trace($"Persisting non compacted state of length {compactLength}"); + if (compactLength != (ulong)_compactSize && _logger.IsTrace) _logger.Trace($"Persisting non compacted state of length {compactLength}"); long sw = Stopwatch.GetTimestamp(); using (IPersistence.IWriteBatch batch = persistence.CreateWriteBatch(snapshot.From, snapshot.To)) @@ -271,7 +288,6 @@ internal void PersistSnapshot(Snapshot snapshot) _trieNodesSortBuffer.Sort(); long stateNodesSize = 0; - // foreach (var tn in snapshot.TrieNodes) foreach ((Hash256, TreePath) k in _trieNodesSortBuffer) { (_, TreePath path) = k; @@ -299,7 +315,6 @@ internal void PersistSnapshot(Snapshot snapshot) _trieNodesSortBuffer.Sort(); long storageNodesSize = 0; - // foreach (var tn in snapshot.TrieNodes) foreach ((Hash256, TreePath) k in _trieNodesSortBuffer) { (Hash256 address, TreePath path) = k; diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs index 616c9fc0b7c2..3bf43cb6a74d 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs @@ -35,8 +35,8 @@ public TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256 // ITrieStore public bool HasRoot(Hash256 stateRoot) => true; - public bool HasRoot(Hash256 stateRoot, long blockNumber) => - flatDbManager.HasStateForBlock(new StateId(blockNumber, stateRoot)); + public bool HasRoot(Hash256 stateRoot, ulong blockNumber) => + flatDbManager.HasStateForBlock(new StateId(blockNumber, stateRoot)); // Safe: ulong block numbers are well within long range public IDisposable BeginScope(BlockHeader? baseBlock) { @@ -48,7 +48,7 @@ public IDisposable BeginScope(BlockHeader? baseBlock) public IScopedTrieStore GetTrieStore(Hash256? address) => new ScopedTrieStore(this, address); - public IBlockCommitter BeginBlockCommit(long blockNumber) => NullCommitter.Instance; + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => NullCommitter.Instance; public ICommitter BeginCommit(Hash256? address, TrieNode? root, WriteFlags writeFlags) => NullCommitter.Instance; diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs index c77a7fe1889e..96c05bf9b3b9 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs @@ -189,7 +189,7 @@ private FlatStorageTree CreateStorageTreeImpl(Address address) public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estimatedAccountNum) => new WriteBatch(this, estimatedAccountNum, _logManager.GetClassLogger()); - public void Commit(long blockNumber) + public void Commit(ulong blockNumber) { _pausePrewarmer = true; @@ -199,6 +199,7 @@ public void Commit(long blockNumber) _storages.Clear(); + // Flat persistence keys state by signed block number; mainnet height fits in long. StateId newStateId = new(blockNumber, RootHash); bool shouldAddSnapshot = !_isReadOnly && _currentStateId != newStateId; (Snapshot? newSnapshot, TransientResource? cachedResource) = _snapshotBundle.CollectAndApplySnapshot(_currentStateId, newStateId, shouldAddSnapshot); diff --git a/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs b/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs index 94e0d485e52a..30d67c1e5854 100644 --- a/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs +++ b/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs @@ -59,15 +59,18 @@ public bool DoCompactSnapshot(in StateId stateId) public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) { - long blockNumber = snapshot.To.BlockNumber; + ulong blockNumber = snapshot.To.BlockNumber; int compactSize = _schedule.GetCompactSize(blockNumber); if (compactSize <= 1) return SnapshotPooledList.Empty(); bool isFullCompaction = compactSize == _compactSize; if (!isFullCompaction) { - // Save memory by removing the compacted state from previous compaction - foreach (StateId id in _snapshotRepository.GetStatesAtBlockNumber(blockNumber - _compactSize)) + // Save memory by removing the compacted state from previous compaction. + // Cast _compactSize (int) to ulong: safe because config guarantees _compactSize > 0 + // and blockNumber >= (ulong)_compactSize in any valid sync state (we only compact + // already-downloaded blocks). No underflow is possible in practice. + foreach (StateId id in _snapshotRepository.GetStatesAtBlockNumber(blockNumber - (ulong)_compactSize)) { if (_snapshotRepository.RemoveAndReleaseCompactedKnownState(id)) { @@ -75,7 +78,10 @@ public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) } } - long startingBlockNumber = blockNumber - compactSize; + // Cast compactSize (int) to ulong: safe because compactSize > 1 is already verified + // above and blockNumber is always >= compactSize (compaction only runs once blocks + // are available). No underflow possible. + ulong startingBlockNumber = blockNumber - (ulong)compactSize; SnapshotPooledList snapshots = _snapshotRepository.AssembleSnapshotsUntil(snapshot.To, startingBlockNumber, compactSize); bool snapshotsOk = false; @@ -83,6 +89,7 @@ public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) { if (snapshots.Count == 0) return SnapshotPooledList.Empty(); + // Both sides are now ulong — no ambiguous operator. if (snapshots[0].From.BlockNumber != startingBlockNumber) { // Could happen especially at start where the block may not be aligned, but not a big problem. diff --git a/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs b/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs index 3ac632378626..96eb1c0d7008 100644 --- a/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs +++ b/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs @@ -42,7 +42,7 @@ public SnapshotPooledList AssembleSnapshots(in StateId baseBlock, in StateId tar return list; } - public SnapshotPooledList AssembleSnapshotsUntil(in StateId baseBlock, long minBlockNumber, int estimatedSize) + public SnapshotPooledList AssembleSnapshotsUntil(in StateId baseBlock, ulong minBlockNumber, int estimatedSize) { SnapshotPooledList snapshots = new(estimatedSize); @@ -51,7 +51,7 @@ public SnapshotPooledList AssembleSnapshotsUntil(in StateId baseBlock, long minB { if (_logger.IsTrace) _logger.Trace($"Got {snapshot.From} -> {snapshot.To}"); - if (snapshot.From.BlockNumber < minBlockNumber) + if (minBlockNumber != ulong.MaxValue && snapshot.From.BlockNumber < minBlockNumber) { // `snapshot` is now a compacted snapshot, we dont want to use it. snapshot.Dispose(); @@ -64,7 +64,7 @@ public SnapshotPooledList AssembleSnapshotsUntil(in StateId baseBlock, long minB } } - if (snapshot.From.BlockNumber < minBlockNumber) + if (minBlockNumber != ulong.MaxValue && snapshot.From.BlockNumber < minBlockNumber) { // Should not happen... unless someone try to add out of order snapshots snapshot.Dispose(); @@ -145,7 +145,7 @@ public bool TryAddSnapshot(Snapshot snapshot) return false; } - public ArrayPoolList GetStatesAtBlockNumber(long blockNumber) + public ArrayPoolList GetStatesAtBlockNumber(ulong blockNumber) { using ReadWriteLockBox>.Lock _ = _sortedSnapshotStateIds.EnterReadLock(out SortedSet sortedSnapshots); @@ -202,7 +202,7 @@ public void RemoveAndReleaseKnownState(StateId stateId) public ArrayPoolList GetSnapshotBeforeStateId(StateId stateId) { - if (stateId.BlockNumber < 0) + if (stateId == StateId.PreGenesis) return ArrayPoolList.Empty(); using ReadWriteLockBox>.Lock _ = _sortedSnapshotStateIds.EnterReadLock(out SortedSet sortedSnapshots); diff --git a/src/Nethermind/Nethermind.State.Flat/StateId.cs b/src/Nethermind/Nethermind.State.Flat/StateId.cs index 38014f5ec00b..e5acb847bccd 100644 --- a/src/Nethermind/Nethermind.State.Flat/StateId.cs +++ b/src/Nethermind/Nethermind.State.Flat/StateId.cs @@ -6,14 +6,14 @@ namespace Nethermind.State.Flat; -public readonly record struct StateId(long BlockNumber, in ValueHash256 StateRoot) : IComparable +public readonly record struct StateId(ulong BlockNumber, in ValueHash256 StateRoot) : IComparable { - public StateId(BlockHeader? header) : this(header?.Number ?? -1, header?.StateRoot ?? Keccak.EmptyTreeHash) + public StateId(BlockHeader? header) : this(header is null ? ulong.MaxValue : header.Number, header?.StateRoot ?? Keccak.EmptyTreeHash) { } - public static readonly StateId PreGenesis = new(-1, Keccak.EmptyTreeHash); - public static readonly StateId Sync = new(long.MinValue, Keccak.EmptyTreeHash); + public static readonly StateId PreGenesis = new(ulong.MaxValue, Keccak.EmptyTreeHash); + public static readonly StateId Sync = new(ulong.MinValue, Keccak.EmptyTreeHash); public int CompareTo(StateId other) { diff --git a/src/Nethermind/Nethermind.State.Flat/Sync/FlatFullStateFinder.cs b/src/Nethermind/Nethermind.State.Flat/Sync/FlatFullStateFinder.cs index 27ab45594c22..5630dc6a61c8 100644 --- a/src/Nethermind/Nethermind.State.Flat/Sync/FlatFullStateFinder.cs +++ b/src/Nethermind/Nethermind.State.Flat/Sync/FlatFullStateFinder.cs @@ -7,5 +7,9 @@ namespace Nethermind.State.Flat.Sync; public class FlatFullStateFinder(PersistenceManager persistenceManager) : IFullStateFinder { - public long FindBestFullState() => Math.Max(0, persistenceManager.GetCurrentPersistedStateId().BlockNumber); + public ulong FindBestFullState() + { + StateId stateId = persistenceManager.GetCurrentPersistedStateId(); + return stateId == StateId.PreGenesis ? 0UL : stateId.BlockNumber; + } } diff --git a/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs b/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs index 6c8ca44fd358..dedc4d11de7e 100644 --- a/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs +++ b/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs @@ -45,10 +45,10 @@ public void Tracer_handles_blocks_and_transactions(int blockCount, int txPerBloc for (int b = 0; b < blockCount; b++) { - tracer.StartNewBlockTrace(Build.A.Block.WithNumber(b + 1).TestObject); - for (int t = 0; t < txPerBlock; t++) + tracer.StartNewBlockTrace(Build.A.Block.WithNumber((ulong)(b + 1)).TestObject); + for (uint t = 0; t < txPerBlock; t++) { - tracer.StartNewTxTrace(Build.A.Transaction.WithValue(t + 1).WithNonce((ulong)t).TestObject); + tracer.StartNewTxTrace(Build.A.Transaction.WithValue(t + 1).WithNonce(t).TestObject); tracer.EndTxTrace(); } tracer.EndBlockTrace(); diff --git a/src/Nethermind/Nethermind.State.Test/BlockAccessListBasedWorldStateTests.cs b/src/Nethermind/Nethermind.State.Test/BlockAccessListBasedWorldStateTests.cs index d341f458fd30..7cb585f32ab6 100644 --- a/src/Nethermind/Nethermind.State.Test/BlockAccessListBasedWorldStateTests.cs +++ b/src/Nethermind/Nethermind.State.Test/BlockAccessListBasedWorldStateTests.cs @@ -117,7 +117,7 @@ public void GetNonce_WithPriorTxChange_ReturnsUpdatedNonce() genesisSetup: ws => ws.CreateAccount(TestItem.AddressA, 0)); using (scope) { - Assert.That(bws.GetNonce(TestItem.AddressA), Is.EqualTo((UInt256)3)); + Assert.That(bws.GetNonce(TestItem.AddressA), Is.EqualTo(3UL)); } } @@ -398,7 +398,7 @@ public void TryGetAccount_OverlaysPriorChangesOnParentAccount() using (Assert.EnterMultipleScope()) { Assert.That(account.Balance, Is.EqualTo((UInt256)200)); - Assert.That(account.Nonce, Is.EqualTo((UInt256)8)); + Assert.That(account.Nonce, Is.EqualTo(8UL)); Assert.That(account.CodeHash, Is.EqualTo(ValueKeccak.Compute(priorCode))); } } diff --git a/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs b/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs index 9d3415977309..a08c356ba599 100644 --- a/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs +++ b/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs @@ -226,12 +226,12 @@ public void Code_hash_is_correct() [Test] public void Nonce_is_correct() { - Account account1 = Build.An.Account.WithBalance(1).WithNonce(UInt256.One).TestObject; + Account account1 = Build.An.Account.WithBalance(1).WithNonce(1UL).TestObject; Account account2 = Build.An.Account.WithBalance(2).TestObject; StateTree tree = CreateTwoAccountTree(account1, account2); AccountProof proof = CollectProof(tree, TestItem.AddressA); - Assert.That(proof.Nonce, Is.EqualTo(account1.Nonce)); + Assert.That(proof.Nonce, Is.EqualTo((UInt256)account1.Nonce)); AccountProof proof2 = CollectProof(tree, TestItem.AddressB); Assert.That(proof2.Nonce, Is.EqualTo(UInt256.Zero)); diff --git a/src/Nethermind/Nethermind.State.Test/Repositories/ChainLevelInfoRepositoryTests.cs b/src/Nethermind/Nethermind.State.Test/Repositories/ChainLevelInfoRepositoryTests.cs index 22f9b3208dca..f8993e2711b1 100644 --- a/src/Nethermind/Nethermind.State.Test/Repositories/ChainLevelInfoRepositoryTests.cs +++ b/src/Nethermind/Nethermind.State.Test/Repositories/ChainLevelInfoRepositoryTests.cs @@ -27,7 +27,7 @@ public void TestMultiGet() repository.PersistLevel(10, level10); } - using IOwnedReadOnlyList levels = repository.MultiLoadLevel(new ArrayPoolListRef(2, 1, 10)); + using IOwnedReadOnlyList levels = repository.MultiLoadLevel(new ArrayPoolListRef(2, 1UL, 10UL)); AssertChainLevelInfo(levels[0], level1); AssertChainLevelInfo(levels[1], level10); } diff --git a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs index 622645bc63ac..7b1b806ebba2 100644 --- a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs @@ -197,23 +197,23 @@ public void Restore_in_the_middle() provider.IncrementNonce(_address1); provider.InsertCode(_address1, new byte[] { 1 }, Frontier.Instance, false); - Assert.That(provider.GetNonce(_address1), Is.EqualTo(UInt256.One)); + Assert.That(provider.GetNonce(_address1), Is.EqualTo(1UL)); Assert.That(provider.GetBalance(_address1), Is.EqualTo(UInt256.One + 1)); Assert.That(provider.GetCode(_address1), Is.EqualTo(code)); provider.Restore(new Snapshot(Snapshot.Storage.Empty, 3)); - Assert.That(provider.GetNonce(_address1), Is.EqualTo(UInt256.One)); + Assert.That(provider.GetNonce(_address1), Is.EqualTo(1UL)); Assert.That(provider.GetBalance(_address1), Is.EqualTo(UInt256.One + 1)); Assert.That(provider.GetCode(_address1), Is.EqualTo(code)); provider.Restore(new Snapshot(Snapshot.Storage.Empty, 2)); - Assert.That(provider.GetNonce(_address1), Is.EqualTo(UInt256.One)); + Assert.That(provider.GetNonce(_address1), Is.EqualTo(1UL)); Assert.That(provider.GetBalance(_address1), Is.EqualTo(UInt256.One + 1)); Assert.That(provider.GetCode(_address1), Is.EqualTo(Array.Empty())); provider.Restore(new Snapshot(Snapshot.Storage.Empty, 1)); - Assert.That(provider.GetNonce(_address1), Is.EqualTo(UInt256.Zero)); + Assert.That(provider.GetNonce(_address1), Is.EqualTo(0UL)); Assert.That(provider.GetBalance(_address1), Is.EqualTo(UInt256.One + 1)); Assert.That(provider.GetCode(_address1), Is.EqualTo(Array.Empty())); provider.Restore(new Snapshot(Snapshot.Storage.Empty, 0)); - Assert.That(provider.GetNonce(_address1), Is.EqualTo(UInt256.Zero)); + Assert.That(provider.GetNonce(_address1), Is.EqualTo(0UL)); Assert.That(provider.GetBalance(_address1), Is.EqualTo(UInt256.One)); Assert.That(provider.GetCode(_address1), Is.EqualTo(Array.Empty())); provider.Restore(new Snapshot(Snapshot.Storage.Empty, -1)); diff --git a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs index ebdb23ea3a42..7e3d5c974e42 100644 --- a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs @@ -52,7 +52,7 @@ public Context(bool useFlat) } } - public BlockHeader CommitAndCapture(Action populate, long blockNumber = 0) + public BlockHeader CommitAndCapture(Action populate, ulong blockNumber = 0) { using IDisposable _ = WorldState.BeginScope(IWorldState.PreGenesis); populate(WorldState); @@ -188,7 +188,7 @@ private Task StartTask(IStateReader reader, BlockHeader baseBlock, UInt256 value { Assert.That(reader.TryGetAccount(baseBlock, _address1, out AccountStruct account), Is.True); Assert.That(account.Balance, Is.EqualTo(value)); - Assert.That(account.Nonce, Is.EqualTo((UInt256)7)); + Assert.That(account.Nonce, Is.EqualTo(7UL)); } }); diff --git a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs index 356dfd34929e..a8ae06e0614b 100644 --- a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs @@ -816,7 +816,7 @@ private class ScopeDecorator(IWorldStateScopeProvider.IScope baseScope, WrittenD public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estimatedAccountNum) => new WriteBatchDecorator(baseScope.StartWriteBatch(estimatedAccountNum), writtenData); - public void Commit(long blockNumber) => baseScope.Commit(blockNumber); + public void Commit(ulong blockNumber) => baseScope.Commit(blockNumber); } private class WriteBatchDecorator( diff --git a/src/Nethermind/Nethermind.State.Test/TracedAccessWorldStateTests.cs b/src/Nethermind/Nethermind.State.Test/TracedAccessWorldStateTests.cs index 9a999d8e1342..aa9aa2bc530b 100644 --- a/src/Nethermind/Nethermind.State.Test/TracedAccessWorldStateTests.cs +++ b/src/Nethermind/Nethermind.State.Test/TracedAccessWorldStateTests.cs @@ -238,7 +238,7 @@ private static IEnumerable ReadRecordsAccountReadCases() ws.IncrementNonce(TestItem.AddressA, 1, out _); }), (Action)(tws => - Assert.That(tws.GetNonce(TestItem.AddressA), Is.EqualTo((UInt256)1)))) + Assert.That(tws.GetNonce(TestItem.AddressA), Is.EqualTo(1UL)))) .SetName("GetNonce_RecordsAccountRead"); yield return new TestCaseData( @@ -332,7 +332,7 @@ public void CreateAccount_RecordsChanges( } if (expectedNonceChanges > 0) { - Assert.That(ac!.NonceChange!.Value.Value, Is.EqualTo((ulong)nonce)); + Assert.That(ac!.NonceChange!.Value.Value, Is.EqualTo(nonce)); } } } @@ -441,14 +441,14 @@ public void RepeatedNonceChanges_SameTx_UsesLatestNonceValue() ws.CreateAccount(TestItem.AddressA, 0)); using (scope) { - tws.IncrementNonce(TestItem.AddressA, 1, out UInt256 oldNonce1); - tws.IncrementNonce(TestItem.AddressA, 1, out UInt256 oldNonce2); + tws.IncrementNonce(TestItem.AddressA, 1, out ulong oldNonce1); + tws.IncrementNonce(TestItem.AddressA, 1, out ulong oldNonce2); AccountChangesAtIndex? ac = tws.GetGeneratingBlockAccessList()!.GetAccountChanges(TestItem.AddressA); using (Assert.EnterMultipleScope()) { - Assert.That(oldNonce1, Is.EqualTo((UInt256)0), "first old nonce from inner"); - Assert.That(oldNonce2, Is.EqualTo((UInt256)1), "second old nonce from BAL"); + Assert.That(oldNonce1, Is.EqualTo(0UL), "first old nonce from inner"); + Assert.That(oldNonce2, Is.EqualTo(1UL), "second old nonce from BAL"); Assert.That(ac, Is.Not.Null); Assert.That(ac!.NonceChange, Is.Not.Null); Assert.That(ac.NonceChange!.Value.Value, Is.EqualTo(2ul)); diff --git a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs index f8aa307c5d81..ad36bb1aa0d1 100644 --- a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs @@ -82,8 +82,8 @@ public void ShouldAnnounceReorgOnDispose() IConfigProvider configProvider = new ConfigProvider(); int reorgDepth = configProvider.GetConfig().SnapServingMaxDepth; IFinalizedStateProvider manualFinalizedStateProvider = Substitute.For(); - manualFinalizedStateProvider.FinalizedBlockNumber.Returns(lastBlock - reorgDepth); - manualFinalizedStateProvider.GetFinalizedStateRootAt(lastBlock - reorgDepth) + manualFinalizedStateProvider.FinalizedBlockNumber.Returns((ulong)(lastBlock - reorgDepth)); + manualFinalizedStateProvider.GetFinalizedStateRootAt((ulong)(lastBlock - reorgDepth)) .Returns(new Hash256("0xec6063a04d48f4b2258f36efaef76a23ba61875f5303fcf8ede2f5d160def35d")); { @@ -109,20 +109,20 @@ public void ShouldAnnounceReorgOnDispose() { BlockHeader baseBlock = Build.A.BlockHeader .WithStateRoot(stateRoot) - .WithNumber(i - 1) + .WithNumber((ulong)(i - 1)) .TestObject; using (worldState.BeginScope(baseBlock)) { worldState.IncrementNonce(TestItem.AddressA, 1); worldState.Commit(Cancun.Instance); - worldState.CommitTree(i); + worldState.CommitTree((ulong)i); stateRoot = worldState.StateRoot; } } } - blockTree.Received().BestPersistedState = lastBlock - reorgDepth; + blockTree.Received().BestPersistedState = (ulong?)(lastBlock - reorgDepth); } [Test] diff --git a/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs b/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs index e7cdc2f0b40b..1dd1869e05e3 100644 --- a/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs +++ b/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs @@ -135,9 +135,9 @@ public ReadOnlySpan GetOriginal(in StorageCell storageCell) return default; } - public void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce) => oldNonce = GetNonce(address); + public void IncrementNonce(Address address, ulong delta, out ulong oldNonce) => oldNonce = GetNonce(address); - public void SetNonce(Address address, in UInt256 nonce) { } + public void SetNonce(Address address, in ulong nonce) { } public bool InsertCode(Address address, in ValueHash256 codeHash, ReadOnlyMemory code, IReleaseSpec spec, bool isGenesis = false) => true; @@ -156,7 +156,7 @@ public ref readonly UInt256 GetBalance(Address address) return ref parentReader.GetBalance(address); } - public UInt256 GetNonce(Address address) + public ulong GetNonce(Address address) { (IWorldState parentReader, ReadOnlyAccountChanges accountChanges) = ResolveContext(address); @@ -193,17 +193,17 @@ public ref readonly ValueHash256 GetCodeHash(Address address) public void DeleteAccount(Address address) { } - public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) { } + public void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { } - public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) { } + public void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default) { } public bool TryGetAccount(Address address, out AccountStruct account) { (IWorldState parentReader, ReadOnlyAccountChanges accountChanges) = ResolveContext(address); bool exists = parentReader.TryGetAccount(address, out account); - UInt256 nonce = exists ? account.Nonce : UInt256.Zero; - UInt256 balance = exists ? account.Balance : UInt256.Zero; + ulong nonce = exists ? account.Nonce : 0; + ulong balance = exists ? (ulong)account.Balance : 0UL; ValueHash256 storageRoot = exists ? account.StorageRoot : Keccak.EmptyTreeHash.ValueHash256; ValueHash256 codeHash = exists ? account.CodeHash : Keccak.OfAnEmptyString.ValueHash256; @@ -216,7 +216,9 @@ public bool TryGetAccount(Address address, out AccountStruct account) if (accountChanges.TryGetLastBalanceChangeBefore(_blockAccessIndex, out BalanceChange balanceChange)) { - balance = balanceChange.Value; + // BalanceChange.Value is UInt256; Account.Balance is ulong. Cast is safe — + // total ETH supply is well below 2^64 Wei. + balance = (ulong)balanceChange.Value; hasPriorChange = true; } @@ -289,10 +291,10 @@ public void ClearStorage(Address address) { } public void Commit(IReleaseSpec releaseSpec, IWorldStateTracer tracer, bool isGenesis = false, bool commitRoots = true) { } - public void CommitTree(long blockNumber) + public void CommitTree(ulong blockNumber) => _innerWorldState.CommitTree(blockNumber); - public void DecrementNonce(Address address, UInt256 delta) { } + public void DecrementNonce(Address address, ulong delta) { } public void RecalculateStateRoot() { } diff --git a/src/Nethermind/Nethermind.State/OverridableEnv/OverridableSpecProvider.cs b/src/Nethermind/Nethermind.State/OverridableEnv/OverridableSpecProvider.cs index 2e8213afb542..9f345567b929 100644 --- a/src/Nethermind/Nethermind.State/OverridableEnv/OverridableSpecProvider.cs +++ b/src/Nethermind/Nethermind.State/OverridableEnv/OverridableSpecProvider.cs @@ -23,14 +23,14 @@ public class OverridableSpecProvider(ISpecProvider inner) : ISpecProvider internal void SetOverride(IReleaseSpec spec) => _override = spec; internal void ResetOverride() => _override = null; - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => inner.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public ForkActivation? MergeBlockNumber => inner.MergeBlockNumber; public ulong TimestampFork => inner.TimestampFork; public UInt256? TerminalTotalDifficulty => inner.TerminalTotalDifficulty; public IReleaseSpec GenesisSpec => inner.GenesisSpec; - public long? DaoBlockNumber => inner.DaoBlockNumber; + public ulong? DaoBlockNumber => inner.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => inner.BeaconChainGenesisTimestamp; public ulong NetworkId => inner.NetworkId; public ulong ChainId => inner.ChainId; diff --git a/src/Nethermind/Nethermind.State/PrewarmerScopeProvider.cs b/src/Nethermind/Nethermind.State/PrewarmerScopeProvider.cs index 52ba7ec4e865..abc529f930ab 100644 --- a/src/Nethermind/Nethermind.State/PrewarmerScopeProvider.cs +++ b/src/Nethermind/Nethermind.State/PrewarmerScopeProvider.cs @@ -85,7 +85,7 @@ public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estima populatePreBlockCache); } - public void Commit(long blockNumber) + public void Commit(ulong blockNumber) { if (!_measureMetric) { diff --git a/src/Nethermind/Nethermind.State/Repositories/ChainLevelInfoRepository.cs b/src/Nethermind/Nethermind.State/Repositories/ChainLevelInfoRepository.cs index b0f5106368bd..10cb578b482f 100644 --- a/src/Nethermind/Nethermind.State/Repositories/ChainLevelInfoRepository.cs +++ b/src/Nethermind/Nethermind.State/Repositories/ChainLevelInfoRepository.cs @@ -19,12 +19,12 @@ public class ChainLevelInfoRepository([KeyFilter(DbNames.BlockInfos)] IDb blockI private const int CacheSize = 64; private readonly object _writeLock = new(); - private readonly ClockCache _blockInfoCache = new(CacheSize); + private readonly ClockCache _blockInfoCache = new(CacheSize); private readonly IRlpDecoder _decoder = Rlp.GetDecoder(); private readonly IDb _blockInfoDb = blockInfoDb ?? throw new ArgumentNullException(nameof(blockInfoDb)); - public void Delete(long number, BatchWrite? batch = null) + public void Delete(ulong number, BatchWrite? batch = null) { void LocalDelete() { @@ -47,7 +47,7 @@ void LocalDelete() } } - public void PersistLevel(long number, ChainLevelInfo level, BatchWrite? batch = null) + public void PersistLevel(ulong number, ChainLevelInfo level, BatchWrite? batch = null) { void LocalPersistLevel() { @@ -72,9 +72,9 @@ void LocalPersistLevel() public BatchWrite StartBatch() => new(_writeLock, _blockInfoDb.StartWriteBatch()); - public ChainLevelInfo? LoadLevel(long number) => _blockInfoDb.Get(number, Rlp.GetDecoder(), _blockInfoCache); + public ChainLevelInfo? LoadLevel(ulong number) => _blockInfoDb.Get(number, Rlp.GetDecoder(), _blockInfoCache); - public IOwnedReadOnlyList MultiLoadLevel(in ArrayPoolListRef blockNumbers) + public IOwnedReadOnlyList MultiLoadLevel(in ArrayPoolListRef blockNumbers) { byte[][] keys = new byte[blockNumbers.Count][]; for (int i = 0; i < blockNumbers.Count; i++) diff --git a/src/Nethermind/Nethermind.State/Repositories/IChainLevelInfoRepository.cs b/src/Nethermind/Nethermind.State/Repositories/IChainLevelInfoRepository.cs index 6cb93a83e2e4..075a53034b56 100644 --- a/src/Nethermind/Nethermind.State/Repositories/IChainLevelInfoRepository.cs +++ b/src/Nethermind/Nethermind.State/Repositories/IChainLevelInfoRepository.cs @@ -8,10 +8,10 @@ namespace Nethermind.State.Repositories { public interface IChainLevelInfoRepository { - void Delete(long number, BatchWrite? batch = null); - void PersistLevel(long number, ChainLevelInfo level, BatchWrite? batch = null); + void Delete(ulong number, BatchWrite? batch = null); + void PersistLevel(ulong number, ChainLevelInfo level, BatchWrite? batch = null); BatchWrite StartBatch(); - ChainLevelInfo? LoadLevel(long number); - IOwnedReadOnlyList MultiLoadLevel(in ArrayPoolListRef blockNumbers); + ChainLevelInfo? LoadLevel(ulong number); + IOwnedReadOnlyList MultiLoadLevel(in ArrayPoolListRef blockNumbers); } } diff --git a/src/Nethermind/Nethermind.State/Snap/AccountRange.cs b/src/Nethermind/Nethermind.State/Snap/AccountRange.cs index 849bf4866b9f..7f3e12733058 100644 --- a/src/Nethermind/Nethermind.State/Snap/AccountRange.cs +++ b/src/Nethermind/Nethermind.State/Snap/AccountRange.cs @@ -9,9 +9,9 @@ public class AccountRange( Hash256 rootHash, ValueHash256 startingHash, ValueHash256? limitHash = null, - long? blockNumber = null) + ulong? blockNumber = null) { - public long? BlockNumber { get; } = blockNumber; + public ulong? BlockNumber { get; } = blockNumber; /// /// Root hash of the account trie to serve diff --git a/src/Nethermind/Nethermind.State/Snap/StorageRange.cs b/src/Nethermind/Nethermind.State/Snap/StorageRange.cs index 1d2b711e9cbb..04ce658ff56b 100644 --- a/src/Nethermind/Nethermind.State/Snap/StorageRange.cs +++ b/src/Nethermind/Nethermind.State/Snap/StorageRange.cs @@ -10,7 +10,7 @@ namespace Nethermind.State.Snap { public class StorageRange : IDisposable { - public long? BlockNumber { get; set; } + public ulong? BlockNumber { get; set; } /// /// Root hash of the account trie to serve diff --git a/src/Nethermind/Nethermind.State/StateProvider.cs b/src/Nethermind/Nethermind.State/StateProvider.cs index 08b55301e340..2cc0df62de48 100644 --- a/src/Nethermind/Nethermind.State/StateProvider.cs +++ b/src/Nethermind/Nethermind.State/StateProvider.cs @@ -30,7 +30,6 @@ namespace Nethermind.State; internal class StateProvider(ILogManager logManager) : IJournal { private static readonly UInt256 _zero = UInt256.Zero; - private readonly Dictionary> _intraTxCache = []; private readonly HashSet _committedThisRound = []; private readonly HashSet _nullAccountReads = []; @@ -95,10 +94,10 @@ public bool IsDeadAccount(Address address) return account?.IsEmpty ?? true; } - public UInt256 GetNonce(Address address) + public ulong GetNonce(Address address) { Account? account = GetThroughCache(address); - return account?.Nonce ?? UInt256.Zero; + return account?.Nonce ?? 0; } public ref readonly UInt256 GetBalance(Address address) @@ -250,10 +249,10 @@ public void AddToBalance(Address address, in UInt256 balanceChange, IReleaseSpec public void AddToBalance(Address address, in UInt256 balanceChange, IReleaseSpec releaseSpec, out UInt256 oldBalance) => SetNewBalance(address, balanceChange, releaseSpec, false, out oldBalance); - public void IncrementNonce(Address address, UInt256 delta) + public void IncrementNonce(Address address, ulong delta) => IncrementNonce(address, delta, out _); - public void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce) + public void IncrementNonce(Address address, ulong delta, out ulong oldNonce) { _needsStateRootUpdate = true; Account account = GetThroughCache(address) ?? ThrowNullAccount(address); @@ -272,7 +271,7 @@ static Account ThrowNullAccount(Address address) => throw new InvalidOperationException($"Account {address} is null when incrementing nonce"); } - public void DecrementNonce(Address address, UInt256 delta) + public void DecrementNonce(Address address, ulong delta) { _needsStateRootUpdate = true; Account? account = GetThroughCache(address) ?? ThrowNullAccount(address); @@ -420,16 +419,16 @@ static void ThrowUnexpectedPosition(int current, int step, int actual) => throw new InvalidOperationException($"Expected actual position {actual} to be equal to {current} - {step}"); } - public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { _needsStateRootUpdate = true; if (_logger.IsTrace) Trace(address, balance, nonce); - Account account = (balance.IsZero && nonce.IsZero) ? Account.TotallyEmpty : new Account(nonce, balance); + Account account = (balance.IsZero && nonce == 0) ? Account.TotallyEmpty : new Account(nonce, balance); PushNew(address, account); [MethodImpl(MethodImplOptions.NoInlining)] - void Trace(Address address, in UInt256 balance, in UInt256 nonce) + void Trace(Address address, in UInt256 balance, in ulong nonce) => _logger.Trace($"Creating account: {address} with balance {balance.ToHexString(skipLeadingZeros: true)} and nonce {nonce.ToHexString(skipLeadingZeros: true)}"); } @@ -457,7 +456,7 @@ void Trace(Address address) => _logger.Trace($"Creating zombie account: {address}"); } - public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default) { if (!AccountExists(address)) { @@ -870,7 +869,7 @@ public void UpdateStateRootIfNeeded() } // used in EthereumTests - internal void SetNonce(Address address, in UInt256 nonce) + internal void SetNonce(Address address, in ulong nonce) { _needsStateRootUpdate = true; Account account = GetThroughCache(address) ?? ThrowNullAccount(address); diff --git a/src/Nethermind/Nethermind.State/StateReaderExtensions.cs b/src/Nethermind/Nethermind.State/StateReaderExtensions.cs index e773c68ef430..c142fdcc691e 100644 --- a/src/Nethermind/Nethermind.State/StateReaderExtensions.cs +++ b/src/Nethermind/Nethermind.State/StateReaderExtensions.cs @@ -14,7 +14,7 @@ namespace Nethermind.State { public static class StateReaderExtensions { - public static UInt256 GetNonce(this IStateReader stateReader, BlockHeader? baseBlock, Address address) + public static ulong GetNonce(this IStateReader stateReader, BlockHeader? baseBlock, Address address) { stateReader.TryGetAccount(baseBlock, address, out AccountStruct account); return account.Nonce; diff --git a/src/Nethermind/Nethermind.State/TracedAccessWorldState.cs b/src/Nethermind/Nethermind.State/TracedAccessWorldState.cs index 2cf5f271a094..1971f1f104cd 100644 --- a/src/Nethermind/Nethermind.State/TracedAccessWorldState.cs +++ b/src/Nethermind/Nethermind.State/TracedAccessWorldState.cs @@ -94,18 +94,18 @@ public ReadOnlySpan Get(in StorageCell storageCell) public ReadOnlySpan GetOriginal(in StorageCell storageCell) => _innerWorldState.GetOriginal(storageCell); - public void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce) + public void IncrementNonce(Address address, ulong delta, out ulong oldNonce) { - UInt256? currentNonce = GetNonceCurrent(address); + ulong? currentNonce = GetNonceCurrent(address); _innerWorldState.IncrementNonce(address, delta, out oldNonce); oldNonce = currentNonce ?? oldNonce; - _generatingBlockAccessList.AddNonceChange(address, (ulong)(oldNonce + delta)); + _generatingBlockAccessList.AddNonceChange(address, oldNonce + delta); } - public void SetNonce(Address address, in UInt256 nonce) + public void SetNonce(Address address, in ulong nonce) { _innerWorldState.SetNonce(address, nonce); - _generatingBlockAccessList.AddNonceChange(address, (ulong)nonce); + _generatingBlockAccessList.AddNonceChange(address, nonce); } public bool InsertCode(Address address, in ValueHash256 codeHash, ReadOnlyMemory code, IReleaseSpec spec, bool isGenesis = false) @@ -134,7 +134,7 @@ public ref readonly UInt256 GetBalance(Address address) return ref _innerWorldState.GetBalance(address); } - public UInt256 GetNonce(Address address) + public ulong GetNonce(Address address) { AddAccountRead(address); return GetNonceInternal(address); @@ -184,13 +184,13 @@ public void DeleteAccount(Address address) _innerWorldState.DeleteAccount(address); } - public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { RecordCreateAccount(address, balance, nonce); _innerWorldState.CreateAccount(address, balance, nonce); } - public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default) { RecordCreateAccount(address, balance, nonce); _innerWorldState.CreateAccountIfNotExists(address, balance, nonce); @@ -282,10 +282,10 @@ public void ClearStorage(Address address) public void Commit(IReleaseSpec releaseSpec, IWorldStateTracer tracer, bool isGenesis = false, bool commitRoots = true) => _innerWorldState.Commit(releaseSpec, tracer, isGenesis, commitRoots); - public void CommitTree(long blockNumber) + public void CommitTree(ulong blockNumber) => _innerWorldState.CommitTree(blockNumber); - public void DecrementNonce(Address address, UInt256 delta) + public void DecrementNonce(Address address, ulong delta) => _innerWorldState.DecrementNonce(address, delta); public ArrayPoolList? GetAccountChanges() @@ -318,10 +318,10 @@ private UInt256 GetBalanceInternal(Address address) return accountChanges?.BalanceChange?.Value; } - private UInt256 GetNonceInternal(Address address) + private ulong GetNonceInternal(Address address) => GetNonceCurrent(address) ?? _innerWorldState.GetNonce(address); - private UInt256? GetNonceCurrent(Address address) + private ulong? GetNonceCurrent(Address address) { AccountChangesAtIndex? accountChanges = _generatingBlockAccessList.GetAccountChanges(address); return accountChanges?.NonceChange?.Value; @@ -394,16 +394,16 @@ private bool AccountExistsInternal(Address address) return null; } - private void RecordCreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) + private void RecordCreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { AddAccountRead(address); if (!balance.IsZero) { _generatingBlockAccessList.AddBalanceChange(address, 0, balance); } - if (!nonce.IsZero) + if (nonce != 0) { - _generatingBlockAccessList.AddNonceChange(address, (ulong)nonce); + _generatingBlockAccessList.AddNonceChange(address, nonce); } } diff --git a/src/Nethermind/Nethermind.State/TrieStoreScopeProvider.cs b/src/Nethermind/Nethermind.State/TrieStoreScopeProvider.cs index f018baecd779..8920531750fe 100644 --- a/src/Nethermind/Nethermind.State/TrieStoreScopeProvider.cs +++ b/src/Nethermind/Nethermind.State/TrieStoreScopeProvider.cs @@ -92,7 +92,7 @@ public void Dispose() public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estimatedAccountNumber) => new WorldStateWriteBatch(this, estimatedAccountNumber, _logManager.GetClassLogger()); - public void Commit(long blockNumber) + public void Commit(ulong blockNumber) { using IBlockCommitter blockCommitter = _scopeProvider._trieStore.BeginBlockCommit(blockNumber); diff --git a/src/Nethermind/Nethermind.State/WorldState.cs b/src/Nethermind/Nethermind.State/WorldState.cs index 0a5b3ce7f345..d462d54d1b63 100644 --- a/src/Nethermind/Nethermind.State/WorldState.cs +++ b/src/Nethermind/Nethermind.State/WorldState.cs @@ -159,7 +159,7 @@ public void DeleteAccount(Address address) DebugGuardInScope(); _stateProvider.DeleteAccount(address); } - public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccount(Address address, in UInt256 balance, in ulong nonce = default) { DebugGuardInScope(); _stateProvider.CreateAccount(address, balance, nonce); @@ -189,18 +189,18 @@ public void SubtractFromBalance(Address address, in UInt256 balanceChange, IRele DebugGuardInScope(); _stateProvider.SubtractFromBalance(address, balanceChange, spec, out oldBalance); } - public void IncrementNonce(Address address, UInt256 delta, out UInt256 oldNonce) + public void IncrementNonce(Address address, ulong delta, out ulong oldNonce) { DebugGuardInScope(); _stateProvider.IncrementNonce(address, delta, out oldNonce); } - public void DecrementNonce(Address address, UInt256 delta) + public void DecrementNonce(Address address, ulong delta) { DebugGuardInScope(); _stateProvider.DecrementNonce(address, delta); } - public void CommitTree(long blockNumber) + public void CommitTree(ulong blockNumber) { DebugGuardInScope(); _stateProvider.UpdateStateRootIfNeeded(); @@ -208,7 +208,7 @@ public void CommitTree(long blockNumber) _persistentStorageProvider.ClearStorageMap(); } - public UInt256 GetNonce(Address address) + public ulong GetNonce(Address address) { DebugGuardInScope(); return _stateProvider.GetNonce(address); @@ -287,7 +287,7 @@ public bool IsNonZeroAccount(Address address, out bool accountExists) DebugGuardInScope(); Account? account = _stateProvider.GetThroughCache(address); accountExists = account is not null; - return accountExists && (account!.IsContract || !account.Nonce.IsZero || !_persistentStorageProvider.IsStorageEmpty(address)); + return accountExists && (account!.IsContract || !(account.Nonce == 0) || !_persistentStorageProvider.IsStorageEmpty(address)); } public bool IsDeadAccount(Address address) @@ -338,13 +338,13 @@ internal void Restore(int state, int persistentStorage, int transientStorage) Restore(new Snapshot(new Snapshot.Storage(persistentStorage, transientStorage), state, -1)); } - public void SetNonce(Address address, in UInt256 nonce) + public void SetNonce(Address address, in ulong nonce) { DebugGuardInScope(); _stateProvider.SetNonce(address, nonce); } - public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) + public void CreateAccountIfNotExists(Address address, in UInt256 balance, in ulong nonce = default) { DebugGuardInScope(); _stateProvider.CreateAccountIfNotExists(address, balance, nonce); diff --git a/src/Nethermind/Nethermind.State/WorldStateMetricsScopeProvider.cs b/src/Nethermind/Nethermind.State/WorldStateMetricsScopeProvider.cs index 07a533e8fb8a..b082315624b2 100644 --- a/src/Nethermind/Nethermind.State/WorldStateMetricsScopeProvider.cs +++ b/src/Nethermind/Nethermind.State/WorldStateMetricsScopeProvider.cs @@ -40,7 +40,7 @@ public void Dispose() public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estimatedAccountNum) => baseScope.StartWriteBatch(estimatedAccountNum); - public void Commit(long blockNumber) + public void Commit(ulong blockNumber) { long start = Stopwatch.GetTimestamp(); baseScope.Commit(blockNumber); diff --git a/src/Nethermind/Nethermind.State/WorldStateScopeOperationLogger.cs b/src/Nethermind/Nethermind.State/WorldStateScopeOperationLogger.cs index a02e2c7edece..261922fe2d8f 100644 --- a/src/Nethermind/Nethermind.State/WorldStateScopeOperationLogger.cs +++ b/src/Nethermind/Nethermind.State/WorldStateScopeOperationLogger.cs @@ -59,7 +59,7 @@ public IWorldStateScopeProvider.IStorageTree CreateStorageTree(Address address) public IWorldStateScopeProvider.IWorldStateWriteBatch StartWriteBatch(int estimatedAccountNum) => new WriteBatchWrapper(innerScope.StartWriteBatch(estimatedAccountNum), scopeId, logger); - public void Commit(long blockNumber) => innerScope.Commit(blockNumber); + public void Commit(ulong blockNumber) => innerScope.Commit(blockNumber); } private class StorageTreeWrapper(IWorldStateScopeProvider.IStorageTree storageTree, Address address, long scopeId, ILogger logger) : IWorldStateScopeProvider.IStorageTree diff --git a/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs b/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs index ef3c7df66609..b32ebbbd38b1 100644 --- a/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs +++ b/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs @@ -24,7 +24,7 @@ namespace Nethermind.StateComposition.Test.Diff; [TestFixture] public class TrieDiffWalkerTests { - private static Account CreateEOA(int balance = 100) => new(0, (UInt256)balance); + private static Account CreateEOA(ulong balance = 100UL) => new(0UL, balance); private static Account CreateContract(Hash256 storageRoot, byte[]? code = null) { @@ -332,7 +332,7 @@ public void LargeTrie_IncrementalMatchesFullScan() MemDb db = new(); StateTree tree = new(new RawScopedTrieStore(db), LimboLogs.Instance); - for (int i = 0; i < 50; i++) + for (ulong i = 0; i < 50; i++) { byte[] addressBytes = new byte[20]; addressBytes[0] = (byte)(i >> 8); @@ -348,7 +348,7 @@ public void LargeTrie_IncrementalMatchesFullScan() tree.Accept(v1, root1); CumulativeTrieStats cumulative = CumulativeTrieStats.FromScanStats(v1.GetStats(1, root1)); - for (int i = 50; i < 60; i++) + for (ulong i = 50; i < 60; i++) { byte[] addressBytes = new byte[20]; addressBytes[0] = (byte)(i >> 8); @@ -436,7 +436,7 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() for (int i = 0; i < newEOAsPerBlock; i++) { Address addr = AddressFromSeed(addressSeed++); - tree.Set(addr, CreateEOA(rng.Next(1, 10000))); + tree.Set(addr, CreateEOA((ulong)rng.Next(1, 10000))); eoaAddresses.Add(addr); } @@ -462,7 +462,7 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() for (int i = 0; i < modifiedEOAsPerBlock && pool > 0; i++) { int idx = rng.Next(0, pool); - tree.Set(eoaAddresses[idx], CreateEOA(rng.Next(1, 10000))); + tree.Set(eoaAddresses[idx], CreateEOA((ulong)rng.Next(1, 10000))); } } @@ -499,9 +499,8 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() $"\nState generated: {eoaAddresses.Count} EOAs, {contractAddresses.Count} contracts, {totalBlocks} blocks\n"); // --- Verification: scan(X) + diffs(X→Y) == scan(Y) --- - (int from, int to)[] ranges = [(0, 5), (0, 10), (0, 19), (5, 15), (10, 19), (0, 1), (18, 19)]; - - foreach ((int from, int to) in ranges) + (ulong from, ulong to)[] ranges = [(0, 5), (0, 10), (0, 19), (5, 15), (10, 19), (0, 1), (18, 19)]; + foreach ((ulong from, ulong to) in ranges) { // 1. Full scan at 'from' StateCompositionVisitor v1 = new(LimboLogs.Instance); @@ -513,7 +512,7 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() // 2. Incremental diffs from→to RawScopedTrieStore resolver = new(db); TrieDiffWalker walker = new(); - for (int b = from; b < to; b++) + for (ulong b = from; b < to; b++) { TrieDiff diff = walker.ComputeDiff(roots[b], roots[b + 1], resolver); cumulative = cumulative.ApplyDiff(diff); diff --git a/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceIncrementalRecoveryTests.cs b/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceIncrementalRecoveryTests.cs index b861484e4652..9508216414a4 100644 --- a/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceIncrementalRecoveryTests.cs +++ b/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceIncrementalRecoveryTests.cs @@ -41,7 +41,7 @@ private static StateCompositionSnapshotStore CreateSnapshotStore() => private static IStateCompositionConfig CreateConfig() => TestDataBuilders.CreateTestConfig(trackDepthIncrementally: true); - private static void SeedBaseline(StateCompositionStateHolder holder, long blockNumber, Hash256 stateRoot) => + private static void SeedBaseline(StateCompositionStateHolder holder, ulong blockNumber, Hash256 stateRoot) => holder.InitializeIncremental(TestDataBuilders.EmptyBaseline(), blockNumber, stateRoot); [Test] diff --git a/src/Nethermind/Nethermind.StateComposition.Test/Snapshots/SnapshotRoundTripTests.cs b/src/Nethermind/Nethermind.StateComposition.Test/Snapshots/SnapshotRoundTripTests.cs index 2a4be9c6be07..06b928746a47 100644 --- a/src/Nethermind/Nethermind.StateComposition.Test/Snapshots/SnapshotRoundTripTests.cs +++ b/src/Nethermind/Nethermind.StateComposition.Test/Snapshots/SnapshotRoundTripTests.cs @@ -51,10 +51,10 @@ private static CumulativeTrieStats BuildStats(long codeBytes, ImmutableArray? slotCountByAddress = null, Dictionary? codeHashRefcounts = null, Dictionary? codeHashSizes = null) => diff --git a/src/Nethermind/Nethermind.StateComposition/Data/ScanMetadata.cs b/src/Nethermind/Nethermind.StateComposition/Data/ScanMetadata.cs index 40e12a80d596..360f96831102 100644 --- a/src/Nethermind/Nethermind.StateComposition/Data/ScanMetadata.cs +++ b/src/Nethermind/Nethermind.StateComposition/Data/ScanMetadata.cs @@ -13,7 +13,7 @@ namespace Nethermind.StateComposition.Data; /// public readonly record struct ScanMetadata { - public long BlockNumber { get; init; } + public ulong BlockNumber { get; init; } public Hash256 StateRoot { get; init; } public DateTimeOffset CompletedAt { get; init; } public TimeSpan Duration { get; init; } diff --git a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionReport.cs b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionReport.cs index c661d8d9c26e..0f887a5d112c 100644 --- a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionReport.cs +++ b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionReport.cs @@ -18,7 +18,7 @@ public readonly record struct StateCompositionReport public TrieDepthDistribution TrieDistribution { get; init; } /// Block number these stats correspond to. 0 until the first scan completes. - public long BlockNumber { get; init; } + public ulong BlockNumber { get; init; } public int DiffsSinceBaseline { get; init; } diff --git a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionSnapshot.cs b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionSnapshot.cs index fcd00a02c742..d07a67d0a264 100644 --- a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionSnapshot.cs +++ b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionSnapshot.cs @@ -22,10 +22,10 @@ namespace Nethermind.StateComposition.Data; /// public readonly record struct StateCompositionSnapshot( CumulativeTrieStats Stats, - long BlockNumber, + ulong BlockNumber, Hash256 StateRoot, int DiffsSinceBaseline, - long ScanBlockNumber, + ulong ScanBlockNumber, CumulativeDepthStats DepthStats, Dictionary SlotCountByAddress, Dictionary CodeHashRefcounts, diff --git a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionStats.cs b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionStats.cs index 446234a68fc0..a58b7519b2e2 100644 --- a/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionStats.cs +++ b/src/Nethermind/Nethermind.StateComposition/Data/StateCompositionStats.cs @@ -9,7 +9,7 @@ namespace Nethermind.StateComposition.Data; internal readonly record struct StateCompositionStats { - public long BlockNumber { get; init; } + public ulong BlockNumber { get; init; } public Hash256? StateRoot { get; init; } public long AccountsTotal { get; init; } public long ContractsTotal { get; init; } diff --git a/src/Nethermind/Nethermind.StateComposition/Metrics.cs b/src/Nethermind/Nethermind.StateComposition/Metrics.cs index 3b10cfdb53a9..44f7174342f1 100644 --- a/src/Nethermind/Nethermind.StateComposition/Metrics.cs +++ b/src/Nethermind/Nethermind.StateComposition/Metrics.cs @@ -60,7 +60,7 @@ public static class Metrics [GaugeMetric] [Description("Block number of latest incremental update")] - public static long StateCompIncrementalBlock { get; set; } + public static ulong StateCompIncrementalBlock { get; set; } [GaugeMetric] [Description("Diffs applied since last full scan")] @@ -72,7 +72,7 @@ public static class Metrics [GaugeMetric] [Description("Block number of last completed full scan")] - public static long StateCompScanBlock { get; set; } + public static ulong StateCompScanBlock { get; set; } [CounterMetric] [Description("Total full scans completed")] diff --git a/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionService.cs b/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionService.cs index 16ba4aef4b02..39e5fdd364a5 100644 --- a/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionService.cs +++ b/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionService.cs @@ -288,7 +288,7 @@ private void PublishScanResults(StateCompositionStats stats, TrieDepthDistributi /// for every snapshot write — interval writes, scan completion, and the /// graceful-shutdown flush all go through here so behavior cannot drift. /// - private void WriteSnapshotForHead(CumulativeTrieStats stats, long blockNumber, Hash256 stateRoot) + private void WriteSnapshotForHead(CumulativeTrieStats stats, ulong blockNumber, Hash256 stateRoot) { if (!_config.PersistSnapshots) return; _snapshotStore.WriteSnapshot(_stateHolder.BuildSnapshot(stats, blockNumber, stateRoot)); @@ -327,7 +327,7 @@ public async Task StopAsync() { lock (_diffLock) { - if (!_stateHolder.TryGetShutdownSnapshot(out Hash256 stateRoot, out long blockNumber, out CumulativeTrieStats stats)) + if (!_stateHolder.TryGetShutdownSnapshot(out Hash256 stateRoot, out ulong blockNumber, out CumulativeTrieStats stats)) return; if (_logger.IsInfo) diff --git a/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionStateHolder.cs b/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionStateHolder.cs index 12a9b225c215..fec1d3c59bc4 100644 --- a/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionStateHolder.cs +++ b/src/Nethermind/Nethermind.StateComposition/Service/StateCompositionStateHolder.cs @@ -34,7 +34,7 @@ internal sealed class StateCompositionStateHolder private CumulativeTrieStats _incrementalStats = new() { SlotCountHistogram = ImmutableArray.Empty }; private bool _hasIncrementalBaseline; private readonly CumulativeDepthStats _currentDepthStats = new(); - private long _incrementalBlock; + private ulong _incrementalBlock; private int _diffsSinceBaseline; // Sentinel: Hash256.Zero means "no baseline" (cold start or post-invalidation). // OnNewHeadBlock and RunIncrementalDiff gate on this directly instead of nullables. @@ -73,7 +73,7 @@ internal sealed class StateCompositionStateHolder /// internal CumulativeDepthStats CurrentDepthStats => _currentDepthStats; - public long IncrementalBlock { get { lock (_lock) return _incrementalBlock; } } + public ulong IncrementalBlock { get { lock (_lock) return _incrementalBlock; } } public int DiffsSinceBaseline { get { lock (_lock) return _diffsSinceBaseline; } } @@ -106,7 +106,7 @@ public StateCompositionReport BuildReport() /// public StateCompositionSnapshot BuildSnapshot( CumulativeTrieStats stats, - long blockNumber, + ulong blockNumber, Hash256 stateRoot) { lock (_lock) @@ -134,7 +134,7 @@ public void SetBaseline(StateCompositionStats stats, TrieDepthDistribution dist) } } - public void MarkScanCompleted(long blockNumber, Hash256 stateRoot, TimeSpan duration, bool isComplete) + public void MarkScanCompleted(ulong blockNumber, Hash256 stateRoot, TimeSpan duration, bool isComplete) { lock (_lock) { @@ -160,7 +160,7 @@ public void MarkScanCompleted(long blockNumber, Hash256 stateRoot, TimeSpan dura public void PublishScanBaseline( StateCompositionStats stats, TrieDepthDistribution dist, - long blockNumber, + ulong blockNumber, Hash256 stateRoot, TimeSpan duration, bool isComplete, @@ -203,7 +203,7 @@ public void PublishScanBaseline( /// when no incremental baseline is present or the state root has been /// invalidated ( sentinel). ///
- public bool TryGetShutdownSnapshot(out Hash256 stateRoot, out long blockNumber, out CumulativeTrieStats stats) + public bool TryGetShutdownSnapshot(out Hash256 stateRoot, out ulong blockNumber, out CumulativeTrieStats stats) { lock (_lock) { @@ -222,7 +222,7 @@ public bool TryGetShutdownSnapshot(out Hash256 stateRoot, out long blockNumber, } } - public void InitializeIncremental(CumulativeTrieStats baseline, long blockNumber, Hash256 stateRoot, + public void InitializeIncremental(CumulativeTrieStats baseline, ulong blockNumber, Hash256 stateRoot, TrieDepthDistribution? depthDistribution = null, Dictionary? slotCountByAddress = null, Dictionary? codeHashRefcounts = null, @@ -272,7 +272,7 @@ public void InvalidateBaseline() /// ///
public CumulativeTrieStats ApplyIncrementalDiffAndUpdate( - TrieDiff diff, long blockNumber, Hash256 stateRoot, + TrieDiff diff, ulong blockNumber, Hash256 stateRoot, Func codeSizeLookup) { lock (_lock) diff --git a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs index 992becfdd930..00c10ae06550 100644 --- a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs +++ b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs @@ -77,11 +77,11 @@ private static int EncodeOrLength(RlpStream? stream, StateCompositionSnapshot it length += EncodeLong(stream, item.Stats.ContractsWithStorage); length += EncodeLong(stream, item.Stats.EmptyAccounts); - length += EncodeLong(stream, item.BlockNumber); + length += EncodeULong(stream, item.BlockNumber); stream?.Encode(item.StateRoot); length += Rlp.LengthOf(item.StateRoot); length += EncodeInt(stream, item.DiffsSinceBaseline); - length += EncodeLong(stream, item.ScanBlockNumber); + length += EncodeULong(stream, item.ScanBlockNumber); // Depth stats: present only if seeded. Stored as a leading marker long // (1 = present, 0 = absent) followed by 146 longs (9×16 + 2 scalars) @@ -127,6 +127,8 @@ private static int EncodeLong(RlpStream? stream, long value) return Rlp.LengthOf(value); } + private static int EncodeULong(RlpStream? stream, ulong value) => EncodeLong(stream, (long)value); + private static int EncodeInt(RlpStream? stream, int value) { stream?.Encode(value); @@ -191,10 +193,10 @@ protected override StateCompositionSnapshot DecodeInternal(ref Rlp.ValueDecoderC ContractsWithStorage: ctx.DecodeLong(), EmptyAccounts: ctx.DecodeLong()); - long blockNumber = ctx.DecodeLong(); + ulong blockNumber = ctx.DecodeULong(); Hash256 stateRoot = ctx.DecodeKeccak()!; int diffsSinceBaseline = ctx.DecodeInt(); - long scanBlockNumber = ctx.DecodeLong(); + ulong scanBlockNumber = ctx.DecodeULong(); // Depth stats: marker long followed by 146 longs when present. The // decoder always materializes an instance — an unseeded one when the diff --git a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotStore.cs b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotStore.cs index e9de01ce0d37..bf1ad600ecad 100644 --- a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotStore.cs +++ b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotStore.cs @@ -40,13 +40,13 @@ public void WriteSnapshot(StateCompositionSnapshot snapshot) // still works. The reverse order (remove-first) would let PurgeOldEntries // delete the freshly written snapshot because LatestKey still pointed at // the already-removed old block. - long prevBlock = long.MinValue; + ulong prevBlock = ulong.MinValue; byte[]? prevBytes = db.Get(LatestKey); if (prevBytes is not null && prevBytes.Length >= 8) - prevBlock = BinaryPrimitives.ReadInt64BigEndian(prevBytes); + prevBlock = BinaryPrimitives.ReadUInt64BigEndian(prevBytes); Span key = stackalloc byte[8]; - BinaryPrimitives.WriteInt64BigEndian(key, snapshot.BlockNumber); + BinaryPrimitives.WriteUInt64BigEndian(key, snapshot.BlockNumber); int length = Decoder.GetLength(snapshot); byte[] buffer = ArrayPool.Shared.Rent(length); @@ -62,21 +62,21 @@ public void WriteSnapshot(StateCompositionSnapshot snapshot) } Span blockBytes = stackalloc byte[8]; - BinaryPrimitives.WriteInt64BigEndian(blockBytes, snapshot.BlockNumber); + BinaryPrimitives.WriteUInt64BigEndian(blockBytes, snapshot.BlockNumber); db.PutSpan(LatestKey, blockBytes); - if (prevBlock != long.MinValue && prevBlock != snapshot.BlockNumber) + if (prevBlock != ulong.MinValue && prevBlock != snapshot.BlockNumber) { Span prevKey = stackalloc byte[8]; - BinaryPrimitives.WriteInt64BigEndian(prevKey, prevBlock); + BinaryPrimitives.WriteUInt64BigEndian(prevKey, prevBlock); db.Remove(prevKey); } } - public StateCompositionSnapshot? ReadSnapshot(long blockNumber) + public StateCompositionSnapshot? ReadSnapshot(ulong blockNumber) { Span key = stackalloc byte[8]; - BinaryPrimitives.WriteInt64BigEndian(key, blockNumber); + BinaryPrimitives.WriteUInt64BigEndian(key, blockNumber); byte[]? data = db.Get(key); if (data is null) return null; @@ -103,7 +103,7 @@ public void WriteSnapshot(StateCompositionSnapshot snapshot) byte[]? latestBytes = db.Get(LatestKey); if (latestBytes is null || latestBytes.Length < 8) return null; - long latestBlock = BinaryPrimitives.ReadInt64BigEndian(latestBytes); + ulong latestBlock = BinaryPrimitives.ReadUInt64BigEndian(latestBytes); return ReadSnapshot(latestBlock); } diff --git a/src/Nethermind/Nethermind.StateComposition/Visitors/StateCompositionVisitor.cs b/src/Nethermind/Nethermind.StateComposition/Visitors/StateCompositionVisitor.cs index 9d51895d6bf7..72ea7bac7854 100644 --- a/src/Nethermind/Nethermind.StateComposition/Visitors/StateCompositionVisitor.cs +++ b/src/Nethermind/Nethermind.StateComposition/Visitors/StateCompositionVisitor.cs @@ -201,7 +201,7 @@ public void VisitAccount(in StateCompositionContext ctx, TrieNode node, in Accou // _codeHashSizes is a ConcurrentDictionary during the parallel scan — it is // converted to a plain Dictionary exactly once here so downstream consumers // do not pay the concurrent-dict overhead on every diff. - public StateCompositionStats GetStats(long blockNumber, Hash256? stateRoot) + public StateCompositionStats GetStats(ulong blockNumber, Hash256? stateRoot) { VisitorCounters agg = GetAggregated(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs index 155b5c926d5a..9ee3096d1b3e 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs @@ -30,13 +30,13 @@ namespace Nethermind.Synchronization.Test; public partial class BlockDownloaderTests { - [TestCase(16L, 32L, false, 32, 32)] - [TestCase(16L, 32L, false, 32, 29)] - [TestCase(16L, 32L, true, 0, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, true, 32, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, false, 32, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, false, 32, SyncBatchSizeMax * 8 - 16L)] - public async Task Merge_Happy_path(long beaconPivot, long headNumber, bool enableFastSync, int fastSyncLag, long insertedBeaconBlocks) + [TestCase(16UL, 32UL, false, 32, 32UL)] + [TestCase(16UL, 32UL, false, 32, 29UL)] + [TestCase(16UL, 32UL, true, 0, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, true, 32, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, false, 32, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, false, 32, SyncBatchSizeMax * 8 - 16UL)] + public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool enableFastSync, int fastSyncLag, ulong insertedBeaconBlocks) { bool withReceipts = enableFastSync; int notSyncedTreeStartingBlockNumber = 3; @@ -46,7 +46,7 @@ public async Task Merge_Happy_path(long beaconPivot, long headNumber, bool enabl .GoesLikeThis() .WithBlockTrees(notSyncedTreeStartingBlockNumber + 1, (int)headNumber + 1, receiptStorage: receiptStorage) .InsertBeaconPivot(beaconPivot) - .InsertBeaconHeaders(notSyncedTreeStartingBlockNumber + 1, beaconPivot - 1) + .InsertBeaconHeaders((ulong)(notSyncedTreeStartingBlockNumber + 1), beaconPivot - 1) .InsertBeaconBlocks(beaconPivot + 1, insertedBeaconBlocks, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); BlockTree syncedTree = blockTrees.SyncedTree; @@ -78,10 +78,10 @@ public async Task Merge_Happy_path(long beaconPivot, long headNumber, bool enabl { await ctx.FastSyncUntilNoRequest(peerInfo); long expectedDownloadStart = notSyncedTreeStartingBlockNumber; - long expectedDownloadEnd = Math.Min(headNumber, insertedBeaconBlocks - fastSyncLag); + long expectedDownloadEnd = Math.Min((long)headNumber, (long)insertedBeaconBlocks - fastSyncLag); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); - Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(Math.Max(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max((ulong)notSyncedTreeStartingBlockNumber, (ulong)expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(Math.Max((ulong)notSyncedTreeStartingBlockNumber, (ulong)expectedDownloadEnd))); int receiptCount = 0; for (long i = expectedDownloadStart; i < expectedDownloadEnd; i++) @@ -93,7 +93,7 @@ public async Task Merge_Happy_path(long beaconPivot, long headNumber, bool enabl } Assert.That(ctx.ReceiptStorage.Count, Is.EqualTo(withReceipts ? receiptCount : 0)); - Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(Math.Max(insertedBeaconBlocks - fastSyncLag, beaconPivot))); + Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(Math.Max(insertedBeaconBlocks - (ulong)fastSyncLag, beaconPivot))); } await ctx.FullSyncUntilNoRequest(peerInfo); @@ -110,7 +110,7 @@ public async Task Can_reach_terminal_block(long headNumber, int options, int thr .WithBlockTrees(4, (int)headNumber + 1, true, ttd) .InsertBeaconPivot(16) .InsertBeaconHeaders(4, 15) - .InsertBeaconBlocks(17, headNumber, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); + .InsertBeaconBlocks(17, (ulong)headNumber, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); BlockTree syncedTree = blockTrees.SyncedTree; await using IContainer container = CreateMergeNode(blockTrees, new MergeConfig() @@ -120,7 +120,7 @@ public async Task Can_reach_terminal_block(long headNumber, int options, int thr PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16, BlockTreeLookupOptions.None)); + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -129,9 +129,9 @@ public async Task Can_reach_terminal_block(long headNumber, int options, int thr Assert.That(ctx.PoSSwitcher.HasEverReachedTerminalBlock(), Is.True); } - [TestCase(32L, 16, false, 16)] - [TestCase(32L, 16, true, 3)] // No beacon header, so it does not sync - public async Task IfNoBeaconPivot_thenStopAtPoS(long headNumber, int ttdBlock, bool withBeaconPivot, int expectedBestKnownNumber) + [TestCase(32UL, 16, false, 16)] + [TestCase(32UL, 16, true, 3)] // No beacon header, so it does not sync + public async Task IfNoBeaconPivot_thenStopAtPoS(ulong headNumber, int ttdBlock, bool withBeaconPivot, int expectedBestKnownNumber) { UInt256 ttd = 10_000_000; int negativeTd = BlockHeaderBuilder.DefaultDifficulty.ToInt32(null); @@ -155,7 +155,7 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(long headNumber, int ttdBlock, b PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16, BlockTreeLookupOptions.None)); + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -164,9 +164,9 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(long headNumber, int ttdBlock, b Assert.That(notSyncedTree.BestKnownNumber, Is.EqualTo(expectedBestKnownNumber)); } - [TestCase(32L, 32L, 0, 32)] - [TestCase(32L, 32L, 10, 22)] - public async Task WillSkipBlocksToIgnore(long pivot, long headNumber, int blocksToIgnore, long expectedBestKnownNumber) + [TestCase(32UL, 32UL, 0, 32)] + [TestCase(32UL, 32UL, 10, 22)] + public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int blocksToIgnore, long expectedBestKnownNumber) { BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() @@ -272,11 +272,11 @@ public async Task BlockDownloader_works_correctly_with_withdrawals() // normally chain length should be head number + 1 so here we setup a slightly shorter chain which // will only be fixed slightly later - long chainLength = headNumber + 1; + ulong chainLength = (ulong)headNumber + 1; SyncPeerMock syncPeerInternal = new(chainLength, true, responseOptions, true); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => syncPeerInternal.GetBlockHeaders(ci.ArgAt(0), ci.ArgAt(1), ci.ArgAt(2), ci.ArgAt(3))); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => syncPeerInternal.GetBlockHeaders(ci.ArgAt(0), ci.ArgAt(1), ci.ArgAt(2), ci.ArgAt(3))); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => syncPeerInternal.GetBlockBodies(ci.ArgAt>(0), ci.ArgAt(1))); @@ -298,12 +298,12 @@ public async Task BlockDownloader_works_correctly_with_withdrawals() await ctx.FullSyncUntilNoRequest(peerInfo); } - [TestCase(2)] - [TestCase(6)] - [TestCase(34)] - [TestCase(129)] - [TestCase(1024)] - public void BlockDownloader_does_not_stop_processing_when_main_chain_is_unknown(long pivot) + [TestCase(2UL)] + [TestCase(6UL)] + [TestCase(34UL)] + [TestCase(129UL)] + [TestCase(1024UL)] + public void BlockDownloader_does_not_stop_processing_when_main_chain_is_unknown(ulong pivot) { BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() @@ -365,10 +365,10 @@ ISyncPeerPool PeerPool PeerPool ) { - public void InsertBeaconHeaderFrom(SyncPeerMock syncPeer, long high, long low) + public void InsertBeaconHeaderFrom(SyncPeerMock syncPeer, ulong high, ulong low) { BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.BeaconHeaderInsert; - for (long i = high; i >= low; --i) + for (ulong i = high; i >= low; --i) { BlockHeader? beaconHeader = syncPeer.BlockTree.FindHeader(i, BlockTreeLookupOptions.None)!; @@ -377,7 +377,7 @@ public void InsertBeaconHeaderFrom(SyncPeerMock syncPeer, long high, long low) } } - public override void ShouldFastSyncedUntil(long blockNumber) => + public override void ShouldFastSyncedUntil(ulong blockNumber) => // With post merge, best suggested header always follow beacon pivot but not necessarily synced. // But BestSuggestedBody is updated, unlike PreMerge. // I don't make the rules diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index 06f0c5306139..a48feeb7d377 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -55,27 +55,27 @@ namespace Nethermind.Synchronization.Test; public partial class BlockDownloaderTests { private const int FullBatch = 24; - private const int SyncBatchSizeMax = 128; - - [TestCase(1L, false, 0)] - [TestCase(32L, false, 0)] - [TestCase(32L, true, 0)] - [TestCase(1L, true, 0)] - [TestCase(2L, true, 0)] - [TestCase(3L, true, 0)] - [TestCase(32L, true, 0)] + private const ulong SyncBatchSizeMax = 128; + + [TestCase(1UL, false, 0)] + [TestCase(32UL, false, 0)] + [TestCase(32UL, true, 0)] + [TestCase(1UL, true, 0)] + [TestCase(2UL, true, 0)] + [TestCase(3UL, true, 0)] + [TestCase(32UL, true, 0)] [TestCase(SyncBatchSizeMax * 8, true, 0)] [TestCase(SyncBatchSizeMax * 8, false, 0)] - [TestCase(1L, false, 32)] - [TestCase(32L, false, 32)] - [TestCase(32L, true, 32)] - [TestCase(1L, true, 32)] - [TestCase(2L, true, 32)] - [TestCase(3L, true, 32)] - [TestCase(32L, true, 32)] + [TestCase(1UL, false, 32)] + [TestCase(32UL, false, 32)] + [TestCase(32UL, true, 32)] + [TestCase(1UL, true, 32)] + [TestCase(2UL, true, 32)] + [TestCase(3UL, true, 32)] + [TestCase(32UL, true, 32)] [TestCase(SyncBatchSizeMax * 8, true, 32)] [TestCase(SyncBatchSizeMax * 8, false, 32)] - public async Task Happy_path(long headNumber, bool enableFastSync, int fastSynclag) + public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSynclag) { await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { @@ -92,7 +92,7 @@ public async Task Happy_path(long headNumber, bool enableFastSync, int fastSyncl // normally chain length should be head number + 1 so here we setup a slightly shorter chain which // will only be fixed slightly later - long chainLength = headNumber + 1; + ulong chainLength = headNumber + 1; SyncPeerMock syncPeer = new(chainLength, withReceipts, responseOptions); PeerInfo peerInfo = new(syncPeer); @@ -101,20 +101,23 @@ public async Task Happy_path(long headNumber, bool enableFastSync, int fastSyncl if (enableFastSync) { await ctx.FastSyncUntilNoRequest(peerInfo); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0, Math.Min(headNumber, headNumber - fastSynclag)))); + // Use long arithmetic to safely handle the fastSynclag subtraction (which could underflow if ulong). + long effectiveHead = Math.Max(0L, (long)headNumber - fastSynclag); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)effectiveHead)); } syncPeer.ExtendTree(chainLength * 2); await ctx.FullSyncUntilNoRequest(peerInfo); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0, peerInfo.HeadNumber))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0UL, peerInfo.HeadNumber))); // full sync does not set main chain, but triggers it processing which eventually set main chain Assert.That(ctx.BlockTree.IsMainChain(ctx.BlockTree.BestSuggestedHeader!.Hash!), Is.EqualTo(false)); if (enableFastSync) { int receiptCount = 0; - for (int i = 0; i < (int)Math.Max(0, headNumber - fastSynclag); i++) + long effectiveHead2 = Math.Max(0L, (long)headNumber - fastSynclag); + for (int i = 0; i < (int)effectiveHead2; i++) { if (i % 3 == 0) { @@ -129,10 +132,10 @@ public async Task Happy_path(long headNumber, bool enableFastSync, int fastSyncl [Test] public async Task Invoke_UpdateMainChain_Once() { - long headNumber = 100; + ulong headNumber = 100; int fastSyncLag = 10; bool withReceipts = true; - long chainLength = headNumber + 1; + ulong chainLength = headNumber + 1; await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { @@ -145,23 +148,27 @@ public async Task Invoke_UpdateMainChain_Once() PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); - List newHeadSequence = []; + List newHeadSequence = []; ctx.BlockTree.BlockAddedToMain += (_, b) => newHeadSequence.Add(b.Block.Number); await ctx.FastSyncUntilNoRequest(peerInfo); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0, Math.Min(headNumber, headNumber - fastSyncLag)))); + long effectiveHead = Math.Max(0L, (long)headNumber - fastSyncLag); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)effectiveHead)); - List expectedNewHeadSequence = Enumerable.Range(1, (int)(chainLength - fastSyncLag - 1)).Select((i) => (long)i).ToList(); + List expectedNewHeadSequence = Enumerable + .Range(1, (int)(chainLength - (ulong)fastSyncLag - 1)) + .Select(i => (ulong)i) + .ToList(); Assert.That(newHeadSequence, Is.EqualTo(expectedNewHeadSequence)); } [Test] public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion() { - long headNumber = 200; + ulong headNumber = 200; int fastSyncLag = 10; bool withReceipts = true; - long chainLength = headNumber + 1; + ulong chainLength = headNumber + 1; IForwardHeaderProvider mockForwardHeaderProvider = Substitute.For(); @@ -278,7 +285,7 @@ public async Task Ancestor_lookup_simple() ctx.BlockTree.SuggestBlock(block1025); ctx.BlockTree.SuggestBlock(block1026); - for (int i = 0; i < 1023; i++) + for (uint i = 0; i < 1023; i++) { Assert.That(syncPeer.BlockTree.FindBlock(i, BlockTreeLookupOptions.None)!.Hash, Is.EqualTo(ctx.BlockTree.FindBlock(i, BlockTreeLookupOptions.None)!.Hash), i.ToString()); } @@ -339,39 +346,39 @@ public async Task Can_sync_with_peer_when_it_times_out(int ignoredBlocks, bool m }); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(async ci => await ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(async ci => await ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.TimeoutOnFullBatch)); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(FullBatch + ignoredBlocks + 20); + syncPeer.HeadNumber.Returns((ulong)(FullBatch + ignoredBlocks + 20)); PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); - await ctx.FullDispatcherSync(Math.Max(0, peerInfo.HeadNumber)); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0, peerInfo.HeadNumber))); + await ctx.FullDispatcherSync(Math.Max(0UL, peerInfo.HeadNumber)); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0UL, peerInfo.HeadNumber))); } - [TestCase(32, 32, 0, true)] - [TestCase(32, 16, 0, true)] - [TestCase(32, 32, 0, false)] - [TestCase(32, 16, 0, false)] - [TestCase(32, 16, 100, true)] - [TestCase(32, 16, 100, false)] - [TestCase(500, 250, 0, true)] - [TestCase(500, 250, 0, false)] - public async Task Can_sync_partially_when_only_some_bodies_is_available(int blockCount, int availableBlock, int minResponseLength, bool mergeDownloader) + [TestCase(32UL, 32UL, 0, true)] + [TestCase(32UL, 16UL, 0, true)] + [TestCase(32UL, 32UL, 0, false)] + [TestCase(32UL, 16UL, 0, false)] + [TestCase(32UL, 16UL, 100, true)] + [TestCase(32UL, 16UL, 100, false)] + [TestCase(500UL, 250UL, 0, true)] + [TestCase(500UL, 250UL, 0, false)] + public async Task Can_sync_partially_when_only_some_bodies_is_available(ulong blockCount, ulong availableBlock, int minResponseLength, bool mergeDownloader) { await using IContainer node = mergeDownloader ? CreateMergeNode() : CreateNode(); Context ctx = node.Resolve(); Response responseOptions = Response.AllCorrect | Response.WithTransactions & ~Response.AllKnown | Response.Consistent; ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(async ci => await ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), responseOptions)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(async ci => await ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), responseOptions)); List requestedHashes = []; syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) @@ -429,29 +436,29 @@ public async Task Peer_only_advertise_one_header() Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(_ => ctx.ResponseBuilder.BuildHeaderResponse(0, 1, Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1); + syncPeer.HeadNumber.Returns(1UL); ctx.ConfigureBestPeer(peerInfo); await ctx.FullSyncUntilNoRequest(peerInfo); Assert.That(ctx.BlockTree.BestSuggestedBody!.Number, Is.EqualTo(0)); } - [TestCase(33L)] - [TestCase(65L)] + [TestCase(33UL)] + [TestCase(65UL)] [Retry(3)] - public async Task Peer_sends_just_one_item_when_advertising_more_blocks_but_no_bodies(long headNumber) + public async Task Peer_sends_just_one_item_when_advertising_more_blocks_but_no_bodies(ulong headNumber) { await using IContainer node = CreateNode(); Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.NoBody)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.NoBody)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.JustFirst)); @@ -472,12 +479,12 @@ public async Task Throws_on_inconsistent_batch() await using IContainer node = CreateNode(); Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1024); + syncPeer.HeadNumber.Returns(1024UL); ctx.ConfigureBestPeer(peerInfo); await ctx.FullSyncUntilNoRequest(peerInfo); @@ -492,11 +499,11 @@ public async Task Throws_on_invalid_seal() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); ctx.ConfigureBestPeer(peerInfo); await ctx.Feed.PrepareRequest(default); @@ -512,13 +519,13 @@ public async Task Throws_on_invalid_header() Response options = Response.AllCorrect | Response.Consistent; ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), options)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), options)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), options | Response.JustFirst)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); ctx.ConfigureBestPeer(peerInfo); BlocksRequest blockRequest = await ctx.Feed.PrepareRequest(default); @@ -567,10 +574,10 @@ public async Task Prune_download_requests_map() [TestCase(false)] public async Task Can_DownloadBlockOutOfOrder(bool isMerge) { - int chainLength = 1024; - int syncPivotNumber = 128; - int beaconPivotNumber = 256; - int fastSyncLag = 1; + uint chainLength = 1024; + uint syncPivotNumber = 128; + uint beaconPivotNumber = 256; + uint fastSyncLag = 1; Response responseOptions = Response.AllCorrect | Response.WithTransactions; SyncPeerMock syncPeer = new(chainLength, true, responseOptions); @@ -580,7 +587,7 @@ public async Task Can_DownloadBlockOutOfOrder(bool isMerge) ISyncConfig syncConfig = new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = fastSyncLag, + StateMinDistanceFromHead = (int)fastSyncLag, PivotNumber = syncPivot.Number, PivotHash = syncPivot.Hash!.ToString(), }; @@ -642,17 +649,17 @@ public async Task Second_sync_does_not_redownload_blocks() ctx.ConfigureBestPeer(peerInfo); await ctx.FullSyncUntilNoRequest(peerInfo); - long afterFirstSync = ctx.BlockTree.BestSuggestedHeader!.Number; + ulong afterFirstSync = ctx.BlockTree.BestSuggestedHeader!.Number; syncPeer.ExtendTree(20); // Simulate 5 blocks arriving via P2P - advances BestKnownNumber without going through BlockDownloader - for (long i = afterFirstSync + 1; i <= afterFirstSync + 5; i++) + for (ulong i = afterFirstSync + 1; i <= afterFirstSync + 5; i++) { BlockHeader? header = syncPeer.BlockTree.FindHeader(i, BlockTreeLookupOptions.None); if (header is not null) ctx.BlockTree.SuggestHeader(header); } - long bestKnownAfterPropagation = ctx.BlockTree.BestKnownNumber; + ulong bestKnownAfterPropagation = ctx.BlockTree.BestKnownNumber; using BlocksRequest? secondRequest = await ctx.FullSyncFeedComponent.Feed.PrepareRequest(); Assert.That(secondRequest, Is.Not.Null); @@ -683,8 +690,8 @@ public async Task Flag_lesser_quality_on_body_download_failure() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(Task.FromException(new TimeoutException())); @@ -693,7 +700,7 @@ public async Task Flag_lesser_quality_on_body_download_failure() .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1); + syncPeer.HeadNumber.Returns(1UL); ctx.ConfigureBestPeer(peerInfo); Assert.That((await ctx.HandleOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.LesserQuality)); } @@ -707,8 +714,8 @@ public async Task Throws_on_receipt_task_exception_when_downloading_receipts() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions | Response.AllKnown)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions | Response.AllKnown)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions)); @@ -717,7 +724,7 @@ public async Task Throws_on_receipt_task_exception_when_downloading_receipts() .Returns(Task.FromException>(new TimeoutException())); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(10); + syncPeer.HeadNumber.Returns(10UL); ctx.ConfigureBestPeer(peerInfo); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.OK)); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.LesserQuality)); @@ -735,11 +742,11 @@ public async Task On_null_receipt_will_retry() // normally chain length should be head number + 1 so here we setup a slightly shorter chain which // will only be fixed slightly later - long chainLength = headNumber + 1; + ulong chainLength = (ulong)(headNumber + 1); SyncPeerMock syncPeerInternal = new(chainLength, true, responseOptions); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => syncPeerInternal.GetBlockHeaders(ci.ArgAt(0), ci.ArgAt(1), ci.ArgAt(2), ci.ArgAt(3))); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => syncPeerInternal.GetBlockHeaders(ci.ArgAt(0), ci.ArgAt(1), ci.ArgAt(2), ci.ArgAt(3))); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => syncPeerInternal.GetBlockBodies(ci.ArgAt>(0), ci.ArgAt(1))); @@ -774,8 +781,8 @@ public async Task Does_mark_low_quality_on_transaction_count_different_than_rece ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions)); @@ -785,7 +792,7 @@ public async Task Does_mark_low_quality_on_transaction_count_different_than_rece .Result.Select(r => r is null || r.Length == 0 ? r : r.Skip(1).ToArray()).ToPooledList(10)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(2); + syncPeer.HeadNumber.Returns(2UL); ctx.ConfigureBestPeer(peerInfo); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.OK)); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.LesserQuality)); @@ -800,8 +807,8 @@ public async Task Mark_low_quality_on_incorrect_receipts_root() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect | Response.WithTransactions)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions)); @@ -810,7 +817,7 @@ public async Task Mark_low_quality_on_incorrect_receipts_root() .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions | Response.IncorrectReceiptRoot).Result); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(2); + syncPeer.HeadNumber.Returns(2UL); ctx.ConfigureBestPeer(peerInfo); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.OK)); Assert.That((await ctx.HandleFastSyncOneRequest(peerInfo)), Is.EqualTo(SyncResponseHandlingResult.LesserQuality)); @@ -855,10 +862,11 @@ private IContainer CreateNode(Action? configurer = null, IConf return tree; }) - .AddSingleton, IBlockTree>((blockTree) => new Dictionary() + // Dictionary key changed from long to ulong to match BlockHeader.Number + .AddSingleton, IBlockTree>((blockTree) => new Dictionary() { { - 0, blockTree.Genesis!.Hash! + 0UL, blockTree.Genesis!.Hash! }, }) .AddSingleton(); @@ -950,7 +958,7 @@ public Task FullSyncUntilNoRequest(PeerInfo peerInfo) => public void WasSuggested(Hash256 blockHash) => Assert.That(_wasSuggested.TryGetValue(blockHash, out _), Is.True); - public async Task FullDispatcherSync(long untilBestSuggestedHeaderIs, long timeoutMs = 10000) + public async Task FullDispatcherSync(ulong untilBestSuggestedHeaderIs, long timeoutMs = 10000) { using AutoCancelTokenSource cts = AutoCancelTokenSource.ThatCancelAfter(timeoutMs.Milliseconds()); @@ -997,7 +1005,7 @@ public async Task HandleFastSyncOneRequest(PeerInfo return FastSyncFeedComponent.Feed.HandleResponse(blockRequest, peerInfo); } - public virtual void ShouldFastSyncedUntil(long blockNumber) => + public virtual void ShouldFastSyncedUntil(ulong blockNumber) => Assert.That(BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(blockNumber)); public void Deconstruct(out ResponseBuilder ResponseBuilder, out SyncFeedComponent FastSyncFeedComponent, out SyncFeedComponent FullSyncFeedComponent, out IForwardSyncController ForwardSyncController, out IBlockTree BlockTree, out InMemoryReceiptStorage ReceiptStorage, out ISyncPeerPool PeerPool) @@ -1027,7 +1035,7 @@ private class SyncPeerMock : ISyncPeer public string Name => "Mock"; public DisconnectReason? DisconnectReason { get; private set; } - public SyncPeerMock(long chainLength, bool withReceipts, Response flags, bool withWithdrawals = false) + public SyncPeerMock(ulong chainLength, bool withReceipts, Response flags, bool withWithdrawals = false) { _withReceipts = withReceipts; _withWithdrawals = withWithdrawals; @@ -1047,7 +1055,7 @@ public SyncPeerMock(BlockTree blockTree, bool withReceipts, Response flags, UInt TotalDifficulty = peerTotalDifficulty; } - private void BuildTree(long chainLength, bool withReceipts) + private void BuildTree(ulong chainLength, bool withReceipts) { _receiptStorage = new InMemoryReceiptStorage(); BlockTreeBuilder builder = Build.A.BlockTree(MainnetSpecProvider.Instance); @@ -1064,7 +1072,7 @@ private void BuildTree(long chainLength, bool withReceipts) TotalDifficulty = BlockTree.Head.TotalDifficulty ?? 0; } - public void ExtendTree(long newLength) => + public void ExtendTree(ulong newLength) => BuildTree(newLength, _withReceipts); public Node Node { get; } = null!; @@ -1073,7 +1081,7 @@ public void ExtendTree(long newLength) => public string ProtocolCode { get; } = null!; public Hash256 HeadHash { get; set; } = null!; public PublicKey Id => Node.Id; - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public UInt256? TotalDifficulty { get; set; } public bool IsInitialized { get; set; } public bool IsPriority { get; set; } @@ -1092,7 +1100,7 @@ public async Task GetBlockBodies(IReadOnlyList blockH return await Task.FromResult(_bodiesSerializer.Deserialize(messageSerialized).Bodies!); } - public async Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) + public async Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) { bool justFirst = _flags.HasFlag(Response.JustFirst); bool timeoutOnFullBatch = _flags.HasFlag(Response.TimeoutOnFullBatch); @@ -1105,7 +1113,8 @@ public async Task GetBlockBodies(IReadOnlyList blockH BlockHeader[] headers = new BlockHeader[maxBlocks]; for (int i = 0; i < (justFirst ? 1 : maxBlocks); i++) { - headers[i] = BlockTree.FindHeader(number + i, BlockTreeLookupOptions.None)!; + // Cast loop variable i (int) to ulong to avoid ambiguous operator with ulong number + headers[i] = BlockTree.FindHeader(number + (ulong)i, BlockTreeLookupOptions.None)!; } using BlockHeadersMessage message = new(headers.ToPooledList()); @@ -1154,14 +1163,14 @@ public bool TryGetSatelliteProtocol(string protocol, out T protocolHandler) w throw new NotImplementedException(); } - private class ResponseBuilder(IBlockTree blockTree, Dictionary testHeaderMapping) + private class ResponseBuilder(IBlockTree blockTree, Dictionary testHeaderMapping) { private static readonly ReceiptMessageDecoder ReceiptDecoder = new(); private readonly IBlockTree _blockTree = blockTree; - private readonly Dictionary _testHeaderMapping = testHeaderMapping; + private readonly Dictionary _testHeaderMapping = testHeaderMapping; - public async Task?> BuildHeaderResponse(long startNumber, int number, Response flags) + public async Task?> BuildHeaderResponse(ulong startNumber, int number, Response flags) { bool consistent = flags.HasFlag(Response.Consistent); bool justFirst = flags.HasFlag(Response.JustFirst); @@ -1208,7 +1217,8 @@ private class ResponseBuilder(IBlockTree blockTree, Dictionary te _blockTree.SuggestHeader(header); } - _testHeaderMapping[startNumber + i] = headers[i].Hash!; + // Cast loop variable i (int) to ulong to avoid ambiguous operator with ulong startNumber + _testHeaderMapping[startNumber + (ulong)i] = headers[i].Hash!; } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/E2ESyncTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/E2ESyncTests.cs index 77e02a47a040..0c4a5ea4a530 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/E2ESyncTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/E2ESyncTests.cs @@ -112,12 +112,16 @@ private int AllocatePort() => /// whose value is the sum of all original values. This preserves the cumulative effect /// while ensuring the dictionary keys don't inflate biggestBlockTransition. ///
- private static void RekeyDictionaryToGenesis(IDictionary? dict) + private static void RekeyDictionaryToGenesis(IDictionary? dict) { if (dict is null or { Count: 0 }) return; - long total = dict.Values.Sum(); + ulong total = 0; + foreach (ulong val in dict.Values) + { + total += val; + } dict.Clear(); - dict[0] = total; + dict[0UL] = total; } /// @@ -125,12 +129,12 @@ private static void RekeyDictionaryToGenesis(IDictionary? dict) /// using the last (highest-block) reward value. This preserves the final block reward /// while ensuring the dictionary keys don't inflate biggestBlockTransition. /// - private static void RekeyBlockRewardToGenesis(SortedDictionary? dict) + private static void RekeyBlockRewardToGenesis(SortedDictionary? dict) { if (dict is null or { Count: 0 }) return; UInt256 lastReward = dict.Values.Last(); dict.Clear(); - dict[0] = lastReward; + dict[0UL] = lastReward; } /// @@ -371,7 +375,7 @@ private static void NormalizeEngineBlockTransitions(IChainSpecParametersProvider if (engineParameters is EthashChainSpecEngineParameters ethashParameters) { ethashParameters.BlockReward = []; - ethashParameters.DifficultyBombDelays = new Dictionary(); + ethashParameters.DifficultyBombDelays = new Dictionary(); } } } @@ -514,8 +518,8 @@ private static async Task SetPivot(IContainer server, SyncConfig syncConfig, Can IBlockProcessingQueue blockProcessingQueue = server.Resolve(); await blockProcessingQueue.WaitForBlockProcessing(cancellationToken); IBlockTree serverBlockTree = server.Resolve(); - long serverHeadNumber = serverBlockTree.Head!.Number; - BlockHeader pivot = serverBlockTree.FindHeader(serverHeadNumber - headPivotDistance)!; + ulong serverHeadNumber = serverBlockTree.Head!.Number; + BlockHeader pivot = serverBlockTree.FindHeader(serverHeadNumber - (ulong)headPivotDistance)!; syncConfig.PivotHash = pivot.Hash!.ToString(); syncConfig.PivotNumber = pivot.Number; syncConfig.PivotTotalDifficulty = pivot.TotalDifficulty!.Value.ToString(); @@ -594,7 +598,7 @@ public async Task FastSync_downloads_block_access_lists_over_eth71() Assert.That(serverBal, Is.Not.Null); } - long syncPivotNumber = 0; + ulong syncPivotNumber = 0; PrivateKey clientKey = TestItem.PrivateKeyF; await using IContainer client = await CreateNode(clientKey, async (cfg, spec) => { @@ -681,7 +685,7 @@ public async Task FastSync_skips_pre_eip7928_block_access_lists_over_eth71() Assert.That(firstActivatedBal, Is.Not.Null); } - long syncPivotNumber = 0; + ulong syncPivotNumber = 0; PrivateKey clientKey = TestItem.PrivateKeyF; await using IContainer client = await CreateNode(clientKey, async (cfg, spec) => { @@ -809,7 +813,7 @@ public async Task BuildBlockWithTxs(Transaction[] transactions, CancellationToke public async Task SyncUntilFinished(IContainer server, CancellationToken cancellationToken, long finalizedDistanceFromHead) { IBlockTree otherBlockTree = server.Resolve(); - long finalizedBlockNumber = Math.Max(0, otherBlockTree.Head!.Number - finalizedDistanceFromHead); + ulong finalizedBlockNumber = otherBlockTree.Head!.Number > (ulong)finalizedDistanceFromHead ? otherBlockTree.Head!.Number - (ulong)finalizedDistanceFromHead : 0UL; Block finalizedBlock = otherBlockTree.FindBlock(finalizedBlockNumber)!; Block headBlock = otherBlockTree.Head!; blockCacheService.BlockCache.TryAdd(new Hash256AsKey(finalizedBlock.Hash!), finalizedBlock); @@ -889,15 +893,15 @@ private async Task ConnectTo(IContainer server, CancellationToken cancellationTo } } - private readonly Dictionary _nonces = []; + private readonly Dictionary _nonces = []; public async Task BuildBlockWithCode(byte[][] codes, CancellationToken cancellation) { // 1 000 000 000 - long gasLimit = 1_000_000; + ulong gasLimit = 1_000_000; - _nonces.TryGetValue(nodeKey.Address, out UInt256 currentNonce); - IReleaseSpec spec = specProvider.GetSpec((blockTree.Head?.Number) + 1 ?? 0, null); + _nonces.TryGetValue(nodeKey.Address, out ulong currentNonce); + IReleaseSpec spec = specProvider.GetSpec((blockTree.Head?.Number ?? 0UL) + 1UL, null); Transaction[] txs = codes.Select((byteCode) => Build.A.Transaction .WithCode(byteCode) .WithNonce(currentNonce++) @@ -911,10 +915,10 @@ public async Task BuildBlockWithCode(byte[][] codes, CancellationToken cancellat public async Task BuildBlockWithStorage(int blockNumber, CancellationToken cancellation) { - long gasLimit = 200_000; + ulong gasLimit = 200_000; - _nonces.TryGetValue(nodeKey.Address, out UInt256 currentNonce); - IReleaseSpec spec = specProvider.GetSpec((blockTree.Head?.Number ?? 0) + 1, null); + _nonces.TryGetValue(nodeKey.Address, out ulong currentNonce); + IReleaseSpec spec = specProvider.GetSpec((blockTree.Head?.Number ?? 0UL) + 1UL, null); Transaction tx; @@ -971,7 +975,8 @@ private ValueTask VerifyAllBlocksAndReceipts(IContainer server, CancellationToke IBlockTree otherBlockTree = server.Resolve(); IReceiptStorage otherReceiptStorage = server.Resolve(); - for (int i = 0; i < otherBlockTree.Head?.Number; i++) + ulong headNumber = otherBlockTree.Head?.Number ?? 0UL; + for (ulong i = 0; i < headNumber; i++) { cancellationToken.ThrowIfCancellationRequested(); Block clientBlock = blockTree.FindBlock(i)!; @@ -1029,7 +1034,7 @@ await ExecuteSyncFromServer(server, async (sourceServer, token) => await VerifyAllBlocksAndReceipts(sourceServer, token); }, cancellationToken); - public async Task SyncFromServerAndVerifyAccessLists(IContainer server, long syncPivotNumber, CancellationToken cancellationToken) => + public async Task SyncFromServerAndVerifyAccessLists(IContainer server, ulong syncPivotNumber, CancellationToken cancellationToken) => await ExecuteSyncFromServer(server, async (sourceServer, token) => { await VerifyHeadWith(sourceServer, token); @@ -1064,14 +1069,14 @@ await blockProcessorExceptionDetector.WatchForFailure(async (token) => Assert.That(stateVerified, Is.True); } - private Task VerifyBlockAccessListsWith(IContainer server, long syncPivotNumber, CancellationToken cancellationToken) + private Task VerifyBlockAccessListsWith(IContainer server, ulong syncPivotNumber, CancellationToken cancellationToken) { IBlockTree sourceBlockTree = server.Resolve(); IBlockAccessListStore sourceBlockAccessListStore = server.Resolve(); - long sourceHeadNumber = sourceBlockTree.Head!.Number; + ulong sourceHeadNumber = sourceBlockTree.Head!.Number; TestContext.Progress.WriteLine($"BAL sync verification: comparing BAL presence and exact BAL blobs for blocks 1-{sourceHeadNumber}. Pivot {syncPivotNumber}."); - for (long blockNumber = 1; blockNumber <= sourceHeadNumber; blockNumber++) + for (ulong blockNumber = 1; blockNumber <= sourceHeadNumber; blockNumber++) { cancellationToken.ThrowIfCancellationRequested(); CompareBlockAccessList(blockNumber); @@ -1085,7 +1090,7 @@ private Task VerifyBlockAccessListsWith(IContainer server, long syncPivotNumber, TestContext.Progress.WriteLine($"BAL sync verification: BALs matched through head {sourceHeadNumber}."); return Task.CompletedTask; - void CompareBlockAccessList(long blockNumber) + void CompareBlockAccessList(ulong blockNumber) { Block sourceBlock = sourceBlockTree.FindBlock(blockNumber)!; Block syncedBlock = blockTree.FindBlock(blockNumber)!; @@ -1129,7 +1134,7 @@ void CompareBlockAccessList(long blockNumber) } } - private static byte[]? GetBlockAccessListRlp(IBlockAccessListStore blockAccessListStore, long blockNumber, Hash256 blockHash) + private static byte[]? GetBlockAccessListRlp(IBlockAccessListStore blockAccessListStore, ulong blockNumber, Hash256 blockHash) { using MemoryManager? rlp = blockAccessListStore.GetRlp(blockNumber, blockHash); return rlp?.Memory.ToArray(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs index 27fb2c9ee16c..b44d0ce00426 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs @@ -41,7 +41,7 @@ public void Setup() _syncPeerPool = Substitute.For(); _metadataDb = new TestMemDb(); - _blockTree.SyncPivot.Returns((1, TestItem.KeccakA)); + _blockTree.SyncPivot.Returns((1UL, TestItem.KeccakA)); _feed = new BlockAccessListsSyncFeed( MainnetSpecProvider.Instance, @@ -84,7 +84,7 @@ public void Rejects_block_access_list_with_wrong_header_hash() SyncResponseHandlingResult result = _feed.HandleResponse(batch); Assert.That(result, Is.EqualTo(SyncResponseHandlingResult.NoProgress)); - _blockAccessListStore.DidNotReceive().Insert(Arg.Any(), Arg.Any(), Arg.Any()); + _blockAccessListStore.DidNotReceive().Insert(Arg.Any(), Arg.Any(), Arg.Any()); _syncPeerPool.Received(1).ReportBreachOfProtocol( peerInfo, DisconnectReason.InvalidTxOrUncle, @@ -94,20 +94,20 @@ public void Rejects_block_access_list_with_wrong_header_hash() [Test] public void Treats_pivot_without_block_access_list_hash_as_available() { - const long previousBarrier = 123; + const ulong previousBarrier = 123; _metadataDb.Set(MetadataDbKeys.BlockAccessListsBarrierWhenStarted, previousBarrier.ToBigEndianByteArrayWithoutLeadingZeros()); BlockHeader pivotHeader = Build.A.BlockHeader .WithBlockAccessListHash(null) .TestObject; - _blockTree.SyncPivot.Returns((2, TestItem.KeccakB)); + _blockTree.SyncPivot.Returns((2UL, TestItem.KeccakB)); _blockTree.FindHeader(TestItem.KeccakB, blockNumber: 2).Returns(pivotHeader); _feed.InitializeFeed(); - long barrier = _metadataDb.Get(MetadataDbKeys.BlockAccessListsBarrierWhenStarted).ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + ulong barrier = _metadataDb.Get(MetadataDbKeys.BlockAccessListsBarrierWhenStarted).ToLongFromBigEndianByteArrayWithoutLeadingZeros(); Assert.That(barrier, Is.EqualTo(previousBarrier)); - _blockAccessListStore.DidNotReceive().Exists(Arg.Any(), TestItem.KeccakB); + _blockAccessListStore.DidNotReceive().Exists(Arg.Any(), TestItem.KeccakB); } [Test] @@ -125,7 +125,7 @@ public void Treats_absent_bal_as_unavailable_without_penalizing_peer() SyncResponseHandlingResult result = _feed.HandleResponse(batch); Assert.That(result, Is.EqualTo(SyncResponseHandlingResult.NoProgress)); - _blockAccessListStore.DidNotReceive().Insert(Arg.Any(), Arg.Any(), Arg.Any()); + _blockAccessListStore.DidNotReceive().Insert(Arg.Any(), Arg.Any(), Arg.Any()); _syncPeerPool.DidNotReceive().ReportBreachOfProtocol( Arg.Any(), Arg.Any(), diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs index b74016724676..39208a566144 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs @@ -56,7 +56,7 @@ public void Setup() .WithBlocksDb(_blocksDb) .TestObject; - for (int i = 1; i < 100; i++) + for (ulong i = 1; i < 100; i++) { Block block = _syncingFromBlockTree.FindBlock(i, BlockTreeLookupOptions.None)!; _syncingToBlockTree.Insert(block.Header); @@ -206,12 +206,12 @@ public async Task ShouldRecoverOnInsertFailure() Assert.That(req2.Infos[0]!.BlockNumber, Is.EqualTo(95)); } - [TestCase(1, 99, false, null, false)] - [TestCase(1, 99, true, null, false)] - [TestCase(1, 99, false, 0, false)] + [TestCase(1UL, 99UL, false, null, false)] + [TestCase(1UL, 99UL, true, null, false)] + [TestCase(1UL, 99UL, false, 0L, false)] public void When_finished_sync_with_old_default_barrier_then_finishes_immediately( - long AncientBarrierInConfig, - long lowestInsertedBlockNumber, + ulong AncientBarrierInConfig, + ulong lowestInsertedBlockNumber, bool JustStarted, long? previousBarrierInDb, bool shouldFinish) @@ -245,7 +245,7 @@ public async Task When_AncientBodiesBarrier_exceeds_SyncPivot_then_finishes_imme public async Task When_AncientBodiesBarrier_decreased_after_partial_sync_feed_resumes_download() { // Previous run downloaded bodies from pivot (99) down to block 60. - for (int i = 60; i <= 99; i++) + for (ulong i = 60; i <= 99; i++) { _syncingToBlockTree.Insert(_syncingFromBlockTree.FindBlock(i, BlockTreeLookupOptions.None)!); } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs index 325d8fbbe1fc..1ff63a11e435 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs @@ -63,7 +63,7 @@ public void When_initialized_with_no_inserted_headers_progress_starts_at_zero() // Regression test for issue #11447: Reset() with a null LowestInsertedBlockHeader used to fall // back to 0, producing a current value of (_pivotNumber + 1) — visible as "Old Headers // 24,998,904 / 24,998,903 (100.00 %)" right after a fresh FlatDB sync started. - const long pivotNumber = 1000; + const ulong pivotNumber = 1000UL; BlockTree blockTree = Build.A.BlockTree().WithoutSettingHead.TestObject; blockTree.SyncPivot = (pivotNumber, TestItem.KeccakA); @@ -126,7 +126,7 @@ public async Task Can_handle_forks_with_persisted_headers() BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(); IBlockTree blockTree = blockTreeBuilder.TestObject; - for (int i = 500; i < 1000; i++) + for (ulong i = 500; i < 1000; i++) { Assert.That(blockTree.Insert(forkedBlockTree.FindHeader(i)!), Is.EqualTo(AddBlockResult.Added)); } @@ -430,7 +430,7 @@ public async Task Can_keep_returning_nulls_after_all_batches_were_prepared() [Test] public async Task Does_not_prepare_batch_when_destination_moves_past_request_cursor() { - const long pivotNumber = 1000; + const ulong pivotNumber = 1000UL; IBlockTree blockTree = Substitute.For(); blockTree.SyncPivot.Returns((pivotNumber, TestItem.KeccakA)); @@ -563,7 +563,7 @@ public async Task Can_insert_all_good_headers_from_dependent_batch_with_missing_ IBlockTree localBlockTree = Build.A.BlockTree(peerChain.FindBlock(0, BlockTreeLookupOptions.None)!, null).WithSyncConfig(syncConfig).TestObject; localBlockTree.SyncPivot = (pivotHeader.Number, pivotHeader.Hash); - const int lowestInserted = 999; + const ulong lowestInserted = 999UL; localBlockTree.Insert(peerChain.Head!, BlockTreeInsertBlockOptions.SaveHeader); ISyncReport report = new NullSyncReport(); @@ -575,12 +575,15 @@ public async Task Can_insert_all_good_headers_from_dependent_batch_with_missing_ using HeadersSyncBatch? dependentBatch = await feed.PrepareRequest(); dependentBatch!.ResponseSourcePeer = new PeerInfo(Substitute.For()); - void FillBatch(HeadersSyncBatch batch, long start, bool applyNulls) + void FillBatch(HeadersSyncBatch batch, ulong start, bool applyNulls) { int c = count; - List list = Enumerable.Range((int)start, batch.RequestSize) - .Select(i => peerChain.FindBlock(i, BlockTreeLookupOptions.None)!.Header) - .ToList(); + List list = new(batch.RequestSize); + ulong current = start; + for (int j = 0; j < batch.RequestSize; j++, current++) + { + list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); + } if (applyNulls) for (int i = nullIndex; 0 < c; i += increment) { @@ -592,9 +595,9 @@ void FillBatch(HeadersSyncBatch batch, long start, bool applyNulls) batch.Response = list.ToPooledList(); } - FillBatch(firstBatch!, lowestInserted - firstBatch!.RequestSize, false); - FillBatch(dependentBatch, lowestInserted - dependentBatch.RequestSize * 2, true); - long targetHeaderInDependentBatch = dependentBatch.StartNumber; + FillBatch(firstBatch!, lowestInserted - (ulong)firstBatch!.RequestSize, false); + FillBatch(dependentBatch, lowestInserted - (ulong)(dependentBatch.RequestSize * 2), true); + ulong targetHeaderInDependentBatch = dependentBatch.StartNumber; feed.HandleResponse(dependentBatch); feed.HandleResponse(firstBatch); @@ -623,7 +626,7 @@ public async Task Does_not_download_persisted_header() localBlockTree.SyncPivot = (pivotHeader.Number, pivotHeader.Hash); // Insert some chain - for (int i = 0; i < 600; i++) + for (ulong i = 0; i < 600; i++) { Assert.That(localBlockTree.SuggestHeader(peerChain.FindHeader(i)!), Is.EqualTo(AddBlockResult.Added)); } @@ -634,10 +637,16 @@ public async Task Does_not_download_persisted_header() localBlockTreeBuilder.ChainLevelInfoRepository, localBlockTreeBuilder.HeaderStore); feed.InitializeFeed(); - void FillBatch(HeadersSyncBatch batch) => - batch.Response = Enumerable.Range((int)batch.StartNumber!, batch.RequestSize) - .Select(i => peerChain.FindBlock(i, BlockTreeLookupOptions.None)!.Header) - .ToPooledList(batch.RequestSize); + void FillBatch(HeadersSyncBatch batch) + { + List list = new(batch.RequestSize); + ulong current = batch.StartNumber; + for (int j = 0; j < batch.RequestSize; j++, current++) + { + list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); + } + batch.Response = list.ToPooledList(); + } using HeadersSyncBatch batch1 = (await feed.PrepareRequest())!; Assert.That(batch1.StartNumber, Is.EqualTo(808)); @@ -675,7 +684,7 @@ public async Task Limits_persisted_headers_dependency() PivotNumber = pivotHeader.Number, PivotHash = pivotHeader.Hash!.ToString(), PivotTotalDifficulty = pivotHeader.TotalDifficulty.ToString()!, - FastHeadersMemoryBudget = (ulong)100.KB, + FastHeadersMemoryBudget = 100UL.KB, }; BlockTreeBuilder localBlockTreeBuilder = Build.A.BlockTree(peerChain.FindBlock(0, BlockTreeLookupOptions.None)!, null).WithSyncConfig(syncConfig); @@ -683,7 +692,7 @@ public async Task Limits_persisted_headers_dependency() localBlockTree.SyncPivot = (pivotHeader.Number, pivotHeader.Hash); // Insert some chain - for (int i = 300; i < 600; i++) + for (ulong i = 300; i < 600; i++) { Assert.That(localBlockTree.Insert(peerChain.FindHeader(i)!), Is.EqualTo(AddBlockResult.Added)); } @@ -718,8 +727,9 @@ public async Task Can_use_persisted_header_without_total_difficulty() IBlockTree localBlockTree = localBlockTreeBuilder.TestObject; localBlockTree.SyncPivot = (pivotHeader.Number, pivotHeader.Hash); - long firstCheckedHeader = pivotHeader.Number - GethSyncLimits.MaxHeaderFetch; - for (long i = firstCheckedHeader - 1; i <= firstCheckedHeader; i++) + // pivot.Number (700) >> MaxHeaderFetch, so firstCheckedHeader > 0 and the loop cannot underflow. + ulong firstCheckedHeader = pivotHeader.Number - (ulong)GethSyncLimits.MaxHeaderFetch; + for (ulong i = firstCheckedHeader - 1; i <= firstCheckedHeader; i++) { BlockHeader header = peerChain.FindHeader(i)!; header.TotalDifficulty = null; @@ -828,7 +838,7 @@ public void IsFinished_returns_false_when_headers_not_downloaded() }; blockTree.LowestInsertedHeader.Returns(Build.A.BlockHeader.WithNumber(2).WithStateRoot(TestItem.KeccakA).TestObject); - blockTree.SyncPivot.Returns((1, Keccak.Zero)); + blockTree.SyncPivot.Returns((1UL, Keccak.Zero)); HeadersSyncFeed feed = new( blockTree, @@ -863,7 +873,7 @@ public void When_lowestInsertedHeaderHasNoTD_then_fetchFromBlockTreeAgain() chainLevelInfoRepository: Substitute.For(), headerStore: Substitute.For(), totalDifficultyStrategy: new CumulativeTotalDifficultyStrategy()); - blockTree.SyncPivot.Returns((1000, TestItem.KeccakA)); + blockTree.SyncPivot.Returns((1000UL, TestItem.KeccakA)); BlockHeader header = Build.A.BlockHeader.WithNumber(900).TestObject; header.Difficulty = 10; @@ -898,7 +908,7 @@ public void When_cant_determine_pivot_total_difficulty_then_throw() chainLevelInfoRepository: Substitute.For(), headerStore: Substitute.For(), totalDifficultyStrategy: new CumulativeTotalDifficultyStrategy()); - blockTree.SyncPivot.Returns((1010, TestItem.KeccakB)); + blockTree.SyncPivot.Returns((1010UL, TestItem.KeccakB)); Action act = () => feed.InitializeFeed(); Assert.That(act, Throws.TypeOf()); @@ -925,7 +935,7 @@ public async Task Should_Limit_BatchSize_ToEstimate() chainLevelInfoRepository: Substitute.For(), headerStore: Substitute.For(), totalDifficultyStrategy: new CumulativeTotalDifficultyStrategy()); - blockTree.SyncPivot.Returns((1000, TestItem.KeccakB)); + blockTree.SyncPivot.Returns((1000UL, TestItem.KeccakB)); syncPeerPool.EstimateRequestLimit(RequestType.Headers, Arg.Any(), AllocationContexts.Headers, default) .Returns(Task.FromResult(5)); @@ -941,16 +951,16 @@ private class ResettableHeaderSyncFeed( ISyncConfig? syncConfig, ISyncReport? syncReport, ILogManager? logManager, - long? hangOnBlockNumber = null, - long? hangOnBlockNumberAfterInsert = null, + ulong? hangOnBlockNumber = null, + ulong? hangOnBlockNumberAfterInsert = null, ManualResetEventSlim? hangLatch = null, bool alwaysStartHeaderSync = false ) : HeadersSyncFeed(blockTree, syncPeerPool, syncConfig, syncReport, Substitute.For(), logManager, Substitute.For(), Substitute.For(), alwaysStartHeaderSync: alwaysStartHeaderSync) { private readonly ManualResetEventSlim? _hangLatch = hangLatch; - private readonly long? _hangOnBlockNumber = hangOnBlockNumber; - private readonly long? _hangOnBlockNumberAfterInsert = hangOnBlockNumberAfterInsert; + private readonly ulong? _hangOnBlockNumber = hangOnBlockNumber; + private readonly ulong? _hangOnBlockNumberAfterInsert = hangOnBlockNumberAfterInsert; public void Reset() { @@ -986,13 +996,13 @@ private class DestinationHeaderSyncFeed( ISyncConfig? syncConfig, ISyncReport? syncReport, ILogManager? logManager, - long destinationNumber + ulong destinationNumber ) : HeadersSyncFeed(blockTree, syncPeerPool, syncConfig, syncReport, Substitute.For(), logManager, Substitute.For(), Substitute.For()) { - public long DestinationNumber { get; set; } = destinationNumber; + public ulong DestinationNumber { get; set; } = destinationNumber; - protected override long HeadersDestinationNumber => DestinationNumber; + protected override ulong HeadersDestinationNumber => DestinationNumber; } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/ReceiptsSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/ReceiptsSyncFeedTests.cs index f3052a5f7490..89987193ba7a 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/ReceiptsSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/ReceiptsSyncFeedTests.cs @@ -37,20 +37,20 @@ private class Scenario { public Scenario(ISpecProvider specProvider, int nonEmptyBlocks, int txPerBlock, int emptyBlocks = 0) { - Blocks = new Block[_pivotNumber + 1]; + Blocks = new Block[(int)_pivotNumber + 1]; Blocks[0] = Build.A.Block.Genesis.TestObject; Block parent = Blocks[0]!; - for (int blockNumber = 1; blockNumber <= _pivotNumber; blockNumber++) + for (int blockNumber = 1; blockNumber <= (int)_pivotNumber; blockNumber++) { Block block = Build.A.Block .WithParent(parent) - .WithTransactions(blockNumber > _pivotNumber - nonEmptyBlocks ? txPerBlock : 0, specProvider).TestObject; + .WithTransactions(blockNumber > (int)_pivotNumber - nonEmptyBlocks ? txPerBlock : 0, specProvider).TestObject; - if (blockNumber > _pivotNumber - nonEmptyBlocks - emptyBlocks) + if (blockNumber > (int)_pivotNumber - nonEmptyBlocks - emptyBlocks) Blocks[blockNumber] = block; - if (blockNumber == _pivotNumber - nonEmptyBlocks - emptyBlocks + 1) + if (blockNumber == (int)_pivotNumber - nonEmptyBlocks - emptyBlocks + 1) LowestInsertedBody = block; parent = block; @@ -77,7 +77,7 @@ public Scenario(ISpecProvider specProvider, int nonEmptyBlocks, int txPerBlock, private IDb _metadataDb; private IHistoryPruner _historyPruner; - private static long _pivotNumber = 1024; + private static ulong _pivotNumber = 1024; private static readonly Scenario _1024BodiesWithOneTxEach; private static readonly Scenario _256BodiesWithOneTxEach; @@ -243,14 +243,14 @@ public async Task When_configured_to_skip_receipts_then_finishes_immediately() Assert.That(_progressLogger.HasEnded, Is.True); } - [TestCase(1, 1024, false, null, false)] - [TestCase(1, 1024, true, null, false)] - [TestCase(1, 1024, false, 0, false)] + [TestCase(1UL, 1024UL, false, null, false)] + [TestCase(1UL, 1024UL, true, null, false)] + [TestCase(1UL, 1024UL, false, 0UL, false)] public void When_finished_sync_with_old_default_barrier_then_finishes_immediately( - long AncientBarrierInConfig, - long? lowestInsertedReceiptBlockNumber, + ulong AncientBarrierInConfig, + ulong? lowestInsertedReceiptBlockNumber, bool JustStarted, - long? previousBarrierInDb, + ulong? previousBarrierInDb, bool shouldFinish) { _syncPointers = Substitute.For(); @@ -280,15 +280,15 @@ public async Task When_AncientReceiptsBarrier_exceeds_SyncPivot_then_finishes_im DownloadReceiptsInFastSync = true, }; _blockTree.SyncPivot.Returns((_pivotNumber, scenario.Blocks.Last()!.Hash!)); - _blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns( + _blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns( ci => { - Block? block = scenario.Blocks[ci.Arg()]; + Block? block = scenario.Blocks[(int)ci.Arg()]; return block is null ? null - : new BlockInfo(block.Hash!, block.TotalDifficulty ?? 0) { BlockNumber = ci.Arg() }; + : new BlockInfo(block.Hash!, block.TotalDifficulty ?? 0) { BlockNumber = ci.Arg() }; }); - _receiptStorage.HasBlock(Arg.Any(), Arg.Any()).Returns(false); + _receiptStorage.HasBlock(Arg.Any(), Arg.Any()).Returns(false); _syncPointers = new MemorySyncPointers(); _feed = new ReceiptsSyncFeed( @@ -351,16 +351,16 @@ private void LoadScenario(Scenario scenario, ISyncConfig syncConfig) _feed.InitializeFeed(); _blockTree.Genesis.Returns(scenario.Blocks[0]!.Header); - _blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns( + _blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns( ci => { - Block? block = scenario.Blocks[ci.Arg()]; + Block? block = scenario.Blocks[(int)ci.Arg()]; if (block is null) return null; BlockInfo blockInfo = new(block.Hash!, block.TotalDifficulty ?? 0) { - BlockNumber = ci.Arg(), + BlockNumber = ci.Arg(), }; return blockInfo; }); @@ -374,7 +374,7 @@ private void LoadScenario(Scenario scenario, ISyncConfig syncConfig) scenario.BlocksByHash.TryGetValue(ci.Arg(), out Block? value) ? value.Header : null); - _syncPointers.LowestInsertedReceiptBlockNumber.Returns((long?)null); + _syncPointers.LowestInsertedReceiptBlockNumber.Returns((ulong?)null); } [Test] @@ -448,7 +448,7 @@ public async Task Can_sync_final_batch() FillBatchResponses(batch!); _feed.HandleResponse(batch); - _syncPointers.LowestInsertedReceiptBlockNumber.Returns(1); + _syncPointers.LowestInsertedReceiptBlockNumber.Returns(1UL); Assert.That(_feed.PrepareRequest().Result, Is.EqualTo(null)); Assert.That(_feed.CurrentState, Is.EqualTo(SyncFeedState.Finished)); @@ -469,7 +469,7 @@ public void Is_fast_block_receipts_finished_returns_false_when_receipts_not_down _blockTree.LowestInsertedHeader.Returns(Build.A.BlockHeader.WithNumber(1).WithStateRoot(TestItem.KeccakA).TestObject); _syncPointers = Substitute.For(); - _syncPointers.LowestInsertedReceiptBlockNumber.Returns(2); + _syncPointers.LowestInsertedReceiptBlockNumber.Returns(2UL); ReceiptsSyncFeed feed = CreateFeed(); Assert.That(feed.IsFinished, Is.False); @@ -489,7 +489,7 @@ public void Is_fast_block_bodies_finished_returns_true_when_bodies_not_downloade _blockTree.LowestInsertedHeader.Returns(Build.A.BlockHeader.WithNumber(1).WithStateRoot(TestItem.KeccakA).TestObject); _syncPointers = Substitute.For(); - _syncPointers.LowestInsertedReceiptBlockNumber.Returns(1); + _syncPointers.LowestInsertedReceiptBlockNumber.Returns(1UL); ReceiptsSyncFeed feed = CreateFeed(); feed.InitializeFeed(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs index 65613260d35e..81a50ece8950 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs @@ -47,7 +47,7 @@ public void Can_read_back_all_set_values() public void Will_not_go_below_ancient_barrier() { IBlockTree blockTree = Substitute.For(); - blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns(new BlockInfo(TestItem.KeccakA, 0)); + blockTree.FindCanonicalBlockInfo(Arg.Any()).Returns(new BlockInfo(TestItem.KeccakA, 0)); SyncStatusList syncStatusList = new(blockTree, 1000, null, 900); syncStatusList.TryGetInfosForBatch(500, new AlwaysDownloadStrategy(), out BlockInfo?[] infos); @@ -59,10 +59,10 @@ public void Will_not_go_below_ancient_barrier() public void Will_skip_existing_keys() { IBlockTree blockTree = Substitute.For(); - blockTree.FindCanonicalBlockInfo(Arg.Any()) + blockTree.FindCanonicalBlockInfo(Arg.Any()) .Returns(ci => { - long blockNumber = (long)ci[0]; + ulong blockNumber = ci.ArgAt(0); return new BlockInfo(TestItem.KeccakA, 0) { BlockNumber = blockNumber @@ -71,19 +71,19 @@ public void Will_skip_existing_keys() SyncStatusList syncStatusList = new(blockTree, 100000, null, 1000); - ConstantDownloadStrategy downloadStrategy = new([99999, 99995, 99950, 99000, 99001, 99003, 85000]); + ConstantDownloadStrategy downloadStrategy = new([99999UL, 99995UL, 99950UL, 99000UL, 99001UL, 99003UL, 85000UL]); - List TryGetInfos() + List TryGetInfos() { syncStatusList.TryGetInfosForBatch(50, downloadStrategy, out BlockInfo?[] infos); return [.. infos.Where(bi => bi != null).Select((bi) => bi!.BlockNumber)]; } - Assert.That(TryGetInfos(), Is.EquivalentTo([99999, 99995])); // first two as it will try the first 50 only - Assert.That(TryGetInfos(), Is.EquivalentTo([99950])); // Then the next 50 - Assert.That(TryGetInfos(), Is.EquivalentTo([99000, 99001, 99003])); // If the next 50 failed, it will try looking far back. + Assert.That(TryGetInfos(), Is.EquivalentTo([99999UL, 99995UL])); // first two as it will try the first 50 only + Assert.That(TryGetInfos(), Is.EquivalentTo([99950UL])); // Then the next 50 + Assert.That(TryGetInfos(), Is.EquivalentTo([99000UL, 99001UL, 99003UL])); // If the next 50 failed, it will try looking far back. Assert.That(TryGetInfos(), Is.Empty); // If it look far back enough and still does not find anything it will just return so that progress can update. - Assert.That(TryGetInfos(), Is.EquivalentTo([85000])); // But as the existing blocks was already marked as inserted, it should be able to make progress on later call. + Assert.That(TryGetInfos(), Is.EquivalentTo([85000UL])); // But as the existing blocks was already marked as inserted, it should be able to make progress on later call. } [Test] @@ -185,7 +185,7 @@ private class AlwaysDownloadStrategy : IBlockDownloadStrategy public bool ShouldDownloadBlock(BlockInfo info) => true; } - private class ConstantDownloadStrategy(HashSet needToFetchBlocks) : IBlockDownloadStrategy + private class ConstantDownloadStrategy(HashSet needToFetchBlocks) : IBlockDownloadStrategy { public bool ShouldDownloadBlock(BlockInfo info) => needToFetchBlocks.Contains(info.BlockNumber); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs index 0537ee2d870c..bce0112ccf0d 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs @@ -68,7 +68,7 @@ public async Task Eth66Peer_RunGetNodeData() peer.ProtocolVersion.Returns((byte)66); peer.IsInitialized.Returns(true); peer.TotalDifficulty.Returns(new Int256.UInt256(1_000_000_000)); - peer.HeadNumber.Returns(ChainLength - 1); + peer.HeadNumber.Returns((ulong)(ChainLength - 1)); _pool.AddPeer(peer); using StateSyncBatch batch = new( @@ -89,7 +89,7 @@ public async Task GroupMultipleStorageSlotsByAccount() peer.ProtocolVersion.Returns((byte)67); peer.IsInitialized.Returns(true); peer.TotalDifficulty.Returns(new Int256.UInt256(1_000_000_000)); - peer.HeadNumber.Returns(ChainLength - 1); + peer.HeadNumber.Returns((ulong)(ChainLength - 1)); ISnapSyncPeer snapPeer = Substitute.For(); peer.TryGetSatelliteProtocol("snap", out Arg.Any()).Returns( x => diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs index 54e6c2241692..40c297cc5b78 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs @@ -135,7 +135,7 @@ public async Task HealBigSqueezedRandomTree() int endHashIndex; // Now process account ranges using stored snapshots - for (int blockNumber = 1; blockNumber <= blockJumps; blockNumber++) + for (uint blockNumber = 1; blockNumber <= blockJumps; blockNumber++) { // Set remote tree to the state at this block number remote.StateTree.RootHash = rootHashAtBlock[blockNumber]; @@ -164,7 +164,7 @@ public async Task HealBigSqueezedRandomTree() endHashIndex = pathPool.Length - 1; } - ProcessAccountRange(remote.StateTree, snapTrieFactory, blockJumps, finalRootHash, + ProcessAccountRange(remote.StateTree, snapTrieFactory, (ulong)blockJumps, finalRootHash, accounts.Where(a => a.Key >= pathPool[startingHashIndex] && a.Key <= pathPool[endHashIndex]).Select(a => new PathWithAccount(a.Key, a.Value)).ToArray()); startingHashIndex += 1000; @@ -181,7 +181,7 @@ public async Task HealBigSqueezedRandomTree() Assert.That(data.RequestedNodesCount, Is.LessThan(accounts.Count / 2)); } - private static void ProcessAccountRange(StateTree remoteStateTree, ISnapTrieFactory snapTrieFactory, int blockNumber, Hash256 rootHash, PathWithAccount[] accounts) + private static void ProcessAccountRange(StateTree remoteStateTree, ISnapTrieFactory snapTrieFactory, ulong blockNumber, Hash256 rootHash, PathWithAccount[] accounts) { ValueHash256 startingHash = accounts.First().Path; ValueHash256 endHash = accounts.Last().Path; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs index a71a9d20c0de..c8be5ecff216 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs @@ -573,7 +573,7 @@ public async Task Pending_items_cache_mechanism_works_across_root_changes(Cancel TestItem.Addresses[i], TrieScenarios.AccountJustState0 .WithChangedBalance((UInt256)(i + 10)) - .WithChangedNonce((UInt256)1) + .WithChangedNonce(1UL) .WithChangedCodeHash(Keccak.Compute(TrieScenarios.Code0)) .WithChangedStorageRoot(storage.RootHash)); } @@ -615,7 +615,7 @@ async Task RunOneRequest() TestItem.Addresses[i], TrieScenarios.AccountJustState0 .WithChangedBalance((UInt256)(i + 100)) - .WithChangedNonce((UInt256)2) + .WithChangedNonce(2UL) .WithChangedCodeHash(Keccak.Compute(TrieScenarios.Code1)) .WithChangedStorageRoot(storage.RootHash)); } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs index ee1c745e2f11..938cb7c8c73d 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs @@ -153,14 +153,14 @@ protected ContainerBuilder BuildTestContainerBuilder(RemoteDbContext remote, int .AddSingleton(static _ => { ISyncProgressResolver resolver = Substitute.For(); - resolver.FindBestHeader().Returns(0L); - resolver.FindBestFullState().Returns(0L); + resolver.FindBestHeader().Returns(0UL); + resolver.FindBestFullState().Returns(0UL); return resolver; }) .AddSingleton(static _ => { IBeaconSyncStrategy strategy = Substitute.For(); - strategy.GetTargetBlockHeight().Returns((long?)0L); + strategy.GetTargetBlockHeight().Returns((ulong?)0UL); return strategy; }); @@ -264,7 +264,7 @@ public SyncPeerMock( _maxRandomizedLatencyMs = maxRandomizedLatencyMs ?? 0; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider testFinalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider testFinalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); TrieStore trieStore = new(new NodeStorage(stateDb), Nethermind.Trie.Pruning.No.Pruning, Persist.EveryBlock, testFinalizedStateProvider, pruningConfig, LimboLogs.Instance); _stateDb = trieStore.TrieNodeRlpStore; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs index 823a0b4de65c..b12b004d88f8 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs @@ -23,13 +23,13 @@ namespace Nethermind.Synchronization.Test; public partial class ForwardHeaderProviderTests { - [TestCase(16L, 32L, 32, 32, 3, 32)] - [TestCase(16L, 32L, 32, 29, 3, 29)] - [TestCase(16L, 32L, 0, 32, 3, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, 32, 32, 3, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, 32, 32, 3, 32)] - [TestCase(16L, SyncBatchSizeMax * 8, 32, SyncBatchSizeMax * 8 - 16L, 3, 130)] - public async Task Merge_Happy_path(long beaconPivot, long headNumber, int threshold, long insertedBeaconBlocks, long expectedFirstBlock, long expectedLastBlock) + [TestCase(16UL, SyncBatchSizeMax * 8UL, 32, 32UL, 3, 32)] + [TestCase(16UL, SyncBatchSizeMax * 8UL, 32, 29UL, 3, 29)] + [TestCase(16UL, SyncBatchSizeMax * 8UL, 0, 32UL, 3, 32)] + [TestCase(16UL, SyncBatchSizeMax * 8UL, 32, 32UL, 3, 32)] + [TestCase(16UL, SyncBatchSizeMax * 8UL, 32, 32UL, 3, 32)] + [TestCase(16UL, SyncBatchSizeMax * 8UL, 32, SyncBatchSizeMax * 8UL - 16UL, 3, 130)] + public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, int threshold, ulong insertedBeaconBlocks, long expectedFirstBlock, long expectedLastBlock) { int notSyncedTreeStartingBlockNumber = 3; @@ -37,7 +37,7 @@ public async Task Merge_Happy_path(long beaconPivot, long headNumber, int thresh .GoesLikeThis() .WithBlockTrees(notSyncedTreeStartingBlockNumber + 1, (int)headNumber + 1) .InsertBeaconPivot(beaconPivot) - .InsertBeaconHeaders(notSyncedTreeStartingBlockNumber + 1, beaconPivot - 1) + .InsertBeaconHeaders((ulong)(notSyncedTreeStartingBlockNumber + 1), beaconPivot - 1) .InsertBeaconBlocks(beaconPivot + 1, insertedBeaconBlocks, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); BlockTree syncedTree = blockTrees.SyncedTree; @@ -83,7 +83,7 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(long headNumber, int options, in PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16, BlockTreeLookupOptions.None)); + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); @@ -95,9 +95,9 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(long headNumber, int options, in } - [TestCase(32L, 32L, 0, 32)] - [TestCase(32L, 32L, 10, 22)] - public async Task WillSkipBlocksToIgnore(long pivot, long headNumber, int blocksToIgnore, long expectedBestKnownNumber) + [TestCase(32UL, 32UL, 0, 32)] + [TestCase(32UL, 32UL, 10, 22)] + public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int blocksToIgnore, long expectedBestKnownNumber) { BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs index 60d6975bbf3d..cc93da4d7539 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs @@ -93,7 +93,7 @@ public async Task Ancestor_lookup_simple() ctx.BlockTree.SuggestBlock(block1025); ctx.BlockTree.SuggestBlock(block1026); - for (int i = 0; i < 1023; i++) + for (uint i = 0; i < 1023; i++) { Assert.That(syncPeer.BlockTree.FindBlock(i, BlockTreeLookupOptions.None)!.Hash, Is.EqualTo(ctx.BlockTree.FindBlock(i, BlockTreeLookupOptions.None)!.Hash), i.ToString()); } @@ -107,7 +107,7 @@ public async Task Ancestor_lookup_simple() public async Task Ancestor_lookup_with_sync_pivot() { SyncPeerMock syncPeer = new(1024, false, Response.AllCorrect); - int pivotNumber = 500; + uint pivotNumber = 500; BlockHeader syncPivot = syncPeer.BlockTree.FindHeader(pivotNumber, BlockTreeLookupOptions.None)!; await using IContainer node = CreateNode(builder => @@ -146,16 +146,16 @@ public async Task Ancestor_failure_blocks() ctx.PeerPool.Received().ReportBreachOfProtocol(peerInfo, DisconnectReason.ForwardSyncFailed, Arg.Any()); } - [TestCase(33L)] - [TestCase(65L)] - public async Task Peer_only_advertise_some_header(long headNumber) + [TestCase(33UL)] + [TestCase(65UL)] + public async Task Peer_only_advertise_some_header(ulong headNumber) { await using IContainer node = CreateNode(); Context ctx = node.Resolve(); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(_ => ctx.ResponseBuilder.BuildHeaderResponse(0, (int)(headNumber + 1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); @@ -175,12 +175,12 @@ public async Task Throws_on_inconsistent_batch() await using IContainer node = CreateNode(); Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1024); + syncPeer.HeadNumber.Returns(1024UL); ctx.ConfigureBestPeer(peerInfo); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; @@ -196,11 +196,11 @@ public async Task Throws_on_invalid_seal() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); ctx.ConfigureBestPeer(peerInfo); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; @@ -216,30 +216,30 @@ public async Task Cache_block_headers_unless_peer_changed() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); ctx.ConfigureBestPeer(peerInfo); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; Assert.That((await forwardHeader.GetBlockHeaders(0, 128, CancellationToken.None)), Is.Not.Null); Assert.That((await forwardHeader.GetBlockHeaders(0, 128, CancellationToken.None)), Is.Not.Null); - await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); + await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); ISyncPeer newSyncPeer = Substitute.For(); newSyncPeer.HeadHash.Returns(TestItem.KeccakB); - newSyncPeer.HeadNumber.Returns(1000); + newSyncPeer.HeadNumber.Returns(1000UL); newSyncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - newSyncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + newSyncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); ctx.ConfigureBestPeer(new PeerInfo(newSyncPeer)); Assert.That((await forwardHeader.GetBlockHeaders(0, 128, CancellationToken.None)), Is.Not.Null); - await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); - await newSyncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); + await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); + await newSyncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); } [Test] @@ -250,11 +250,11 @@ public async Task Cache_block_headers_with_disposal() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); ctx.ConfigureBestPeer(peerInfo); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; @@ -264,7 +264,7 @@ public async Task Cache_block_headers_with_disposal() using IOwnedReadOnlyList? headers2 = await forwardHeader.GetBlockHeaders(0, 128, CancellationToken.None); Assert.That(headers2, Is.Not.Null); - await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); + await syncPeer.Received(1).GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()); } private class SlowSealValidator : ISealValidator @@ -289,15 +289,15 @@ public async Task Can_cancel_seal_validation() Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1000); + syncPeer.HeadNumber.Returns(1000UL); CancellationTokenSource cancellation = new(); cancellation.CancelAfter(100); @@ -321,11 +321,11 @@ public async Task Validate_always_the_last_seal_and_random_seal_in_the_package() BlockHeader[] blockHeadersCopy = blockHeaders?.ToArray() ?? []; ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(blockHeaders); PeerInfo peerInfo = new(syncPeer); - syncPeer.HeadNumber.Returns(511); + syncPeer.HeadNumber.Returns(511UL); ctx.ConfigureBestPeer(peerInfo); IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; @@ -336,7 +336,7 @@ public async Task Validate_always_the_last_seal_and_random_seal_in_the_package() sealValidator.Received().ValidateSeal(blockHeadersCopy![^1], true); } - private class ThrowingPeer(long number, UInt256? totalDiff, Hash256? headHash = null) : ISyncPeer + private class ThrowingPeer(ulong number, UInt256? totalDiff, Hash256? headHash = null) : ISyncPeer { public string Name => "Throwing"; public string ClientId => "EX peer"; @@ -344,7 +344,7 @@ private class ThrowingPeer(long number, UInt256? totalDiff, Hash256? headHash = public string ProtocolCode { get; } = null!; public byte ProtocolVersion { get; } = default; public Hash256 HeadHash { get; set; } = headHash ?? Keccak.Zero; - public long HeadNumber { get; set; } = number; + public ulong HeadNumber { get; set; } = number; public UInt256? TotalDifficulty { get; set; } = totalDiff ?? UInt256.MaxValue; public bool IsInitialized { get; set; } public bool IsPriority { get; set; } @@ -358,7 +358,7 @@ public Task GetBlockBodies(IReadOnlyList blockHashes, public Task?> GetBlockHeaders(Hash256 blockHash, int maxBlocks, int skip, CancellationToken token) => throw new NotImplementedException(); - public Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) => + public Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) => throw new InvalidOperationException(); public Task GetHeadBlockHeader(Hash256? hash, CancellationToken token) => @@ -407,8 +407,8 @@ public async Task Reports_weak_peer_on_timeout_cancellation() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1000); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + syncPeer.HeadNumber.Returns(1000UL); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns?>>(x => throw new OperationCanceledException()); PeerInfo peerInfo = new(syncPeer); @@ -430,8 +430,8 @@ public async Task Throws_on_sync_cancellation() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); - syncPeer.HeadNumber.Returns(1000); - syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + syncPeer.HeadNumber.Returns(1000UL); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns?>>(x => throw new OperationCanceledException()); ctx.ConfigureBestPeer(syncPeer); @@ -562,7 +562,7 @@ private void BuildTree(long chainLength, bool withReceipts) public string ProtocolCode { get; } = null!; public Hash256 HeadHash { get; set; } = null!; public PublicKey Id => Node.Id; - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public UInt256? TotalDifficulty { get; set; } public bool IsInitialized { get; set; } public bool IsPriority { get; set; } @@ -581,7 +581,7 @@ public async Task GetBlockBodies(IReadOnlyList blockH return await Task.FromResult(_bodiesSerializer.Deserialize(messageSerialized).Bodies!); } - public async Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) + public async Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) { bool justFirst = _flags.HasFlag(Response.JustFirst); bool timeoutOnFullBatch = _flags.HasFlag(Response.TimeoutOnFullBatch); @@ -594,7 +594,7 @@ public async Task GetBlockBodies(IReadOnlyList blockH BlockHeader[] headers = new BlockHeader[maxBlocks]; for (int i = 0; i < (justFirst ? 1 : maxBlocks); i++) { - headers[i] = BlockTree.FindHeader(number + i, BlockTreeLookupOptions.None)!; + headers[i] = BlockTree.FindHeader(number + (ulong)i, BlockTreeLookupOptions.None)!; } using BlockHeadersMessage message = new(headers.ToPooledList()); @@ -752,7 +752,7 @@ Block BuildBlockForHeader(BlockHeader header, int txSeed) ? _headers[blockHashes[i]] : Build.A.BlockHeader.WithNumber(blockHeaders[i - 1].Number + 1).WithHash(blockHashes[i]).TestObject; - _testHeaderMapping[startHeader.Number + i] = blockHeaders[i].Hash!; + _testHeaderMapping[(long)(startHeader.Number + (ulong)i)] = blockHeaders[i].Hash!; BlockHeader header = consistent ? blockHeaders[i] diff --git a/src/Nethermind/Nethermind.Synchronization.Test/IContainerSynchronizerTestExtensions.cs b/src/Nethermind/Nethermind.Synchronization.Test/IContainerSynchronizerTestExtensions.cs index 9eb5af8a2a9f..79cafa85ba31 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/IContainerSynchronizerTestExtensions.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/IContainerSynchronizerTestExtensions.cs @@ -16,7 +16,7 @@ public static ContainerBuilder WithSuggestedHeaderOfStateRoot(this ContainerBuil { IBlockTree blockTree = Substitute.For(); BlockHeader header = Build.A.BlockHeader.WithStateRoot(stateRoot).WithNumber(1).TestObject; - blockTree.FindHeader(Arg.Any()).Returns(header); + blockTree.FindHeader(Arg.Any()).Returns(header); blockTree.BestSuggestedHeader.Returns(header); builder.AddSingleton(blockTree); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/MemorySyncPointers.cs b/src/Nethermind/Nethermind.Synchronization.Test/MemorySyncPointers.cs index 0e907a58507b..4827ba8581a9 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/MemorySyncPointers.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/MemorySyncPointers.cs @@ -5,7 +5,7 @@ namespace Nethermind.Synchronization.Test; public class MemorySyncPointers : ISyncPointers { - public long? LowestInsertedBodyNumber { get; set; } - public long? LowestInsertedReceiptBlockNumber { get; set; } - public long? LowestInsertedBlockAccessListBlockNumber { get; set; } + public ulong? LowestInsertedBodyNumber { get; set; } + public ulong? LowestInsertedReceiptBlockNumber { get; set; } + public ulong? LowestInsertedBlockAccessListBlockNumber { get; set; } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/BaseSyncPeerMock.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/BaseSyncPeerMock.cs index 4528f1f11d11..6087da30589f 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/BaseSyncPeerMock.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/BaseSyncPeerMock.cs @@ -18,7 +18,7 @@ namespace Nethermind.Synchronization.Test.ParallelSync; public class BaseSyncPeerMock : ISyncPeer, ISnapSyncPeer { public virtual PublicKey Id { get; } = null!; - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public virtual string ClientId { get; set; } = null!; public virtual void SendNewTransactions(IEnumerable txs, bool sendFullTx) => throw new System.NotImplementedException(); @@ -44,7 +44,7 @@ public virtual void Disconnect(DisconnectReason reason, string details) public virtual Task GetBlockBodies(IReadOnlyList blockHashes, CancellationToken token) => throw new System.NotImplementedException(); - public virtual Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) => + public virtual Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) => throw new System.NotImplementedException(); public Task?> GetBlockHeaders(Hash256 startHash, int maxBlocks, int skip, CancellationToken token) => diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorFastSyncTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorFastSyncTests.cs index 86252afceaab..499fde936f82 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorFastSyncTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorFastSyncTests.cs @@ -163,7 +163,7 @@ public void Finished_fast_sync_but_not_snap_ranges() => Scenario.GoesLikeThis(_n [Test] public void Finished_fast_sync_but_not_snap_ranges_IsFarFromHead() => Scenario.GoesLikeThis(_needToWaitForHeaders) - .IfThisNodeJustFinishedFastBlocksAndFastSync(bestHeader: Scenario.ChainHead.Number - 1000) + .IfThisNodeJustFinishedFastBlocksAndFastSync(bestHeader: Scenario.ChainHead.Number - 1000UL) .AndGoodPeersAreKnown() .WhenSnapSyncIsConfigured() .WhenHeaderIsFarFromHead() diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs index bd68517b284e..547776eb666c 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs @@ -23,8 +23,8 @@ public partial class MultiSyncModeSelectorTestsBase { public static class Scenario { - public const long FastSyncLag = 32; - public const long LargeDistanceBehindHead = 1024; + public const ulong FastSyncLag = 32; + public const ulong LargeDistanceBehindHead = 1024; public static BlockHeader Pivot { get; } = Build.A.Block .WithDifficulty(1) @@ -163,9 +163,9 @@ private void SetDefaults() SyncProgressResolver = Substitute.For(); SyncProgressResolver.ChainDifficulty.Returns(ValidGenesis.TotalDifficulty ?? 0); - SyncProgressResolver.FindBestHeader().Returns(0); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); + SyncProgressResolver.FindBestHeader().Returns(0UL); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); SyncProgressResolver.IsLoadingBlocksFromDb().Returns(false); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.None); SyncProgressResolver.SyncPivot.Returns((Pivot.Number, Keccak.Zero)); @@ -249,7 +249,7 @@ public ScenarioBuilder IfThisNodeIsProcessingAlreadyDownloadedBlocksInFullSync() { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - LargeDistanceBehindHead); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)LargeDistanceBehindHead); SyncProgressResolver.FindBestProcessedBlock().Returns(ChainHead.Number - LargeDistanceBehindHead); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns(ChainHead.TotalDifficulty ?? 0); @@ -265,9 +265,9 @@ public ScenarioBuilder IfTheNodeDoesNotFinishStateSync() () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns(ChainHead.TotalDifficulty ?? 0); return "fully syncing"; @@ -283,8 +283,8 @@ public ScenarioBuilder IfPeersMovedForwardBeforeThisNodeProcessedFirstFullBlock( { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - 2); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - 2UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.None); SyncProgressResolver.ChainDifficulty.Returns((ChainHead.TotalDifficulty ?? 0) + (UInt256)2); return "fully syncing"; @@ -299,9 +299,9 @@ public ScenarioBuilder IfThisNodeIsInTheMiddleOfFastSyncAndFastBlocks(FastBlocks () => { SyncProgressResolver.FindBestHeader().Returns(Pivot.Number + 16); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "mid fast sync and fast blocks"; @@ -316,9 +316,9 @@ public ScenarioBuilder IfThisNodeFinishedFastBlocksButNotFastSync() () => { SyncProgressResolver.FindBestHeader().Returns(Pivot.Number + 16); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "mid fast sync"; @@ -334,7 +334,7 @@ public ScenarioBuilder IfThisNodeHasBeenOfflineForLongTime() { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - LargeDistanceBehindHead); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)LargeDistanceBehindHead); SyncProgressResolver.FindBestProcessedBlock().Returns(ChainHead.Number - LargeDistanceBehindHead); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); @@ -350,9 +350,9 @@ public ScenarioBuilder ThisNodeFinishedFastSyncButNotFastBlocks() () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.None); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "mid fast blocks but fast sync finished"; @@ -367,9 +367,9 @@ public ScenarioBuilder IfThisNodeFinishedStateSyncButNotFastBlocks(FastBlocksSta () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)FastSyncLag); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "just finished state sync but not fast blocks"; @@ -384,9 +384,9 @@ public ScenarioBuilder IfThisNodeJustFinishedStateSyncAndFastBlocks(FastBlocksSt () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)FastSyncLag); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "just finished state sync and fast blocks"; @@ -402,8 +402,8 @@ public ScenarioBuilder IfThisNodeJustFinishedStateSyncCatchUp() { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - FastSyncLag); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)FastSyncLag); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "just finished state sync catch up"; @@ -412,17 +412,17 @@ public ScenarioBuilder IfThisNodeJustFinishedStateSyncCatchUp() return this; } - public ScenarioBuilder IfThisNodeJustFinishedFastBlocksAndFastSync(FastBlocksState fastBlocksState = FastBlocksState.FinishedBlockAccessLists, bool stateFinished = false, long? bestHeader = null) + public ScenarioBuilder IfThisNodeJustFinishedFastBlocksAndFastSync(FastBlocksState fastBlocksState = FastBlocksState.FinishedBlockAccessLists, bool stateFinished = false, ulong? bestHeader = null) { _syncProgressSetups.Add( () => { - bestHeader ??= ChainHead.Number - FastSyncLag; + bestHeader ??= (ChainHead.Number - (ulong)FastSyncLag); SyncProgressResolver.FindBestHeader().Returns(bestHeader.Value); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(stateFinished ? bestHeader.Value : 0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(stateFinished ? (ulong)bestHeader.Value : 0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "just after fast blocks and fast sync"; @@ -433,14 +433,14 @@ public ScenarioBuilder IfThisNodeJustFinishedFastBlocksAndFastSync(FastBlocksSta public ScenarioBuilder IfThisNodeJustStartedFullSyncProcessing(FastBlocksState fastBlocksState = FastBlocksState.FinishedBlockAccessLists) { - long currentBlock = ChainHead.Number - FastSyncLag + 1; + ulong currentBlock = ChainHead.Number - FastSyncLag + 1; _syncProgressSetups.Add( () => { SyncProgressResolver.FindBestHeader().Returns(currentBlock); SyncProgressResolver.FindBestFullBlock().Returns(currentBlock); - SyncProgressResolver.FindBestFullState().Returns(currentBlock); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullState().Returns((ulong)currentBlock); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns((UInt256)currentBlock); return "just started full sync"; @@ -451,14 +451,14 @@ public ScenarioBuilder IfThisNodeJustStartedFullSyncProcessing(FastBlocksState f public ScenarioBuilder IfThisNodeJustFinishedStateSyncButBehindHeader(FastBlocksState fastBlocksState = FastBlocksState.FinishedBlockAccessLists) { - long currentBlock = ChainHead.Number - FastSyncLag; + ulong currentBlock = ChainHead.Number - FastSyncLag; _syncProgressSetups.Add( () => { SyncProgressResolver.FindBestHeader().Returns(currentBlock); - SyncProgressResolver.FindBestFullBlock().Returns(0); //no full blocks available - SyncProgressResolver.FindBestFullState().Returns(currentBlock - 4); //pivot is set to header, but then header follows the head of the chain - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); //no full blocks available + SyncProgressResolver.FindBestFullState().Returns((ulong)(currentBlock - 4)); //pivot is set to header, but then header follows the head of the chain + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns((UInt256)currentBlock); return "just started full sync"; @@ -469,13 +469,13 @@ public ScenarioBuilder IfThisNodeJustFinishedStateSyncButBehindHeader(FastBlocks public ScenarioBuilder IfThisNodeRecentlyStartedFullSyncProcessing(FastBlocksState fastBlocksState = FastBlocksState.FinishedBlockAccessLists) { - long currentBlock = ChainHead.Number - FastSyncLag / 2; + ulong currentBlock = ChainHead.Number - FastSyncLag / 2; _syncProgressSetups.Add( () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(currentBlock); + SyncProgressResolver.FindBestFullState().Returns((ulong)currentBlock); SyncProgressResolver.FindBestProcessedBlock().Returns(currentBlock); SyncProgressResolver.IsFastBlocksFinished().Returns(fastBlocksState); SyncProgressResolver.ChainDifficulty.Returns((UInt256)currentBlock); @@ -497,7 +497,7 @@ public ScenarioBuilder IfThisNodeRecentlyStartedFullSyncProcessingOnEmptyCliqueC { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - FastSyncLag + 1); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - (ulong)FastSyncLag + 1UL); SyncProgressResolver.FindBestProcessedBlock().Returns(ChainHead.Number - FastSyncLag); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns((UInt256)ChainHead.Number - FastSyncLag); @@ -511,13 +511,13 @@ public ScenarioBuilder IfThisNodeHasStateThatIsFarInThePast() { // this is a scenario when we actually have state but the lookup depth is limiting // our ability to find out at what level the state is - long currentBlock = ChainHead.Number - LargeDistanceBehindHead; + ulong currentBlock = ChainHead.Number - LargeDistanceBehindHead; _syncProgressSetups.Add( () => { SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(0); + SyncProgressResolver.FindBestFullState().Returns(0UL); SyncProgressResolver.FindBestProcessedBlock().Returns(currentBlock); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns((UInt256)currentBlock); @@ -535,7 +535,7 @@ public ScenarioBuilder IfTheSyncProgressIsCorrupted() SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number); SyncProgressResolver.FindBestFullBlock().Returns(ChainHead.Number); - SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - 1); + SyncProgressResolver.FindBestFullState().Returns(ChainHead.Number - 1UL); SyncProgressResolver.FindBestProcessedBlock().Returns(ChainHead.Number); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.FinishedBlockAccessLists); SyncProgressResolver.ChainDifficulty.Returns((UInt256)ChainHead.Number); @@ -551,7 +551,7 @@ public ScenarioBuilder WhenHeaderIsFarFromHead() _syncProgressSetups.Add( () => { - SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number - 1000); + SyncProgressResolver.FindBestHeader().Returns(ChainHead.Number - 1000UL); return "header is far from the HEAD"; } ); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/PeerInfoAllocationTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/PeerInfoAllocationTests.cs index cf003dc17ecc..3e11841fd957 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/PeerInfoAllocationTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/PeerInfoAllocationTests.cs @@ -113,13 +113,13 @@ private static ArrayPoolList BuildHeaders(int start, int end) ArrayPoolList headers = new(end - start + 1); for (int number = start; number <= end; number++) { - headers.Add(Build.A.BlockHeader.WithNumber(number).TestObject); + headers.Add(Build.A.BlockHeader.WithNumber((ulong)number).TestObject); } return headers; } - private static PeerInfo SetupPeerInfo(string versionString, long headNumber, byte protocolVersion, int port) + private static PeerInfo SetupPeerInfo(string versionString, ulong headNumber, byte protocolVersion, int port) { ISyncPeer peer = SetupSyncPeer(versionString); peer.Node.Returns(new Node(Build.A.PrivateKey.TestObject.PublicKey, "127.0.0.1", port)); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ReceiptSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ReceiptSyncFeedTests.cs index 4f05e44c5742..2ef2fc0bd1b5 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ReceiptSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ReceiptSyncFeedTests.cs @@ -51,7 +51,7 @@ public void Setup() _syncingToBlockTree = Build.A.BlockTree() .TestObject; - for (int i = 1; i < 100; i++) + for (ulong i = 1; i < 100; i++) { Block block = _syncingFromBlockTree.FindBlock(i, BlockTreeLookupOptions.None)!; _syncingToBlockTree.Insert(block.Header); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs index 4ccbc4ae4030..a55aaa85ade0 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs @@ -27,23 +27,23 @@ int syncPivot ) { IBlockTree blockTree = Substitute.For(); - blockTree.FindHeader(Arg.Any()) - .Returns(static (ci) => Build.A.BlockHeader.WithNumber((long)ci[0]).TestObject); + blockTree.FindHeader(Arg.Any()) + .Returns(static (ci) => Build.A.BlockHeader.WithNumber((ulong)ci[0]).TestObject); Synchronization.FastSync.StateSyncPivot stateSyncPivot = new(blockTree, new TestSyncConfig() { - PivotNumber = syncPivot, + PivotNumber = (ulong)syncPivot, FastSync = true, StateMinDistanceFromHead = minDistance, StateMaxDistanceFromHead = maxDistance, }, LimboLogs.Instance); - blockTree.SyncPivot = (syncPivot, Keccak.Zero); + blockTree.SyncPivot = ((ulong)syncPivot, Keccak.Zero); - blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber(originalBestSuggested).TestObject); + blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber((ulong)originalBestSuggested).TestObject); Assert.That(stateSyncPivot.GetPivotHeader(), Is.Not.Null); - blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber(newBestSuggested).TestObject); - Assert.That(stateSyncPivot.GetPivotHeader()?.Number, Is.EqualTo(newPivotHeader)); + blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber((ulong)newBestSuggested).TestObject); + Assert.That(stateSyncPivot.GetPivotHeader()?.Number, Is.EqualTo((ulong)newPivotHeader)); } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncPeerPoolTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncPeerPoolTests.cs index ccaad9c57198..e4d42d85a972 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncPeerPoolTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncPeerPoolTests.cs @@ -54,7 +54,7 @@ private class SimpleSyncPeerMock(PublicKey publicKey, string description = "simp public string ProtocolCode { get; } = null!; public Node Node { get; } = new Node(publicKey, "127.0.0.1", 30303); public string ClientId { get; } = description; - public long HeadNumber { get; set; } + public ulong HeadNumber { get; set; } public UInt256? TotalDifficulty { get; set; } = 1; public bool IsInitialized { get; set; } public bool IsPriority { get; set; } @@ -67,7 +67,7 @@ public void Disconnect(DisconnectReason reason, string details) => public Task GetBlockBodies(IReadOnlyList blockHashes, CancellationToken token) => Task.FromResult(new OwnedBlockBodies([])); - public Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) => + public Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) => Task.FromResult?>(ArrayPoolList.Empty()); public Task?> GetBlockHeaders(Hash256 startHash, int maxBlocks, int skip, CancellationToken token) => diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncPeersReportTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncPeersReportTest.cs index 6897333d48a0..e3581d3c2dc3 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncPeersReportTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncPeersReportTest.cs @@ -94,7 +94,7 @@ private static PeerInfo BuildPeer( string ip = "127.0.0.1", int port = 3030, ConnectionDirection direction = ConnectionDirection.Out, - int head = 9999, + ulong head = 9999, string protocolVersion = "eth99" ) { @@ -108,7 +108,7 @@ private static (PeerInfo, StubSyncPeer) BuildPeerWithStubSyncPeer( string ip = "127.0.0.1", int port = 3030, ConnectionDirection direction = ConnectionDirection.Out, - int head = 9999, + ulong head = 9999, string protocolVersion = "eth99" ) { diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncProgressResolverTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncProgressResolverTests.cs index f96bbf37536f..ecc0091b4665 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncProgressResolverTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncProgressResolverTests.cs @@ -56,9 +56,9 @@ public void Best_state_is_head_when_there_are_no_suggested_blocks() Assert.That(syncProgressResolver.FindBestFullState(), Is.EqualTo(head.Number)); } - [TestCase(true, 6)] - [TestCase(false, 5)] - public void Best_state_depends_on_whether_suggested_block_has_state(bool suggestedHasState, long expectedNumber) + [TestCase(true, 6UL)] + [TestCase(false, 5UL)] + public void Best_state_depends_on_whether_suggested_block_has_state(bool suggestedHasState, ulong expectedNumber) { SyncProgressResolver syncProgressResolver = CreateProgressResolver(false, new SyncConfig { PivotNumber = 1 }); Block head = Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(5).WithStateRoot(TestItem.KeccakA).TestObject).TestObject; @@ -90,7 +90,7 @@ public void Is_fast_block_bodies_finished_returns_false_when_blocks_not_download DownloadReceiptsInFastSync = true, PivotNumber = 1, }; - _blockTree.SyncPivot.Returns((1, Hash256.Zero)); + _blockTree.SyncPivot.Returns((1UL, Hash256.Zero)); _blockTree.LowestInsertedHeader.Returns(Build.A.BlockHeader.WithNumber(1).WithStateRoot(TestItem.KeccakA).TestObject); SyncProgressResolver syncProgressResolver = CreateProgressResolver(false, syncConfig); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncServerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncServerTests.cs index 44eeb51beb96..5be57c7930ab 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncServerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncServerTests.cs @@ -54,7 +54,7 @@ public void When_finding_hash_it_does_not_load_headers() ctx.BlockTree.FindHash(123).Returns(TestItem.KeccakA); Hash256 result = ctx.SyncServer.FindHash(123)!; - ctx.BlockTree.DidNotReceive().FindHeader(Arg.Any(), Arg.Any()); + ctx.BlockTree.DidNotReceive().FindHeader(Arg.Any(), Arg.Any()); ctx.BlockTree.DidNotReceive().FindHeader(Arg.Any(), Arg.Any()); ctx.BlockTree.DidNotReceive().FindBlock(Arg.Any(), Arg.Any()); Assert.That(result, Is.EqualTo(TestItem.KeccakA)); @@ -567,7 +567,7 @@ public void Broadcast_BlockRangeUpdate_when_latest_increased_enough() localBlockTree.AddBranch(blocksCount * 2 / 3, splitBlockNumber: startBlock, splitVariant: 0); localBlockTree.AddBranch(blocksCount, splitBlockNumber: startBlock, splitVariant: 0); - (long earliest, int latest)[] expectedUpdates = Enumerable.Range(startBlock + 1, blocksCount) + (ulong earliest, int latest)[] expectedUpdates = Enumerable.Range(startBlock + 1, blocksCount) .Where(x => x % frequency == 0) .Select(x => (earliest: localBlockTree.Genesis!.Number, latest: x)) .ToArray()[^2..]; @@ -577,7 +577,7 @@ public void Broadcast_BlockRangeUpdate_when_latest_increased_enough() Assert.That( () => { - (long earliest, long latest)[] arr = peerInfo.SyncPeer.ReceivedCalls() + (ulong earliest, ulong latest)[] arr = peerInfo.SyncPeer.ReceivedCalls() .Where(c => c.GetMethodInfo().Name == nameof(ISyncPeer.NotifyOfNewRange)) .Select(c => c.GetArguments().Cast().Select(b => b.Number).ToArray()) .Select(a => (earliest: a[0], latest: a[1])).ToArray(); @@ -637,7 +637,7 @@ public void GetNodeData_returns_cached_trie_nodes() public void Correctly_clips_lowestBlock() { Context ctx = new(); - ctx.BlockTree.GetLowestBlock().Returns(5); + ctx.BlockTree.GetLowestBlock().Returns(5UL); Assert.That(ctx.SyncServer.LowestBlock, Is.EqualTo(0)); } @@ -709,7 +709,7 @@ public void GetBlockAccessListRlp_returns_expected_value( } else { - blockAccessListStore.DidNotReceive().GetRlp(Arg.Any(), Arg.Any()); + blockAccessListStore.DidNotReceive().GetRlp(Arg.Any(), Arg.Any()); } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index dc00f8ec6f79..b7cab0de8c8c 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -118,7 +118,7 @@ public override Task GetBlockBodies(IReadOnlyList blo return Task.FromResult(new OwnedBlockBodies(result)); } - public override Task?> GetBlockHeaders(long number, int maxBlocks, int skip, CancellationToken token) + public override Task?> GetBlockHeaders(ulong number, int maxBlocks, int skip, CancellationToken token) { if (_causeTimeoutOnHeaders) { @@ -189,7 +189,7 @@ public override void SendNewTransactions(IEnumerable txs, bool send public void AddBlocksUpTo(int i, int branchStart = 0, byte branchIndex = 0) { Block block = Blocks.Last(); - for (long j = block.Number; j < i; j++) + for (long j = (long)block.Number; j < i; j++) { block = Build.A.Block.WithDifficulty(1000000).WithParent(block) .WithTotalDifficulty(block.TotalDifficulty + 1000000) @@ -203,7 +203,7 @@ public void AddBlocksUpTo(int i, int branchStart = 0, byte branchIndex = 0) public void AddHighDifficultyBlocksUpTo(int i, int branchStart = 0, byte branchIndex = 0) { Block block = Blocks.Last(); - for (long j = block.Number; j < i; j++) + for (long j = (long)block.Number; j < i; j++) { block = Build.A.Block.WithParent(block).WithDifficulty(2000000) .WithTotalDifficulty(block.TotalDifficulty + 2000000) @@ -432,7 +432,7 @@ public SyncingContext AfterPeerIsRemoved(ISyncPeer syncPeer) public SyncingContext AfterNewBlockMessage(Block block, ISyncPeer peer) { _logger.Info($"NEW BLOCK MESSAGE {block.Number}"); - block.Header.TotalDifficulty = block.Difficulty * (ulong)(block.Number + 1); + block.Header.TotalDifficulty = block.Difficulty * (block.Number + 1); SyncServer.AddNewBlock(block, peer); return this; } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/TotalDifficultyBasedBetterPeerStrategyTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/TotalDifficultyBasedBetterPeerStrategyTests.cs index 2827b66809f3..9cdcbcc9c965 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/TotalDifficultyBasedBetterPeerStrategyTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/TotalDifficultyBasedBetterPeerStrategyTests.cs @@ -21,7 +21,7 @@ public void Compare_with_header_and_peer_return_expected_results(long td, int ex { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)10); - syncPeer.HeadNumber.Returns(10); + syncPeer.HeadNumber.Returns(10UL); BlockHeader header = Build.A.BlockHeader.WithTotalDifficulty(td).TestObject; TotalDifficultyBetterPeerStrategy betterPeerStrategy = new(LimboLogs.Instance); @@ -35,7 +35,7 @@ public void Compare_with_value_and_peer_return_expected_results(long td, int exp { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)10); - syncPeer.HeadNumber.Returns(10); + syncPeer.HeadNumber.Returns(10UL); TotalDifficultyBetterPeerStrategy betterPeerStrategy = new(LimboLogs.Instance); Assert.That(betterPeerStrategy.Compare(((UInt256)td, 10), syncPeer), Is.EqualTo(expectedResult)); @@ -59,11 +59,11 @@ public void IsBetterThanLocalChain_return_expected_results(long td, bool expecte Assert.That(betterPeerStrategy.IsBetterThanLocalChain(((UInt256)td, 10), ((UInt256)10, 10)), Is.EqualTo(expectedResult)); } - [TestCase(3, 4, 5, 2, true)] - [TestCase(3, 2, 3, 4, true)] - [TestCase(4, 2, 3, 4, false)] - [TestCase(3, 4, 3, 2, false)] - public void IsDesiredPeer_return_expected_results(long chainDifficulty, long bestHeader, long peerTotalDifficulty, long peerNumber, bool expectedResult) + [TestCase(3, 4UL, 5, 2UL, true)] + [TestCase(3, 2UL, 3, 4UL, true)] + [TestCase(4, 2UL, 3, 4UL, false)] + [TestCase(3, 4UL, 3, 2UL, false)] + public void IsDesiredPeer_return_expected_results(long chainDifficulty, ulong bestHeader, long peerTotalDifficulty, ulong peerNumber, bool expectedResult) { ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns((UInt256)peerTotalDifficulty); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs index e5dd0abf2203..d0a1bc989725 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs @@ -157,10 +157,10 @@ BlockHeader FillStorage(IContainer server) using IDisposable _ = mainWorldState.BeginScope(blockTree.Head?.Header); - for (int i = 0; i < 100; i++) + for (ulong i = 0; i < 100; i++) { Address address = new(Keccak.Compute(i.ToString())); - mainWorldState.CreateAccount(address, (UInt256)i, (UInt256)i); + mainWorldState.CreateAccount(address, (UInt256)i, i); } Address storageAddress = new(Keccak.Compute("storage")); @@ -209,16 +209,16 @@ void AssertStorage(IContainer client) IWorldState mainWorldState = client.Resolve().WorldState; using IDisposable _ = mainWorldState.BeginScope(baseBlock); - for (int i = 0; i < 100; i++) + for (ulong i = 0; i < 100; i++) { Address address = new(Keccak.Compute(i.ToString())); Assert.That(mainWorldState.GetBalance(address), Is.EqualTo((UInt256)i)); - Assert.That(mainWorldState.GetNonce(address), Is.EqualTo((UInt256)i)); + Assert.That(mainWorldState.GetNonce(address), Is.EqualTo(i)); } Address storageAddress = new(Keccak.Compute("storage")); Assert.That(mainWorldState.GetBalance(storageAddress), Is.EqualTo((UInt256)100)); - Assert.That(mainWorldState.GetNonce(storageAddress), Is.EqualTo((UInt256)100)); + Assert.That(mainWorldState.GetNonce(storageAddress), Is.EqualTo((ulong)100)); for (int i = 1; i < 100; i++) { Assert.That(mainWorldState.Get(new StorageCell(storageAddress, (UInt256)i)).ToArray(), Is.EqualTo(i.ToBigEndianByteArray())); diff --git a/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs b/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs index d21061004d6e..3c8a230e1031 100644 --- a/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs +++ b/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs @@ -12,18 +12,19 @@ public static class BetterPeerStrategyExtensions public static int Compare(this IBetterPeerStrategy peerStrategy, BlockHeader? header, ISyncPeer? peerInfo) { UInt256? headerDifficulty = header?.TotalDifficulty; - long headerNumber = header?.Number ?? 0; + ulong headerNumber = header?.Number ?? 0UL; UInt256? peerDifficulty = peerInfo?.TotalDifficulty; - long peerInfoHeadNumber = peerInfo?.HeadNumber ?? 0; + ulong peerInfoHeadNumber = peerInfo?.HeadNumber ?? 0UL; return peerStrategy.Compare((headerDifficulty, headerNumber), (peerDifficulty, peerInfoHeadNumber)); } - public static int Compare(this IBetterPeerStrategy peerStrategy, (UInt256 TotalDifficulty, long Number) value, ISyncPeer? peerInfo) + public static int Compare(this IBetterPeerStrategy peerStrategy, (UInt256 TotalDifficulty, ulong Number) value, ISyncPeer? peerInfo) { UInt256? peerDifficulty = peerInfo?.TotalDifficulty; - long peerInfoHeadNumber = peerInfo?.HeadNumber ?? 0; + // ISyncPeer.HeadNumber is ulong; cast to long is safe for realistic chain heights. + ulong peerInfoHeadNumber = peerInfo?.HeadNumber ?? 0UL; return peerStrategy.Compare(value, (peerDifficulty, peerInfoHeadNumber)); } } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs index f60ec64fe6ac..8af652633cd5 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs @@ -114,7 +114,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) } _syncReport.FullSyncBlocksDownloaded.TargetValue = Math.Max(_syncReport.FullSyncBlocksDownloaded.TargetValue, e.Block.Number); - _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0); + _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0UL); } public async Task PrepareRequest(DownloaderOptions options, int fastSyncLag, CancellationToken cancellation) @@ -141,8 +141,8 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) bool originalShouldProcess = (options & DownloaderOptions.Process) == DownloaderOptions.Process; int blocksSynced = 0; - long bestProcessedBlock = 0; - long previousStartingHeaderNumber = -1; + ulong bestProcessedBlock = 0; + ulong? previousStartingHeaderNumber = null; while (true) { @@ -198,7 +198,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) } else { - if (_logger.IsDebug) _logger.Debug($"Processing {satisfiedEntry.Count} entries from {satisfiedEntry[0]?.Header.Number ?? -1} to {satisfiedEntry[^1]?.Header.Number ?? -1}"); + if (_logger.IsDebug) _logger.Debug($"Processing {satisfiedEntry.Count} entries from {satisfiedEntry[0]?.Header.Number ?? ulong.MaxValue} to {satisfiedEntry[^1]?.Header.Number ?? ulong.MaxValue}"); } for (int blockIndex = 0; blockIndex < satisfiedEntry.Count; blockIndex++) @@ -247,7 +247,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) if (blocksSynced > 0) { - _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0); + _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0UL); } _syncReport.FullSyncBlocksDownloaded.CurrentQueued = _downloadRequests.Count; @@ -675,14 +675,14 @@ private bool SuggestBlock( } private (bool shouldProcess, bool shouldDownloadReceipt) ReceiptEdgeCase( - long bestProcessedBlock, - long firstBlockNumber, + ulong bestProcessedBlock, + ulong firstBlockNumber, bool shouldProcess, bool shouldDownloadReceipt) { if (shouldProcess && !shouldDownloadReceipt) { - long firstBlock = firstBlockNumber; + ulong firstBlock = firstBlockNumber; // TODO: Double check this condition // An edge case where we already have the state but are still downloading preceding blocks. // We cannot process such blocks, but we are still requested to process them via blocksRequest.Options. @@ -692,7 +692,7 @@ private bool SuggestBlock( bool isFastSyncTransition = headIsGenesis && toBeProcessedHasNoProcessedParent; if (isFastSyncTransition) { - long bestFullState = _fullStateFinder.FindBestFullState(); + ulong bestFullState = (ulong)_fullStateFinder.FindBestFullState(); shouldProcess = firstBlock > bestFullState && bestFullState != 0; if (!shouldProcess) { diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs index 7dd8029f6bd5..f11c05f7e754 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs @@ -54,7 +54,7 @@ public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPe if (_minBlocksAhead is not null) { - if (info.HeadNumber < (blockTree.BestSuggestedHeader?.Number ?? 0) + _minBlocksAhead) + if (info.HeadNumber < (blockTree.BestSuggestedHeader?.Number ?? 0UL) + (ulong)_minBlocksAhead) { // we need to be able to download some blocks ahead continue; @@ -118,15 +118,15 @@ public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPe } else // by last block otherwise { - long bestPeerNumber = bestDiffPeer.Info.HeadNumber; - long localNumber = blockTree.Head?.Number ?? 0; - long blockDifference = bestPeerNumber > localNumber + ulong bestPeerNumber = bestDiffPeer.Info.HeadNumber; + ulong localNumber = blockTree.Head?.Number ?? 0UL; + ulong blockDifference = bestPeerNumber > localNumber ? bestPeerNumber - localNumber - : 0; + : 0UL; // at least 16 blocks if (blockDifference > 0 - && (blockDifference >= localNumber + minBlocksDiff + && (blockDifference >= localNumber + (ulong)minBlocksDiff || bestDiffPeer.TransferSpeed > averageSpeed)) { return bestDiffPeer.Info; diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs index fe25af78c621..81f87bf68862 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs @@ -33,7 +33,7 @@ ILogManager logManager private ILogger _logger = logManager.GetClassLogger(); private readonly int[] _ancestorJumps = { 1, 2, 3, 8, 16, 32, 64, 128, 256, 384, 512, 640, 768, 896, 1024 }; private int _ancestorLookupLevel; - private long _currentNumber; + private ulong _currentNumber; private readonly Random _rnd = new(); private readonly Guid _sealValidatorUserGuid = Guid.NewGuid(); @@ -97,7 +97,7 @@ private IOwnedReadOnlyList? LastResponseBatch IOwnedReadOnlyList? lastResponseBatch = LastResponseBatch; if (lastResponseBatch is null) return null; - long currentNumber = _currentNumber; + ulong currentNumber = _currentNumber; bool sameFound = false; ArrayPoolList? newResponse = null; ReadOnlySpan lastResponseBatchSpan = lastResponseBatch.AsSpan(); @@ -131,7 +131,9 @@ private void OnNewBestPeer(PeerInfo newBestPeer) // TODO: Is there a (fast) way to know if the new peer's head has the parent of last peer? _ancestorLookupLevel = 0; - _currentNumber = Math.Max(0, Math.Min(blockTree.BestKnownNumber, newBestPeer.HeadNumber - 1)); // Remember, _currentNumber is -1 than what we want. + ulong bestKnown = blockTree.BestKnownNumber; + ulong headNum = newBestPeer.HeadNumber; + _currentNumber = Math.Max(0UL, Math.Min(bestKnown, headNum > 0 ? headNum - 1 : 0)); // Remember, _currentNumber is -1 than what we want. _currentBestPeer = newBestPeer; } @@ -144,9 +146,13 @@ private void OnNewBestPeer(PeerInfo newBestPeer) if (_logger.IsDebug) _logger.Debug($"Continue full sync with {bestPeer} (our best {blockTree.BestKnownNumber})"); - long upperDownloadBoundary = bestPeer.HeadNumber - skipLastN; - long blocksLeft = upperDownloadBoundary - _currentNumber; - int headersToRequest = (int)Math.Min(blocksLeft + 1, maxHeaders); + ulong upperDownloadBoundary = bestPeer.HeadNumber > (ulong)skipLastN ? bestPeer.HeadNumber - (ulong)skipLastN : 0; + if (_currentNumber > upperDownloadBoundary) + { + return null; + } + ulong blocksLeft = upperDownloadBoundary - _currentNumber; + int headersToRequest = (int)Math.Min(blocksLeft + 1, (ulong)maxHeaders); if (headersToRequest <= 1) { return null; @@ -199,7 +205,7 @@ private void OnNewBestPeer(PeerInfo newBestPeer) public virtual void OnSuggestBlock(BlockTreeSuggestOptions options, Block currentBlock, AddBlockResult addResult) => _currentNumber += 1; - private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, ref long currentNumber) + private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, ref ulong currentNumber) { bool parentIsKnown = blockTree.IsKnownBlock(blockBeforeZero.Number, blockBeforeZero.Hash!); if (!parentIsKnown) @@ -212,17 +218,19 @@ private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, r } int ancestorJump = _ancestorJumps[_ancestorLookupLevel] - _ancestorJumps[_ancestorLookupLevel - 1]; - currentNumber = currentNumber >= ancestorJump ? (currentNumber - ancestorJump) : 0L; - currentNumber = Math.Max((blockTree.BestSuggestedHeader?.Number ?? 0) - MaxReorganizationLength, currentNumber); + currentNumber = currentNumber >= (ulong)ancestorJump ? (currentNumber - (ulong)ancestorJump) : 0UL; + ulong bestSuggestedNumber = blockTree.BestSuggestedHeader?.Number ?? 0UL; + ulong minAllowed = bestSuggestedNumber > MaxReorganizationLength ? bestSuggestedNumber - MaxReorganizationLength : 0; + currentNumber = Math.Max(minAllowed, currentNumber); return false; } _ancestorLookupLevel = 0; return true; } - private async Task> RequestHeaders(PeerInfo peer, CancellationToken cancellation, long currentNumber, int headersToRequest) + private async Task> RequestHeaders(PeerInfo peer, CancellationToken cancellation, ulong currentNumber, int headersToRequest) { - sealValidator.HintValidationRange(_sealValidatorUserGuid, currentNumber - 1028, currentNumber + 30000); + sealValidator.HintValidationRange(_sealValidatorUserGuid, (long)currentNumber - 1028, (long)currentNumber + 30000); IOwnedReadOnlyList headers = await peer.SyncPeer.GetBlockHeaders(currentNumber, headersToRequest, 0, cancellation); cancellation.ThrowIfCancellationRequested(); diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BarrierSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BarrierSyncFeed.cs index c4ca78d8230b..ea778be38557 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BarrierSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BarrierSyncFeed.cs @@ -13,16 +13,16 @@ namespace Nethermind.Synchronization.FastBlocks; public abstract class BarrierSyncFeed(IDb metadataDb, ISpecProvider specProvider, ILogger logger) : ActivatedSyncFeed { - protected abstract long? LowestInsertedNumber { get; } + protected abstract ulong? LowestInsertedNumber { get; } protected abstract int BarrierWhenStartedMetadataDbKey { get; } - protected abstract long SyncConfigBarrierCalc { get; } + protected abstract ulong SyncConfigBarrierCalc { get; } protected abstract Func HasPivot { get; } protected readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); protected readonly ILogger _logger = logger; - protected long _barrier; - protected long _pivotNumber; - protected long? _barrierWhenStarted; + protected ulong _barrier; + protected ulong _pivotNumber; + protected ulong? _barrierWhenStarted; protected readonly IDb _metadataDb = metadataDb ?? throw new ArgumentNullException(nameof(metadataDb)); @@ -31,16 +31,16 @@ public void InitializeMetadataDb() if (!HasPivot()) { _barrierWhenStarted = SyncConfigBarrierCalc; - _metadataDb.Set(BarrierWhenStartedMetadataDbKey, _barrierWhenStarted.Value.ToBigEndianByteArrayWithoutLeadingZeros()); + _metadataDb.Set(BarrierWhenStartedMetadataDbKey, ((long)_barrierWhenStarted.Value).ToBigEndianByteArrayWithoutLeadingZeros()); } else if (_metadataDb.KeyExists(BarrierWhenStartedMetadataDbKey)) { - _barrierWhenStarted = _metadataDb.Get(BarrierWhenStartedMetadataDbKey).ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + _barrierWhenStarted = (ulong)_metadataDb.Get(BarrierWhenStartedMetadataDbKey).ToLongFromBigEndianByteArrayWithoutLeadingZeros(); } else { _barrierWhenStarted = _barrier; - _metadataDb.Set(BarrierWhenStartedMetadataDbKey, _barrierWhenStarted.Value.ToBigEndianByteArrayWithoutLeadingZeros()); + _metadataDb.Set(BarrierWhenStartedMetadataDbKey, ((long)_barrierWhenStarted.Value).ToBigEndianByteArrayWithoutLeadingZeros()); } } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncBatch.cs index 2983883d0e2b..45023fb61937 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncBatch.cs @@ -17,5 +17,5 @@ public override void Dispose() Response?.Dispose(); } - public override long? MinNumber => Infos[0]?.BlockNumber; + public override ulong? MinNumber => Infos[0]?.BlockNumber; } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs index c21634672e91..1cba4d823020 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs @@ -27,13 +27,14 @@ namespace Nethermind.Synchronization.FastBlocks; public class BlockAccessListsSyncFeed : BarrierSyncFeed { - protected override long? LowestInsertedNumber => _syncPointers.LowestInsertedBlockAccessListBlockNumber; + protected override ulong? LowestInsertedNumber => _syncPointers.LowestInsertedBlockAccessListBlockNumber; protected override int BarrierWhenStartedMetadataDbKey => MetadataDbKeys.BlockAccessListsBarrierWhenStarted; - protected override long SyncConfigBarrierCalc => _syncConfig.AncientBlockAccessListsBarrierCalc; + protected override ulong SyncConfigBarrierCalc => (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc; protected override Func HasPivot => () => { - (long pivotNumber, Hash256 pivotHash) = _blockTree.SyncPivot; + // SyncPivot.BlockNumber is ulong. + (ulong pivotNumber, Hash256 pivotHash) = _blockTree.SyncPivot; BlockHeader? pivotHeader = _blockTree.FindHeader(pivotHash, blockNumber: pivotNumber); return pivotHeader is not null && (pivotHeader.BlockAccessListHash is null || _blockAccessListStore.Exists(pivotNumber, pivotHash)); @@ -52,7 +53,7 @@ public class BlockAccessListsSyncFeed : BarrierSyncFeed !_syncConfig.DownloadBlockAccessListsInFastSync || AllDownloaded; - private bool AllDownloaded => (_syncPointers.LowestInsertedBlockAccessListBlockNumber ?? long.MaxValue) <= _barrier; + private bool AllDownloaded => (_syncPointers.LowestInsertedBlockAccessListBlockNumber ?? ulong.MaxValue) <= _barrier; public override bool IsFinished => AllDownloaded; public override string FeedName => nameof(BlockAccessListsSyncFeed); @@ -82,21 +83,21 @@ public BlockAccessListsSyncFeed( throw new InvalidOperationException("Entered fast blocks mode without fast blocks enabled in configuration."); } - _pivotNumber = -1; // First reset in `InitializeFeed`. + _pivotNumber = 0; // First reset in `InitializeFeed`. } public override void InitializeFeed() { - if (_pivotNumber != _blockTree.SyncPivot.BlockNumber || _barrier != _syncConfig.AncientBlockAccessListsBarrierCalc) + if (_pivotNumber != _blockTree.SyncPivot.BlockNumber || _barrier != (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc) { _pivotNumber = _blockTree.SyncPivot.BlockNumber; - _barrier = _syncConfig.AncientBlockAccessListsBarrierCalc; + _barrier = (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc; if (_logger.IsInfo) _logger.Info($"Changed pivot in block access lists sync. Now using pivot {_pivotNumber} and barrier {_barrier}"); ResetSyncStatusList(); InitializeMetadataDb(); } base.InitializeFeed(); - _syncReport.FastBlockAccessLists.Reset(0, _pivotNumber - _syncConfig.AncientBlockAccessListsBarrierCalc); + _syncReport.FastBlockAccessLists.Reset(0, _pivotNumber - (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc); } private void ResetSyncStatusList() => @@ -104,7 +105,7 @@ private void ResetSyncStatusList() => _blockTree, _pivotNumber, _syncPointers.LowestInsertedBlockAccessListBlockNumber, - _syncConfig.AncientBlockAccessListsBarrier); + (ulong)_syncConfig.AncientBlockAccessListsBarrier); protected override SyncMode ActivationSyncModes { get; } = SyncMode.FastBlockAccessLists & ~SyncMode.FastBlocks; @@ -287,7 +288,7 @@ private void UpdateSyncReport() private class BlockAccessListDownloadStrategy(IBlockTree blockTree, ISyncReport syncReport) : IBlockDownloadStrategy { - private long _lowestQueriedBlockWithAccessLists = long.MaxValue; + private ulong _lowestQueriedBlockWithAccessLists = ulong.MaxValue; public bool ShouldDownloadBlock(BlockInfo info) { @@ -304,10 +305,10 @@ public bool ShouldDownloadBlock(BlockInfo info) if (header.BlockAccessListHash is not null) { - long currentLowest = Interlocked.Read(ref _lowestQueriedBlockWithAccessLists); + ulong currentLowest = Interlocked.Read(ref _lowestQueriedBlockWithAccessLists); while (info.BlockNumber < currentLowest) { - long previousLowest = Interlocked.CompareExchange(ref _lowestQueriedBlockWithAccessLists, info.BlockNumber, currentLowest); + ulong previousLowest = Interlocked.CompareExchange(ref _lowestQueriedBlockWithAccessLists, info.BlockNumber, currentLowest); if (previousLowest == currentLowest) { break; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncBatch.cs index af86e83c72f9..6371ad1f150b 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncBatch.cs @@ -9,7 +9,7 @@ public class BodiesSyncBatch(BlockInfo[] infos) : FastBlocksBatch { public BlockInfo?[] Infos { get; } = infos; public OwnedBlockBodies? Response { get; set; } - public override long? MinNumber => Infos[0].BlockNumber; + public override ulong? MinNumber => Infos[0].BlockNumber; public override void Dispose() { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 10552ac60197..4eb86aae4597 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -24,15 +24,15 @@ namespace Nethermind.Synchronization.FastBlocks { public class BodiesSyncFeed : BarrierSyncFeed { - protected override long? LowestInsertedNumber => _syncPointers.LowestInsertedBodyNumber; + protected override ulong? LowestInsertedNumber => _syncPointers.LowestInsertedBodyNumber; protected override int BarrierWhenStartedMetadataDbKey => MetadataDbKeys.BodiesBarrierWhenStarted; - protected override long SyncConfigBarrierCalc => ComputeBarrier(_blockTree.SyncPivot.BlockNumber); + protected override ulong SyncConfigBarrierCalc => ComputeBarrier(_blockTree.SyncPivot.BlockNumber); - private long ComputeBarrier(long pivotNumber) + private ulong ComputeBarrier(ulong pivotNumber) { - long clamped = Math.Max(1, Math.Min(pivotNumber, _syncConfig.AncientBodiesBarrier)); - long? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; - return cutoffBlockNumber is null ? clamped : long.Max(clamped, cutoffBlockNumber.Value); + ulong clamped = Math.Max(1UL, Math.Min(pivotNumber, (ulong)_syncConfig.AncientBodiesBarrier)); + ulong? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; + return cutoffBlockNumber is null ? clamped : ulong.Max(clamped, cutoffBlockNumber.Value); } protected override Func HasPivot => @@ -56,7 +56,7 @@ private long ComputeBarrier(long pivotNumber) private SyncStatusList _syncStatusList; private bool ShouldFinish => !_syncConfig.DownloadBodiesInFastSync || AllDownloaded; - private bool AllDownloaded => (_syncPointers.LowestInsertedBodyNumber ?? long.MaxValue) <= _barrier; + private bool AllDownloaded => (_syncPointers.LowestInsertedBodyNumber ?? ulong.MaxValue) <= _barrier; public override bool IsFinished => AllDownloaded; public override string FeedName => nameof(BodiesSyncFeed); @@ -92,13 +92,13 @@ public BodiesSyncFeed( throw new InvalidOperationException("Entered fast bodies mode without fast sync enabled in configuration."); } - _pivotNumber = -1; // First reset in `InitializeFeed`. + _pivotNumber = 0; // First reset in `InitializeFeed`. } public override void InitializeFeed() { - long newPivotNumber = _blockTree.SyncPivot.BlockNumber; - long newBarrier = ComputeBarrier(newPivotNumber); + ulong newPivotNumber = _blockTree.SyncPivot.BlockNumber; + ulong newBarrier = ComputeBarrier(newPivotNumber); if (_pivotNumber != newPivotNumber || _barrier != newBarrier) { _pivotNumber = newPivotNumber; @@ -173,7 +173,7 @@ private void PostFinishCleanUp() } if ( - (_syncPointers.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval || + (_syncPointers.LowestInsertedBodyNumber ?? ulong.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > (ulong)_flushDbInterval || _syncStatusList.LowestInsertWithoutGaps <= _barrier // Other state depends on LowestInsertedBodyNumber, so this need to flush or it wont finish ) { @@ -185,7 +185,7 @@ private void PostFinishCleanUp() private void Flush() { - long lowestInsertedAtPoint = _syncStatusList.LowestInsertWithoutGaps; + ulong lowestInsertedAtPoint = _syncStatusList.LowestInsertWithoutGaps; _blocksDb.Flush(); _syncPointers.LowestInsertedBodyNumber = lowestInsertedAtPoint; } @@ -321,8 +321,8 @@ private class BodiesDownloadStrategy(IBlockTree blockTree, ISyncReport syncRepor public bool ShouldDownloadBlock(BlockInfo info) { bool hasBlock = blockTree.HasBlock(info.BlockNumber, info.BlockHash); - long? cutoff = historyPruner?.CutoffBlockNumber; - cutoff = cutoff is null ? null : long.Min(cutoff!.Value, blockTree.SyncPivot.BlockNumber); + ulong? cutoff = historyPruner?.CutoffBlockNumber; + cutoff = cutoff is null ? null : ulong.Min(cutoff!.Value, blockTree.SyncPivot.BlockNumber); bool shouldDownload = !hasBlock && (cutoff is null || info.BlockNumber >= cutoff); if (!shouldDownload) syncReport.FastBlocksBodies.IncrementSkipped(); return shouldDownload; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksAllocationStrategy.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksAllocationStrategy.cs index d59338d78908..2ed2a485f377 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksAllocationStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksAllocationStrategy.cs @@ -10,9 +10,9 @@ namespace Nethermind.Synchronization.FastBlocks { - public class FastBlocksAllocationStrategy(TransferSpeedType speedType, long? minNumber, bool priority) : IPeerAllocationStrategy + public class FastBlocksAllocationStrategy(TransferSpeedType speedType, ulong? minNumber, bool priority) : IPeerAllocationStrategy { - private readonly long? _minNumber = minNumber; + private readonly ulong? _minNumber = minNumber; private readonly bool _priority = priority; private readonly IPeerAllocationStrategy _slowest = new BySpeedStrategy(speedType, false); private readonly IPeerAllocationStrategy _fastest = new BySpeedStrategy(speedType, true); diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksBatch.cs index e55fa0899137..c40a90a979c4 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksBatch.cs @@ -70,7 +70,7 @@ public double? HandlingTime => (_handlingEndTime ?? _stopwatch.ElapsedMilliseconds) - (_handlingStartTime ?? _stopwatch.ElapsedMilliseconds); /// Minimum head number for peer to be allocated - public abstract long? MinNumber { get; } + public abstract ulong? MinNumber { get; } public virtual void Dispose() { } } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs index 58c19a47e255..117ddfa95cdd 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs @@ -8,8 +8,8 @@ namespace Nethermind.Synchronization.FastBlocks { public class HeadersSyncBatch : FastBlocksBatch { - public long StartNumber { get; set; } - public long EndNumber => StartNumber + RequestSize - 1; + public ulong StartNumber { get; set; } + public ulong EndNumber => StartNumber + (ulong)RequestSize - 1; public int RequestSize { get; set; } public long ResponseSizeEstimate { get; private set; } @@ -39,7 +39,7 @@ public override string ToString() return $"HEADERS {details} [{(Prioritized ? "HIGH" : "LOW")}] [times: S:{SchedulingTime:F0}ms|R:{RequestTime:F0}ms|V:{ValidationTime:F0}ms|W:{WaitingTime:F0}ms|H:{HandlingTime:F0}ms|A:{AgeInMs:F0}ms, retries {Retries}] min#: {MinNumber} {ResponseSourcePeer}"; } - public override long? MinNumber => EndNumber; + public override ulong? MinNumber => EndNumber; public override void Dispose() { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs index c2a5e790c252..df9e73936c49 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs @@ -46,8 +46,8 @@ public class HeadersSyncFeed : ActivatedSyncFeed private readonly Lock _handlerLock = new(); private readonly ulong _fastHeadersMemoryBudget; - protected long _lowestRequestedHeaderNumber; - protected long _pivotNumber; + protected ulong _lowestRequestedHeaderNumber; + protected ulong _pivotNumber; protected record NextHeader(Hash256 Hash256, UInt256? TotalDifficulty); protected NextHeader _expectedNextHeader; @@ -65,7 +65,7 @@ protected record NextHeader(Hash256 Hash256, UInt256? TotalDifficulty); /// /// Responses received from peers but waiting in a queue for some other requests to be handled first /// - private readonly NonBlocking.ConcurrentDictionary _dependencies = new(); + private readonly NonBlocking.ConcurrentDictionary _dependencies = new(); // Stop gap method to reduce allocations from non-struct enumerator // https://github.com/dotnet/runtime/pull/38296 @@ -85,10 +85,11 @@ protected virtual BlockHeader? LowestInsertedBlockHeader protected virtual ProgressLogger HeadersSyncProgressLoggerReport => _syncReport.FastBlocksHeaders; - protected virtual long HeadersDestinationNumber => 0; - protected virtual bool AllHeadersDownloaded => (LowestInsertedBlockHeader?.Number ?? long.MaxValue) <= 1; + protected virtual ulong HeadersDestinationNumber => 0; + // LowestInsertedBlockHeader.Number is ulong; compare against 1UL. Use ulong max sentinel. + protected virtual bool AllHeadersDownloaded => (LowestInsertedBlockHeader?.Number ?? ulong.MaxValue) <= 1UL; - protected virtual long TotalBlocks => _blockTree.SyncPivot.BlockNumber; + protected virtual ulong TotalBlocks => _blockTree.SyncPivot.BlockNumber; public override bool IsFinished => AllHeadersDownloaded; public override string FeedName => nameof(HeadersSyncFeed); @@ -112,7 +113,7 @@ private long HeadersInQueue private long CalculateHeadersInQueue() { // Reuse the enumerator - using IEnumerator> enumerator = _dependencies.GetEnumerator(); + using IEnumerator> enumerator = _dependencies.GetEnumerator(); long count = 0; while (enumerator.MoveNext()) @@ -141,7 +142,7 @@ private ulong MemoryInQueue private ulong CalculateMemoryInQueue() { // Reuse the enumerator - using IEnumerator> enumerator = _dependencies.GetEnumerator(); + using IEnumerator> enumerator = _dependencies.GetEnumerator(); ulong amount = 0; while (enumerator.MoveNext()) @@ -196,19 +197,22 @@ public override void InitializeFeed() base.InitializeFeed(); // null lowest header means nothing inserted yet — without this guard the bar would briefly read 100%. - long currentValue = LowestInsertedBlockHeader is null ? 0 : _pivotNumber - LowestInsertedBlockHeader.Number + 1; + // Both _pivotNumber and LowestInsertedBlockHeader.Number are ulong, so the arithmetic is pure ulong + // and no cast is needed when passing to Reset(ulong, ulong). + ulong currentValue = LowestInsertedBlockHeader is null ? 0UL : (_pivotNumber - LowestInsertedBlockHeader.Number + 1); HeadersSyncProgressLoggerReport.Reset(currentValue, TotalBlocks); } protected virtual void ResetPivot() { - (_pivotNumber, Hash256 nextHeaderHash) = _blockTree.SyncPivot; + (ulong pivotNumberUlong, Hash256 nextHeaderHash) = _blockTree.SyncPivot; + _pivotNumber = pivotNumberUlong; _lowestRequestedHeaderNumber = _pivotNumber + 1; // Because we want the pivot to be requested _expectedNextHeader = new NextHeader(nextHeaderHash, TryGetPivotTotalDifficulty(nextHeaderHash)); // Resume logic BlockHeader? lowestInserted = _blockTree.LowestInsertedHeader; - if (lowestInserted is not null && lowestInserted!.Number < _pivotNumber) + if (lowestInserted is not null && lowestInserted.Number < _pivotNumber) { if (lowestInserted.TotalDifficulty is null) { @@ -234,7 +238,7 @@ protected virtual void ResetPivot() private UInt256 TryGetPivotTotalDifficulty(Hash256 headerHash) { - if (_pivotNumber == _syncConfig.PivotNumber) + if (_pivotNumber == (ulong)_syncConfig.PivotNumber) return _syncConfig.PivotTotalDifficultyParsed; // Pivot is the same as in config // Got from header @@ -288,7 +292,7 @@ protected virtual void FinishAndCleanUp() protected void ClearDependencies() { - foreach (KeyValuePair kvp in _dependencies) + foreach (KeyValuePair kvp in _dependencies) { kvp.Value.Dispose(); } @@ -298,6 +302,7 @@ protected void ClearDependencies() protected virtual void PostFinishCleanUp() { + // TotalBlocks is ulong; ProgressLogger.Update now accepts ulong — no cast required. HeadersSyncProgressLoggerReport.Update(TotalBlocks); HeadersSyncProgressLoggerReport.CurrentQueued = 0; HeadersSyncProgressLoggerReport.MarkEnd(); @@ -310,16 +315,16 @@ protected virtual void PostFinishCleanUp() private bool CanHandleDependentBatch() { - long? lowest = LowestInsertedBlockHeader?.Number; - return lowest.HasValue && _dependencies.ContainsKey(lowest.Value - 1); + ulong? lowest = LowestInsertedBlockHeader?.Number; + return lowest.HasValue && lowest.Value > 0 && _dependencies.ContainsKey(lowest.Value - 1); } private void HandleDependentBatches(CancellationToken cancellationToken) { - long? lowest = LowestInsertedBlockHeader?.Number; + ulong? lowest = LowestInsertedBlockHeader?.Number; long processedBatchCount = 0; long maxBatchToProcess = (MemoryInQueue < _fastHeadersMemoryBudget / 2) ? 2 : 4; // Try to keep queue large - while (lowest.HasValue && processedBatchCount < maxBatchToProcess && _dependencies.TryRemove(lowest.Value - 1, out HeadersSyncBatch dependentBatch)) + while (lowest.HasValue && lowest.Value > 0 && processedBatchCount < maxBatchToProcess && _dependencies.TryRemove(lowest.Value - 1, out HeadersSyncBatch dependentBatch)) { using (dependentBatch) { @@ -337,8 +342,8 @@ private bool HasDependencyToProcess { get { - long? lowest = LowestInsertedBlockHeader?.Number; - return lowest is not null && _dependencies.ContainsKey(lowest.Value - 1); + ulong? lowest = LowestInsertedBlockHeader?.Number; + return lowest is not null && lowest.Value > 0 && _dependencies.ContainsKey(lowest.Value - 1); } } @@ -372,7 +377,8 @@ private bool HasDependencyToProcess if (batch is not null) { _sent.Add(batch); - if (batch.StartNumber >= (LowestInsertedBlockHeader?.Number ?? 0) - FastBlocksPriorities.ForHeaders) + ulong lowestNumber = LowestInsertedBlockHeader?.Number ?? 0UL; + if (batch.StartNumber >= lowestNumber - (ulong)FastBlocksPriorities.ForHeaders) { batch.Prioritized = true; } @@ -418,8 +424,9 @@ private bool HasDependencyToProcess private HeadersSyncBatch? BuildNewBatch(int requestSize) { HeadersSyncBatch batch = new(); - batch.StartNumber = Math.Max(HeadersDestinationNumber, _lowestRequestedHeaderNumber - requestSize); - batch.RequestSize = (int)Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, requestSize); + ulong requestSizeU = (ulong)requestSize; + batch.StartNumber = Math.Max(HeadersDestinationNumber, _lowestRequestedHeaderNumber >= requestSizeU ? _lowestRequestedHeaderNumber - requestSizeU : 0UL); + batch.RequestSize = (int)Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, (ulong)requestSize); _lowestRequestedHeaderNumber = batch.StartNumber; return batch; } @@ -431,10 +438,10 @@ private void LogStateOnPrepare() { lock (_handlerLock) { - Dictionary all = []; + Dictionary all = []; StringBuilder builder = new(); builder.AppendLine($"SENT {_sent.Count} PENDING {_pending.Count} DEPENDENCIES {_dependencies.Count}"); - foreach (KeyValuePair headerDependency in _dependencies) + foreach (KeyValuePair headerDependency in _dependencies) { all.TryAdd(headerDependency.Value.EndNumber, $" DEPENDENCY {headerDependency.Value}"); } @@ -449,7 +456,7 @@ private void LogStateOnPrepare() all.TryAdd(sentBatch.EndNumber, $" SENT {sentBatch}"); } - foreach (KeyValuePair keyValuePair in all + foreach (KeyValuePair keyValuePair in all .OrderByDescending(static kvp => kvp.Key)) { builder.AppendLine(keyValuePair.Value); @@ -515,7 +522,10 @@ public override SyncResponseHandlingResult HandleResponse(HeadersSyncBatch? batc private static HeadersSyncBatch BuildRightFiller(HeadersSyncBatch batch, int rightFillerSize) { HeadersSyncBatch rightFiller = new(); - rightFiller.StartNumber = batch.EndNumber - rightFillerSize + 1; + // EndNumber is ulong; rightFillerSize is int. Guard against underflow (should never happen in practice). + rightFiller.StartNumber = batch.EndNumber >= (ulong)(rightFillerSize - 1) + ? batch.EndNumber - (ulong)(rightFillerSize - 1) + : 0UL; rightFiller.RequestSize = rightFillerSize; return rightFiller; } @@ -528,7 +538,7 @@ private static HeadersSyncBatch BuildLeftFiller(HeadersSyncBatch batch, int left return leftFiller; } - private static HeadersSyncBatch BuildDependentBatch(HeadersSyncBatch batch, long addedLast, long addedEarliest) + private static HeadersSyncBatch BuildDependentBatch(HeadersSyncBatch batch, ulong addedLast, ulong addedEarliest) { HeadersSyncBatch dependentBatch = new(); dependentBatch.StartNumber = addedEarliest; @@ -571,6 +581,7 @@ private void EnqueueBatch(HeadersSyncBatch batch, bool skipPersisted = false) int newRequestSize = batch.RequestSize - headers.Count; ReadOnlySpan headersSpan = headers.AsSpan(); using HeadersSyncBatch newBatchToProcess = new(); + // headersSpan[0].Number and StartNumber are both ulong — no cast needed. newBatchToProcess.StartNumber = headersSpan[0].Number; newBatchToProcess.RequestSize = headersSpan.Length; newBatchToProcess.Response = headers; @@ -613,8 +624,11 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) using ArrayPoolList headersToAdd = new(response.Length); (Hash256 nextHeaderHash, UInt256? nextHeaderTotalDifficulty) = _expectedNextHeader; - long addedLast = batch.StartNumber - 1; - long addedEarliest = batch.EndNumber + 1; + // Use ulong.MaxValue as "not set" sentinel for addedEarliest (any real block number will be lower). + // Use 0 as "not set" sentinel for addedLast (any real block number ≥ 1 will be higher). + // These are adjusted during iteration; arithmetic is safe for realistic block heights. + ulong addedLast = batch.StartNumber == 0 ? 0UL : batch.StartNumber - 1UL; + ulong addedEarliest = batch.EndNumber + 1UL; BlockHeader? lowestInsertedHeader = null; int skippedAtTheEnd = 0; for (int i = response.Length - 1; i >= 0; i--) @@ -626,7 +640,8 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) continue; } - if (header.Number != batch.StartNumber + i) + // Both header.Number and batch.StartNumber are ulong. + if (header.Number != batch.StartNumber + (ulong)i) { if (batch.ResponseSourcePeer is not null) { @@ -660,8 +675,9 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) headersToAdd.Add(header); - addedEarliest = Math.Min(addedEarliest, header.Number); - addedLast = Math.Max(addedLast, header.Number); + // header.Number is ulong — direct ulong arithmetic. + if (header.Number < addedEarliest) addedEarliest = header.Number; + if (header.Number > addedLast) addedLast = header.Number; } UInt256? totalDifficulty = nextHeaderTotalDifficulty; @@ -679,15 +695,28 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) lowestInsertedHeader = headersToAdd[0]; } - int added = (int)(addedLast - addedEarliest + 1); - int leftFillerSize = (int)(addedEarliest - batch.StartNumber); - int rightFillerSize = (int)(batch.EndNumber - addedLast); + int added; + int leftFillerSize; + int rightFillerSize; + if (addedLast >= addedEarliest) + { + added = (int)(addedLast - addedEarliest + 1); + leftFillerSize = addedEarliest > batch.StartNumber ? (int)(addedEarliest - batch.StartNumber) : 0; + rightFillerSize = batch.EndNumber > addedLast ? (int)(batch.EndNumber - addedLast) : 0; + } + else + { + added = 0; + leftFillerSize = batch.RequestSize; + rightFillerSize = 0; + } if (added + leftFillerSize + rightFillerSize != batch.RequestSize) { throw new Exception($"Added {added} + left {leftFillerSize} + right {rightFillerSize} != request size {batch.RequestSize} in {batch}"); } - if (lowestInsertedHeader is not null && lowestInsertedHeader.Number < (LowestInsertedBlockHeader?.Number ?? long.MaxValue)) + // lowestInsertedHeader.Number and LowestInsertedBlockHeader.Number are ulong. Use ulong max sentinel. + if (lowestInsertedHeader is not null && lowestInsertedHeader.Number < (LowestInsertedBlockHeader?.Number ?? ulong.MaxValue)) { LowestInsertedBlockHeader = lowestInsertedHeader; SetExpectedNextHeaderToParent(lowestInsertedHeader); @@ -732,6 +761,8 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) if (LowestInsertedBlockHeader is not null) { + // Both _pivotNumber and LowestInsertedBlockHeader.Number are ulong. The subtraction yields + // ulong directly; ProgressLogger.Update now accepts ulong so no cast is required here. HeadersSyncProgressLoggerReport.Update(_pivotNumber - LowestInsertedBlockHeader.Number + 1); } @@ -745,6 +776,7 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response { BlockHeader lowestInserted = LowestInsertedBlockHeader; // response does not carry expected data + // header.Number is ulong; lowestInserted.Number is ulong — direct comparison is fine. if (header.Number == lowestInserted?.Number && header.Hash != lowestInserted?.Hash) { if (batch.ResponseSourcePeer is not null) @@ -766,7 +798,10 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response // However, if the header hash does match the parent of the LowestInsertedBlockHeader, then its just // `_nextHeaderHash` not updated as the `BlockTree.Insert` has not returned yet. // We just let it go to the dependency graph. - if (header.Number == (LowestInsertedBlockHeader?.Number ?? _pivotNumber + 1) - 1 && header.Hash != LowestInsertedBlockHeader?.ParentHash) + // header.Number is ulong; _pivotNumber is ulong; LowestInsertedBlockHeader.Number is ulong. + // Compute expected previous number: default to (_pivotNumber+1) when no header inserted yet. + ulong expectedPrevNumber = LowestInsertedBlockHeader?.Number ?? (_pivotNumber + 1); + if (header.Number == expectedPrevNumber - 1UL && header.Hash != LowestInsertedBlockHeader?.ParentHash) { if (_logger.IsDebug) _logger.Debug($"{batch} - ended up IGNORED - different branch - number {header.Number} was {header.Hash} while expected {nextHeaderHash}"); if (batch.ResponseSourcePeer is not null) @@ -780,6 +815,7 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response return false; } + // header.Number and LowestInsertedBlockHeader.Number are both ulong — direct comparison. if (header.Number == LowestInsertedBlockHeader?.Number) { if (_logger.IsDebug) _logger.Debug($"{batch} - ended up IGNORED - different branch"); @@ -794,6 +830,7 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response return false; } + // _dependencies is keyed by ulong — header.Number is ulong, no cast needed. if (_dependencies.ContainsKey(header.Number)) { EnqueueBatch(batch, true); @@ -806,13 +843,15 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response return false; } - long lastNumber = -1; + // Use ulong.MaxValue as "not visited" sentinel for lastNumber. + ulong lastNumber = ulong.MaxValue; for (int j = 0; j < response.Length; j++) { BlockHeader? current = response[j]; if (current is not null) { - if (lastNumber != -1 && lastNumber < current.Number - 1) + // Detect a gap: if we have a previous number and current is not sequential. + if (lastNumber != ulong.MaxValue && current.Number > lastNumber + 1) { //There is a gap in this response, //so we save the whole batch for now, @@ -821,12 +860,13 @@ bool ValidateFirstHeader(BlockHeader header, ReadOnlySpan response addedLast = batch.EndNumber; break; } - addedEarliest = Math.Min(addedEarliest, current.Number); - addedLast = Math.Max(addedLast, current.Number); + if (current.Number < addedEarliest) addedEarliest = current.Number; + if (current.Number > addedLast) addedLast = current.Number; lastNumber = current.Number; } } HeadersSyncBatch dependentBatch = BuildDependentBatch(batch, addedLast, addedEarliest); + // _dependencies is keyed by ulong — header.Number is ulong, no cast needed. _dependencies[header.Number] = dependentBatch; MarkDirty(); if (_logger.IsDebug) _logger.Debug($"{batch} -> DEPENDENCY {dependentBatch}"); @@ -864,7 +904,7 @@ public override void Dispose() { _sent.DisposeItems(); _pending.DisposeItems(); - foreach (KeyValuePair kvp in _dependencies) + foreach (KeyValuePair kvp in _dependencies) { kvp.Value.Dispose(); } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncBatch.cs index 5bf4d175be97..a6b3910a3844 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncBatch.cs @@ -17,6 +17,6 @@ public override void Dispose() Response?.Dispose(); } - public override long? MinNumber => Infos[0].BlockNumber; + public override ulong? MinNumber => Infos[0].BlockNumber; } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs index b5acbd0d0756..96ecad8f430c 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs @@ -30,16 +30,16 @@ namespace Nethermind.Synchronization.FastBlocks { public class ReceiptsSyncFeed : BarrierSyncFeed { - protected override long? LowestInsertedNumber => _syncPointers.LowestInsertedReceiptBlockNumber; + protected override ulong? LowestInsertedNumber => _syncPointers.LowestInsertedReceiptBlockNumber; protected override int BarrierWhenStartedMetadataDbKey => MetadataDbKeys.ReceiptsBarrierWhenStarted; - protected override long SyncConfigBarrierCalc => ComputeBarrier(_blockTree.SyncPivot.BlockNumber); + protected override ulong SyncConfigBarrierCalc => ComputeBarrier(_blockTree.SyncPivot.BlockNumber); - private long ComputeBarrier(long pivotNumber) + private ulong ComputeBarrier(ulong pivotNumber) { - long requested = Math.Max(_syncConfig.AncientBodiesBarrier, _syncConfig.AncientReceiptsBarrier); - long clamped = Math.Max(1, Math.Min(pivotNumber, requested)); - long? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; - return cutoffBlockNumber is null ? clamped : long.Max(clamped, cutoffBlockNumber.Value); + ulong requested = Math.Max((ulong)_syncConfig.AncientBodiesBarrier, (ulong)_syncConfig.AncientReceiptsBarrier); + ulong clamped = Math.Max(1UL, Math.Min(pivotNumber, requested)); + ulong? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; + return cutoffBlockNumber is null ? clamped : ulong.Max(clamped, cutoffBlockNumber.Value); } protected override Func HasPivot => @@ -59,7 +59,7 @@ private long ComputeBarrier(long pivotNumber) private SyncStatusList _syncStatusList; private bool ShouldFinish => !_syncConfig.DownloadReceiptsInFastSync || AllDownloaded; - private bool AllDownloaded => (_syncPointers.LowestInsertedReceiptBlockNumber ?? long.MaxValue) <= _barrier; + private bool AllDownloaded => (_syncPointers.LowestInsertedReceiptBlockNumber ?? ulong.MaxValue) <= _barrier; public override bool IsFinished => AllDownloaded; public override string FeedName => nameof(ReceiptsSyncFeed); @@ -91,13 +91,13 @@ public ReceiptsSyncFeed( throw new InvalidOperationException("Entered fast blocks mode without fast blocks enabled in configuration."); } - _pivotNumber = -1; // First reset in `InitializeFeed`. + _pivotNumber = 0; // First reset in `InitializeFeed`. } public override void InitializeFeed() { - long newPivotNumber = _blockTree.SyncPivot.BlockNumber; - long newBarrier = ComputeBarrier(newPivotNumber); + ulong newPivotNumber = _blockTree.SyncPivot.BlockNumber; + ulong newBarrier = ComputeBarrier(newPivotNumber); if (_pivotNumber != newPivotNumber || _barrier != newBarrier) { _pivotNumber = newPivotNumber; @@ -278,6 +278,7 @@ private int InsertReceipts(ReceiptsSyncBatch batch) Block? block = _blockTree.FindBlock(blockInfo.BlockHash); if (block is null) { + // blockInfo.BlockNumber is ulong; _barrier is long. Cast is safe for realistic heights. if (blockInfo.BlockNumber >= _barrier) { if (_logger.IsWarn) _logger.Warn($"Could not find block {blockInfo.BlockHash}"); @@ -344,8 +345,8 @@ private class ReceiptDownloadStrategy(IBlockTree blockTree, IReceiptStorage rece public bool ShouldDownloadBlock(BlockInfo info) { bool hasReceipt = receiptStorage.HasBlock(info.BlockNumber, info.BlockHash); - long? cutoff = historyPruner?.CutoffBlockNumber; - cutoff = cutoff is null ? null : long.Min(cutoff!.Value, blockTree.SyncPivot.BlockNumber); + ulong? cutoff = historyPruner?.CutoffBlockNumber; + cutoff = cutoff is null ? null : ulong.Min(cutoff!.Value, blockTree.SyncPivot.BlockNumber); bool shouldDownload = !hasReceipt && (cutoff is null || info.BlockNumber >= cutoff); if (!shouldDownload) syncReport.FastBlocksReceipts.IncrementSkipped(); return shouldDownload; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs index d35451a99576..32a141c3e6d7 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs @@ -17,11 +17,11 @@ internal class SyncStatusList private long _queueSize; private readonly IBlockTree _blockTree; private readonly FastBlockStatusList _statuses; - private readonly LruCache _cache = new(maxCapacity: 64, startCapacity: 64, "blockInfo Cache"); - private long _lowestInsertWithoutGaps; - private readonly long _lowerBound; + private readonly LruCache _cache = new(maxCapacity: 64, startCapacity: 64, "blockInfo Cache"); + private ulong _lowestInsertWithoutGaps; + private readonly ulong _lowerBound; - public long LowestInsertWithoutGaps + public ulong LowestInsertWithoutGaps { get => _lowestInsertWithoutGaps; private init => _lowestInsertWithoutGaps = value; @@ -29,10 +29,10 @@ public long LowestInsertWithoutGaps public long QueueSize => _queueSize; - public SyncStatusList(IBlockTree blockTree, long pivotNumber, long? lowestInserted, long lowerBound) + public SyncStatusList(IBlockTree blockTree, ulong pivotNumber, ulong? lowestInserted, ulong lowerBound) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - _statuses = new FastBlockStatusList(pivotNumber + 1); + _statuses = new FastBlockStatusList((long)pivotNumber + 1); LowestInsertWithoutGaps = lowestInserted ?? pivotNumber; _lowerBound = lowerBound; @@ -41,7 +41,7 @@ public SyncStatusList(IBlockTree blockTree, long pivotNumber, long? lowestInsert private void GetInfosForBatch(Span blockInfos) { int collected = 0; - long currentNumber = Volatile.Read(ref _lowestInsertWithoutGaps); + ulong currentNumber = Volatile.Read(ref _lowestInsertWithoutGaps); while (collected < blockInfos.Length && currentNumber != 0 && currentNumber >= _lowerBound) { if (blockInfos[collected] is not null) @@ -50,7 +50,7 @@ private void GetInfosForBatch(Span blockInfos) continue; } - if (_statuses.TrySet(currentNumber, FastBlockStatus.Sent, out FastBlockStatus status)) + if (_statuses.TrySet((long)currentNumber, FastBlockStatus.Sent, out FastBlockStatus status)) { if (_cache.TryGet(currentNumber, out BlockInfo blockInfo)) { @@ -66,7 +66,7 @@ private void GetInfosForBatch(Span blockInfos) } else if (status == FastBlockStatus.Inserted) { - long currentLowest = Volatile.Read(ref _lowestInsertWithoutGaps); + ulong currentLowest = Volatile.Read(ref _lowestInsertWithoutGaps); if (currentNumber == currentLowest) { if (Interlocked.CompareExchange(ref _lowestInsertWithoutGaps, currentLowest - 1, currentLowest) == currentLowest) @@ -171,9 +171,9 @@ void CompileOutput(out BlockInfo?[] outputArray) } } - public void MarkInserted(long blockNumber) + public void MarkInserted(ulong blockNumber) { - if (_statuses.TrySet(blockNumber, FastBlockStatus.Inserted)) + if (_statuses.TrySet((long)blockNumber, FastBlockStatus.Inserted)) { Interlocked.Increment(ref _queueSize); } @@ -181,7 +181,7 @@ public void MarkInserted(long blockNumber) public void MarkPending(BlockInfo blockInfo) { - if (_statuses.TrySet(blockInfo.BlockNumber, FastBlockStatus.Pending)) + if (_statuses.TrySet((long)blockInfo.BlockNumber, FastBlockStatus.Pending)) { _cache.Set(blockInfo.BlockNumber, blockInfo); } diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/BranchProgress.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/BranchProgress.cs index 57166463ebc0..916418ec5d84 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/BranchProgress.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/BranchProgress.cs @@ -24,9 +24,9 @@ internal class BranchProgress private long _lastReportMs = 0; public decimal LastProgress { get; private set; } - public long CurrentSyncBlock { get; } + public ulong CurrentSyncBlock { get; } - public BranchProgress(long syncBlockNumber, ILogger logger) + public BranchProgress(ulong syncBlockNumber, ILogger logger) { _logger = logger; CurrentSyncBlock = syncBlockNumber; diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/IStateSyncPivot.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/IStateSyncPivot.cs index a167d69f167a..b2f900057899 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/IStateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/IStateSyncPivot.cs @@ -12,7 +12,7 @@ public interface IStateSyncPivot BlockHeader? GetPivotHeader(); void UpdateHeaderForcefully(); ConcurrentHashSet UpdatedStorages { get; } - long Diff { get; } + ulong Diff { get; } /// Returns true if state sync can be finalized at . /// The proposed finalization point. /// true if ready to finalize; otherwise false. diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs index 7c13a6242771..a35eda6d68cd 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs @@ -16,11 +16,14 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa private BlockHeader? _bestHeader; private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - public long Diff => (blockTree.BestSuggestedHeader?.Number ?? 0) - (_bestHeader?.Number ?? 0); + // BestSuggestedHeader.Number and _bestHeader.Number are ulong. Diff is long (can be negative during reorgs). + public ulong Diff => blockTree.BestSuggestedHeader?.Number ?? 0UL - (_bestHeader?.Number ?? 0UL); public BlockHeader? GetPivotHeader() { - if (_bestHeader is null || (blockTree.BestSuggestedHeader?.Number + syncConfig.StateMinDistanceFromHead) - _bestHeader.Number >= syncConfig.StateMaxDistanceFromHead) + // BestSuggestedHeader.Number is ulong; StateMinDistanceFromHead/StateMaxDistanceFromHead are long. + // Cast to long for arithmetic; safe for realistic chain heights. + if (_bestHeader is null || ((long)(blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) - (long)_bestHeader.Number >= syncConfig.StateMaxDistanceFromHead) { TrySetNewBestHeader($"distance from HEAD:{Diff}"); } @@ -30,7 +33,7 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa public void UpdateHeaderForcefully() { - if (_bestHeader is null || (blockTree.BestSuggestedHeader?.Number + syncConfig.StateMinDistanceFromHead) > _bestHeader.Number) + if (_bestHeader is null || ((long)(blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) > (long)_bestHeader.Number) { TrySetNewBestHeader("too many empty responses"); } @@ -39,11 +42,13 @@ public void UpdateHeaderForcefully() private void TrySetNewBestHeader(string msg) { BlockHeader bestSuggestedHeader = blockTree.BestSuggestedHeader; // Note: Best suggested header is always `syncConfig.StateMinDistanceFromHead`. behind from actual head. - long targetBlockNumber = (bestSuggestedHeader?.Number ?? 0); + // bestSuggestedHeader.Number is ulong; target is long for Math.Max and FindHeader. + ulong targetBlockNumber = bestSuggestedHeader?.Number ?? 0UL; targetBlockNumber = Math.Max(targetBlockNumber, 0); // The new pivot must be at least one block after the sync pivot as the forward downloader does not // download the block at the sync pivot which may cause state not found error if state was downloaded // at exactly sync pivot. + // SyncPivot.BlockNumber is ulong; cast to long is safe for realistic chain heights. targetBlockNumber = Math.Max(targetBlockNumber, blockTree.SyncPivot.BlockNumber + 1); BlockHeader bestHeader = blockTree.FindHeader(targetBlockNumber); diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncRunner.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncRunner.cs index 932b5b6cf683..585a22c1cf18 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncRunner.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncRunner.cs @@ -122,17 +122,18 @@ private async Task StateSyncPrecursorWait(CancellationToken token) { await syncModeSelector.WaitUntilMode(m => (m & SyncMode.StateNodes) != 0, token); - int totalSyncLag = syncConfig.StateMinDistanceFromHead + syncConfig.HeaderStateDistance; + ulong totalSyncLag = (ulong)syncConfig.StateMinDistanceFromHead + (ulong)syncConfig.HeaderStateDistance; while (!token.IsCancellationRequested) { - long header = syncProgressResolver.FindBestHeader(); - long peerBlock = 0; + ulong header = syncProgressResolver.FindBestHeader(); + ulong peerBlock = 0; foreach (PeerInfo p in syncPeerPool.InitializedPeers) { - if (p.HeadNumber > peerBlock) peerBlock = p.HeadNumber; + ulong peerHeadNumber = p.HeadNumber; + if (peerHeadNumber > peerBlock) peerBlock = peerHeadNumber; } - long targetBlock = beaconSyncStrategy.GetTargetBlockHeight() ?? peerBlock; + ulong targetBlock = beaconSyncStrategy.GetTargetBlockHeight() ?? peerBlock; if (targetBlock >= header && (targetBlock - header) <= totalSyncLag) return; diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs index 34bd9d3b91e9..9f66909c7486 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs @@ -78,7 +78,7 @@ public class TreeSync private BranchProgress _branchProgress; private int _hintsToResetRoot; - private long _blockNumber; + private ulong _blockNumber; public TreeSync([KeyFilter(DbNames.Code)] IDb codeDb, ITreeSyncStore store, IBlockTree blockTree, IStateSyncPivot stateSyncPivot, ISyncConfig syncConfig, ILogManager logManager) { @@ -401,11 +401,12 @@ public bool IsSyncRoundFinished() } if (_logger.IsInfo) _logger.Info($"Starting the node data sync from the {headerForState.ToString(BlockHeader.Format.Short)} {headerForState.StateRoot} root"); + // headerForState.Number is ulong; ResetStateRoot takes long. Cast is safe for realistic chain heights. ResetStateRoot(headerForState.Number, headerForState.StateRoot!); return headerForState; } - private void ResetStateRoot(long blockNumber, Hash256 stateRoot) + private void ResetStateRoot(ulong blockNumber, Hash256 stateRoot) { _lastResetRoot = DateTime.UtcNow; Interlocked.Exchange(ref _hintsToResetRoot, 0); diff --git a/src/Nethermind/Nethermind.Synchronization/IBeaconSyncStrategy.cs b/src/Nethermind/Nethermind.Synchronization/IBeaconSyncStrategy.cs index d3fd47102802..5e277451ba84 100644 --- a/src/Nethermind/Nethermind.Synchronization/IBeaconSyncStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/IBeaconSyncStrategy.cs @@ -20,7 +20,7 @@ public void AllowBeaconHeaderSync() { } public bool IsBeaconSyncFinished(BlockHeader? blockHeader) => true; public bool MergeTransitionFinished => false; - public long? GetTargetBlockHeight() => null; + public ulong? GetTargetBlockHeight() => null; public Hash256? GetFinalizedHash() => null; public Hash256? GetHeadBlockHash() => null; } @@ -34,7 +34,7 @@ public interface IBeaconSyncStrategy public bool MergeTransitionFinished { get; } - public long? GetTargetBlockHeight(); + public ulong? GetTargetBlockHeight(); public Hash256? GetFinalizedHash(); public Hash256? GetHeadBlockHash(); } diff --git a/src/Nethermind/Nethermind.Synchronization/IBetterPeerStrategy.cs b/src/Nethermind/Nethermind.Synchronization/IBetterPeerStrategy.cs index 0f71c88a3bed..a074bc6d149c 100644 --- a/src/Nethermind/Nethermind.Synchronization/IBetterPeerStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/IBetterPeerStrategy.cs @@ -10,11 +10,11 @@ namespace Nethermind.Synchronization; /// public interface IBetterPeerStrategy { - int Compare(in (UInt256? TotalDifficulty, long Number) valueX, in (UInt256? TotalDifficulty, long Number) valueY); + int Compare(in (UInt256? TotalDifficulty, ulong Number) valueX, in (UInt256? TotalDifficulty, ulong Number) valueY); - bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestBlock); + bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestBlock); - bool IsDesiredPeer(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestHeader); + bool IsDesiredPeer(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestHeader); bool IsLowerThanTerminalTotalDifficulty(UInt256 totalDifficulty) => true; } diff --git a/src/Nethermind/Nethermind.Synchronization/IPivot.cs b/src/Nethermind/Nethermind.Synchronization/IPivot.cs index ce8902976365..51f7ba6a2f43 100644 --- a/src/Nethermind/Nethermind.Synchronization/IPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/IPivot.cs @@ -7,12 +7,12 @@ namespace Nethermind.Synchronization { public interface IPivot { - long PivotNumber { get; } + ulong PivotNumber { get; } Hash256? PivotHash { get; } Hash256? PivotParentHash { get; } - long PivotDestinationNumber { get; } + ulong PivotDestinationNumber { get; } } } diff --git a/src/Nethermind/Nethermind.Synchronization/ISyncPointers.cs b/src/Nethermind/Nethermind.Synchronization/ISyncPointers.cs index eeb727dbdbe3..d17b799e656d 100644 --- a/src/Nethermind/Nethermind.Synchronization/ISyncPointers.cs +++ b/src/Nethermind/Nethermind.Synchronization/ISyncPointers.cs @@ -5,7 +5,7 @@ namespace Nethermind.Synchronization; public interface ISyncPointers { - long? LowestInsertedBodyNumber { get; set; } - long? LowestInsertedReceiptBlockNumber { get; set; } - long? LowestInsertedBlockAccessListBlockNumber { get; set; } + ulong? LowestInsertedBodyNumber { get; set; } + ulong? LowestInsertedReceiptBlockNumber { get; set; } + ulong? LowestInsertedBlockAccessListBlockNumber { get; set; } } diff --git a/src/Nethermind/Nethermind.Synchronization/ISyncServer.cs b/src/Nethermind/Nethermind.Synchronization/ISyncServer.cs index 7ac24343a46d..ffa1ab5983c1 100644 --- a/src/Nethermind/Nethermind.Synchronization/ISyncServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/ISyncServer.cs @@ -15,20 +15,20 @@ namespace Nethermind.Synchronization { public interface ISyncServer : IDisposable { - void HintBlock(Hash256 hash, long number, ISyncPeer receivedFrom); + void HintBlock(Hash256 hash, ulong number, ISyncPeer receivedFrom); void AddNewBlock(Block block, ISyncPeer node); void StopNotifyingPeersAboutNewBlocks(); TxReceipt[]? GetReceipts(Hash256 blockHashes); MemoryManager? GetBlockAccessListRlp(Hash256 blockHash); Block? Find(Hash256 hash); BlockHeader? FindHeader(Hash256 hash); - Hash256? FindHash(long number); + Hash256? FindHash(ulong number); IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse); IByteArrayList GetNodeData(IReadOnlyList keys, CancellationToken cancellationToken, NodeDataType includedTypes = NodeDataType.Code | NodeDataType.State); int GetPeerCount(); ulong NetworkId { get; } BlockHeader Genesis { get; } BlockHeader? Head { get; } - long LowestBlock { get; } + ulong LowestBlock { get; } } } diff --git a/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs b/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs index c4609342b3d9..dda799891eab 100644 --- a/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs @@ -23,10 +23,11 @@ public sealed class ZeroTotalDifficultyStrategy : ITotalDifficultyStrategy public sealed class FixedTotalDifficultyStrategy( ITotalDifficultyStrategy strategy, - long fixesBlockNumber, + ulong fixesBlockNumber, UInt256 toTotalDifficulty ) : ITotalDifficultyStrategy { + // header.Number is ulong; fixesBlockNumber is ulong — no cast needed. public UInt256 ParentTotalDifficulty(BlockHeader header) => header.Number > 0 && header.Number - 1 == fixesBlockNumber ? toTotalDifficulty : strategy.ParentTotalDifficulty(header); diff --git a/src/Nethermind/Nethermind.Synchronization/Metrics.cs b/src/Nethermind/Nethermind.Synchronization/Metrics.cs index fa51ce019080..aa43f8b81a36 100644 --- a/src/Nethermind/Nethermind.Synchronization/Metrics.cs +++ b/src/Nethermind/Nethermind.Synchronization/Metrics.cs @@ -18,15 +18,15 @@ public static class Metrics [GaugeMetric] [Description("Bodies downloaded in fast blocks stage")] - public static long FastBodies; + public static ulong FastBodies; [GaugeMetric] [Description("Receipts downloaded in fast blocks stage")] - public static long FastReceipts; + public static ulong FastReceipts; [GaugeMetric] [Description("Access lists downloaded in fast blocks stage")] - public static long FastBlockAccessLists; + public static ulong FastBlockAccessLists; [GaugeMetric] [Description("State synced in bytes")] diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs index 09be0ee0b824..b252c4ac7133 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs @@ -17,15 +17,18 @@ public class FullStateFinder( // TODO: we can search 1024 back and confirm 128 deep header and start using it as Max(0, confirmed) // then we will never have to look 128 back again // note that we will be doing that every second or so - private const int MaxLookupBack = 128; + private const ulong MaxLookupBack = 128; private readonly IStateReader _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - private long _lastKnownState; + + // Block numbers are ulong throughout; 0 is the "not yet known" sentinel (genesis is never + // a valid "last known full state" to resume from). + private ulong _lastKnownState; private bool IsFullySynced(BlockHeader block) => block.StateRoot == Keccak.EmptyTreeHash || _stateReader.HasStateForBlock(block); - public long FindBestFullState() + public ulong FindBestFullState() { // so the full state can be in a few places but there are some best guesses // if we are state syncing then the full state may be one of the recent blocks (maybe one of the last 128 blocks) @@ -39,7 +42,7 @@ public long FindBestFullState() BlockHeader initialBestSuggested = _blockTree.BestSuggestedHeader; // just storing here for debugging sake BlockHeader bestSuggested = initialBestSuggested; - long bestFullState = 0; + ulong bestFullState = 0; if (head is not null) { // head search should be very inexpensive as we generally expect the state to be there @@ -48,7 +51,7 @@ public long FindBestFullState() if (bestSuggested is not null) { - if (bestFullState < bestSuggested?.Number) + if (bestFullState < bestSuggested.Number) { bestFullState = Math.Max(bestFullState, SearchForFullState(bestSuggested)); } @@ -62,16 +65,23 @@ public long FindBestFullState() return bestFullState; } - private long SearchForFullState(BlockHeader startHeader) + private ulong SearchForFullState(BlockHeader startHeader) { - long bestFullState = 0; - long maxLookupBack = MaxLookupBack; + ulong bestFullState = 0; + ulong maxLookupBack = MaxLookupBack; if (_lastKnownState != 0) { - maxLookupBack = long.Max(maxLookupBack, startHeader.Number - _lastKnownState + 1); + // Guard against underflow: only extend the window when the header is ahead of + // (or at) the last known state. If startHeader.Number < _lastKnownState the + // chain walked backwards during a reorg; keep the default MaxLookupBack window. + if (startHeader.Number >= _lastKnownState) + { + ulong lookback = startHeader.Number - _lastKnownState + 1; + if (lookback > maxLookupBack) maxLookupBack = lookback; + } } - for (int i = 0; i < maxLookupBack; i++) + for (ulong i = 0; i < maxLookupBack; i++) { if (startHeader is null) { @@ -80,6 +90,7 @@ private long SearchForFullState(BlockHeader startHeader) if (IsFullySynced(startHeader)) { + // startHeader.Number is ulong — direct assignment, no cast needed. bestFullState = startHeader.Number; break; } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/IFullStateFinder.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/IFullStateFinder.cs index 7a9ebf7da044..79134c32d0ba 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/IFullStateFinder.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/IFullStateFinder.cs @@ -5,5 +5,5 @@ namespace Nethermind.Synchronization.ParallelSync; public interface IFullStateFinder { - long FindBestFullState(); + ulong FindBestFullState(); } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncProgressResolver.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncProgressResolver.cs index 973db9116a1d..ea31b531fe9d 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncProgressResolver.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncProgressResolver.cs @@ -10,9 +10,9 @@ namespace Nethermind.Synchronization.ParallelSync { public interface ISyncProgressResolver : IFullStateFinder { - long FindBestHeader(); + ulong FindBestHeader(); - long FindBestFullBlock(); + ulong FindBestFullBlock(); bool IsFastBlocksHeadersFinished(); @@ -24,7 +24,7 @@ public interface ISyncProgressResolver : IFullStateFinder bool IsLoadingBlocksFromDb(); - long FindBestProcessedBlock(); + ulong FindBestProcessedBlock(); UInt256 ChainDifficulty { get; } @@ -32,6 +32,6 @@ public interface ISyncProgressResolver : IFullStateFinder void RecalculateProgressPointers(); - (long BlockNumber, Hash256 BlockHash) SyncPivot { get; } + (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get; } } } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 79e0a29e28a4..376715fe3bce 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - using System; using System.Collections.Generic; using System.Linq; @@ -58,7 +55,7 @@ public class MultiSyncModeSelector : ISyncModeSelector private bool FastBlocksReceiptsFinished => !FastReceiptsEnabled || _syncProgressResolver.IsFastBlocksReceiptsFinished(); private bool FastBlockAccessListsFinished => !FastBlockAccessListsEnabled || _syncProgressResolver.IsFastBlockAccessListsFinished(); private bool NotNeedToWaitForHeaders => !_needToWaitForHeaders || FastBlocksHeadersFinished; - private int TotalSyncLag => _syncConfig.StateMinDistanceFromHead + _syncConfig.HeaderStateDistance; + private ulong TotalSyncLag => (ulong)(_syncConfig.StateMinDistanceFromHead + _syncConfig.HeaderStateDistance); private CancellationTokenSource? _cancellation = new(); @@ -136,7 +133,7 @@ public void Update() else { bool inBeaconControl = _beaconSyncStrategy.ShouldBeInBeaconModeControl(); - (UInt256? peerDifficulty, long? peerBlock) = ReloadDataFromPeers(); + (UInt256? peerDifficulty, ulong? peerBlock) = ReloadDataFromPeers(); // if there are no peers that we could use then we cannot sync if (peerBlock is null or 0) { @@ -366,6 +363,9 @@ private bool ShouldBeInFastSyncMode(Snapshot best) // and we need to sync away from it. // Note: its ok if target block height is not accurate as long as full sync downloader does not stop // earlier than this condition below which would cause a hang. + // Safe: TotalSyncLag is derived from non-negative config ints, and TargetBlock >= TotalSyncLag is + // checked implicitly — if TargetBlock < TotalSyncLag the subtraction wraps to a huge ulong so + // Header (a real block number) will never be >= it, giving the correct "not reached" result. bool notReachedFullSyncTransition = best.Header < best.TargetBlock - TotalSyncLag; // Long range catch-up (switching back to fast/state sync when far behind) was removed. @@ -571,7 +571,11 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool hasAnyPostPivotPeer = best.AnyPostPivotPeerKnown; bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; - bool stickyStateNodes = best.TargetBlock - best.Header < (_syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta); + // Safe: _syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta are non-negative config + // ints whose sum fits comfortably in ulong. If TargetBlock < Header the subtraction wraps + // (ulong underflow) yielding a very large number, so stickyStateNodes is false — correct + // behaviour because we are already ahead of the target. + bool stickyStateNodes = best.TargetBlock - best.Header < (ulong)(_syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta); bool stateNotDownloadedYet = !best.StateDownloaded; @@ -601,17 +605,20 @@ private bool ShouldBeInStateSyncMode(Snapshot best) private static bool ShouldBeInStateNodesMode(Snapshot best) => best.IsInStateSync; - private bool AnyDesiredPeerKnown(Snapshot best) => _betterPeerStrategy.IsDesiredPeer(best.Peer, (best.ChainDifficulty, best.Header)); + private bool AnyDesiredPeerKnown(Snapshot best) => + _betterPeerStrategy.IsDesiredPeer( + (best.Peer.TotalDifficulty, best.Peer.Block), + (best.ChainDifficulty, best.Header)); - private (UInt256? maxPeerDifficulty, long? number) ReloadDataFromPeers() + private (UInt256? maxPeerDifficulty, ulong? number) ReloadDataFromPeers() { UInt256? maxPeerDifficulty = null; - long? number = 0; + ulong? number = 0; foreach (PeerInfo peer in _syncPeerPool.InitializedPeers) { UInt256 currentMax = maxPeerDifficulty ?? UInt256.Zero; - long currentMaxNumber = number ?? 0; + ulong currentMaxNumber = number ?? 0; bool isNewPeerBetterThanCurrentMax = _betterPeerStrategy.Compare((currentMax, currentMaxNumber), peer.SyncPeer) < 0; if (isNewPeerBetterThanCurrentMax) @@ -624,7 +631,7 @@ private bool ShouldBeInStateSyncMode(Snapshot best) // during the beacon header sync our realTotalDifficulty could be 0. We're using peer.TotalDifficulty in this case realTotalDifficulty = realTotalDifficulty == 0 ? peerTD : realTotalDifficulty; - bool isRealPeerBetterThanCurrentMax = _betterPeerStrategy.Compare(((currentMax, currentMaxNumber)), (realTotalDifficulty, peer.HeadNumber)) < 0; + bool isRealPeerBetterThanCurrentMax = _betterPeerStrategy.Compare((currentMax, currentMaxNumber), (realTotalDifficulty, peer.HeadNumber)) < 0; if (isRealPeerBetterThanCurrentMax) { @@ -645,7 +652,7 @@ private bool ShouldBeInStateSyncMode(Snapshot best) public void Dispose() => CancellationTokenExtensions.CancelDisposeAndClear(ref _cancellation); - private Snapshot EnsureSnapshot(in UInt256? peerDifficulty, long peerBlock, bool inBeaconControl) + private Snapshot EnsureSnapshot(in UInt256? peerDifficulty, ulong peerBlock, bool inBeaconControl) { // need to find them in the reversed order otherwise we may fall behind the processing // and think that we have an invalid snapshot @@ -669,32 +676,38 @@ private Snapshot EnsureSnapshot(in UInt256? peerDifficulty, long peerBlock, bool return best; } - private Snapshot TakeSnapshot(in UInt256? peerDifficulty, long peerBlock, bool inBeaconControl) + private Snapshot TakeSnapshot(in UInt256? peerDifficulty, ulong peerBlock, bool inBeaconControl) { // need to find them in the reversed order otherwise we may fall behind the processing // and think that we have an invalid snapshot - long processed = _syncProgressResolver.FindBestProcessedBlock(); - long state = _syncProgressResolver.FindBestFullState(); - long block = _syncProgressResolver.FindBestFullBlock(); - long header = _syncProgressResolver.FindBestHeader(); - long targetBlock = _beaconSyncStrategy.GetTargetBlockHeight() ?? peerBlock; + ulong processed = _syncProgressResolver.FindBestProcessedBlock(); + ulong state = _syncProgressResolver.FindBestFullState(); + ulong block = _syncProgressResolver.FindBestFullBlock(); + ulong header = _syncProgressResolver.FindBestHeader(); + ulong targetBlock = _beaconSyncStrategy.GetTargetBlockHeight() ?? peerBlock; UInt256 chainDifficulty = _syncProgressResolver.ChainDifficulty; + ulong pivotNumber = _syncProgressResolver.SyncPivot.BlockNumber; - return new(processed, state, block, header, chainDifficulty, Math.Max(peerBlock, 0), peerDifficulty, inBeaconControl, targetBlock, _syncProgressResolver.SyncPivot.BlockNumber); + return new(processed, state, block, header, chainDifficulty, peerBlock, peerDifficulty, inBeaconControl, targetBlock, pivotNumber); } - private static bool IsSnapshotInvalid(Snapshot best) => best.Block < 0 - || best.Header < 0 - || best.State < 0 - || best.Processed < 0 - || best.Peer.Block < 0 - || best.TargetBlock < 0 - // best header is at least equal to the best full block - || best.Block > best.Header - // we cannot download state for an unknown header - || best.State > best.Header - // we can only process blocks for which we have full body - || best.Processed > best.Block;// for any processed block we should have its full state// but we only do limited lookups for state so we need to instead fast sync to now; + private static bool IsSnapshotInvalid(Snapshot best) => + // All fields are ulong — the only invalid sentinel is a resolver returning a + // negative long that was cast to ulong, producing a very large value. We treat + // any value above long.MaxValue as invalid (it would be ~2^63+ blocks, impossible + // on any real chain). + best.Block > long.MaxValue + || best.Header > long.MaxValue + || best.State > long.MaxValue + || best.Processed > long.MaxValue + || best.Peer.Block > long.MaxValue + || best.TargetBlock > long.MaxValue + // best header is at least equal to the best full block + || best.Block > best.Header + // we cannot download state for an unknown header + || best.State > best.Header + // we can only process blocks for which we have full body + || best.Processed > best.Block; private void LogDetailedSyncModeChecks(string syncType, params (string Name, bool IsSatisfied)[] checks) { @@ -721,16 +734,16 @@ private void LogDetailedSyncModeChecks(string syncType, params (string Name, boo private ref struct Snapshot { public Snapshot( - long processed, - long state, - long block, - long header, + ulong processed, + ulong state, + ulong block, + ulong header, UInt256 chainDifficulty, - long peerBlock, + ulong peerBlock, in UInt256? peerDifficulty, bool isInBeaconControl, - long targetBlock, - long pivotNumber + ulong targetBlock, + ulong pivotNumber ) { Processed = processed; @@ -767,28 +780,28 @@ long pivotNumber /// /// Best block that has been processed /// - public long Processed { get; } + public ulong Processed { get; } /// /// Best full block state in the state trie (may not be processed if we just finished state trie download) /// - public long State { get; } + public ulong State { get; } /// /// Best block body /// - public long Block { get; } + public ulong Block { get; } /// /// Best block header - may be missing body if we just insert headers /// - public long Header { get; } + public ulong Header { get; } /// /// The best block that we want to go to. best.Peer.Block for PoW, beaconSync.ProcessDestination for PoS, /// which is the NewPayload/FCU block. /// - public long TargetBlock { get; } + public ulong TargetBlock { get; } /// /// Current difficulty of the chain @@ -798,9 +811,9 @@ long pivotNumber /// /// Best peer block - this is what other peers are advertising - it may be lower than our best block if we get disconnected from best peers /// - public (UInt256? TotalDifficulty, long Block) Peer { get; } + public (UInt256? TotalDifficulty, ulong Block) Peer { get; } - public long PivotNumber { get; } + public ulong PivotNumber { get; } } } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs index 721e3191d73b..c5c587e3dc41 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs @@ -26,11 +26,13 @@ public class SyncProgressResolver( private readonly ISyncConfig _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); private readonly IFullStateFinder _fullStateFinder = fullStateFinder ?? throw new ArgumentNullException(nameof(fullStateFinder)); - public long FindBestFullState() => _fullStateFinder.FindBestFullState(); - public long FindBestHeader() => _blockTree.BestSuggestedHeader?.Number ?? 0; - public long FindBestFullBlock() => Math.Min(FindBestHeader(), _blockTree.BestSuggestedBody?.Number ?? 0); // avoiding any potential concurrency issue + public ulong FindBestFullState() => _fullStateFinder.FindBestFullState(); + public ulong FindBestHeader() => _blockTree.BestSuggestedHeader?.Number ?? 0UL; + public ulong FindBestFullBlock() => Math.Min( + _blockTree.BestSuggestedHeader?.Number ?? 0UL, + _blockTree.BestSuggestedBody?.Number ?? 0UL); // avoiding any potential concurrency issue public bool IsLoadingBlocksFromDb() => !_blockTree.CanAcceptNewBlocks; - public long FindBestProcessedBlock() => _blockTree.Head?.Number ?? -1; + public ulong FindBestProcessedBlock() => _blockTree.Head?.Number is { } n ? n : ulong.MaxValue; public UInt256 ChainDifficulty => _blockTree.BestSuggestedBody?.TotalDifficulty ?? UInt256.Zero; public UInt256? GetTotalDifficulty(Hash256 blockHash) @@ -59,7 +61,14 @@ public class SyncProgressResolver( public bool IsFastBlocksReceiptsFinished() => !IsFastBlocks() || !_syncConfig.DownloadReceiptsInFastSync || receiptsSyncFeed.IsFinished; public bool IsFastBlockAccessListsFinished() => !IsFastBlocks() || !_syncConfig.DownloadBlockAccessListsInFastSync || blockAccessListsSyncFeed.IsFinished; public void RecalculateProgressPointers() => _blockTree.RecalculateTreeLevels(); - public (long BlockNumber, Hash256 BlockHash) SyncPivot => _blockTree.SyncPivot; - private bool IsFastBlocks() => _syncConfig.FastSync && _blockTree.SyncPivot.BlockNumber != 0L; // if pivot number is 0 then it is equivalent to fast blocks disabled + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot + { + get + { + (ulong blockNumber, Hash256 blockHash) = _blockTree.SyncPivot; + return (blockNumber, blockHash); + } + } + private bool IsFastBlocks() => _syncConfig.FastSync && _blockTree.SyncPivot.BlockNumber != 0UL; // if pivot number is 0 then it is equivalent to fast blocks disabled } } diff --git a/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs b/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs index 8fe0b10dc809..1b2183aa5424 100644 --- a/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs +++ b/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs @@ -38,7 +38,7 @@ public class PeerInfo(ISyncPeer syncPeer, AllocationAllowances? allocationAllowa /// See . public UInt256? TotalDifficulty => SyncPeer.TotalDifficulty; - public long HeadNumber => SyncPeer.HeadNumber; + public ulong HeadNumber => SyncPeer.HeadNumber; public Hash256 HeadHash => SyncPeer.HeadHash; public AllocationContexts SleepingContexts => (AllocationContexts)Volatile.Read(ref _sleepingContexts); diff --git a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs index 886438e51875..91f4712f4f2c 100644 --- a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs +++ b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs @@ -650,6 +650,7 @@ public void UpdateSyncPeerHeadIfHeaderIsBetter(ISyncPeer syncPeer, BlockHeader h if (parent is not null && (parent.TotalDifficulty ?? 0) != 0) { UInt256 newTotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty; + // header.Number is ulong; Compare expects long Number. Cast is safe for realistic chain heights. bool newValueIsNotWorseThanPeer = _betterPeerStrategy.Compare((newTotalDifficulty, header.Number), syncPeer) >= 0; if (_logger.IsTrace) _logger.Trace($"REFRESH Updating header of {syncPeer} from {syncPeer.HeadNumber} to {header.Number} based on totalDifficulty, newValueIsNotWorseThanPeer {newValueIsNotWorseThanPeer}, newTotalDifficulty: {newTotalDifficulty}, header.Difficulty: {header.Difficulty}, Parent total difficulty: {parent.TotalDifficulty}"); if (newValueIsNotWorseThanPeer) diff --git a/src/Nethermind/Nethermind.Synchronization/Pivot.cs b/src/Nethermind/Nethermind.Synchronization/Pivot.cs index 850d18c409e3..c6e7f8794f45 100644 --- a/src/Nethermind/Nethermind.Synchronization/Pivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/Pivot.cs @@ -11,14 +11,14 @@ public class Pivot : IPivot public Pivot(IBlockTree blockTree) { (PivotNumber, PivotHash) = blockTree.SyncPivot; - PivotDestinationNumber = 0L; + PivotDestinationNumber = 0UL; } - public long PivotNumber { get; } + public ulong PivotNumber { get; } public Hash256? PivotHash { get; } public Hash256? PivotParentHash => null; - public long PivotDestinationNumber { get; } + public ulong PivotDestinationNumber { get; } } diff --git a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs index 911d2363a070..14998f6026a5 100644 --- a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs +++ b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs @@ -49,7 +49,7 @@ public SyncReport(ISyncPeerPool syncPeerPool, INodeStatsManager nodeStatsManager BeaconHeaders.SetFormat((progress) => { - long numHeadersToDownload = _pivot.PivotNumber - _pivot.PivotDestinationNumber + 1; + long numHeadersToDownload = (long)(_pivot.PivotNumber - _pivot.PivotDestinationNumber + 1); string skipSectionStr = progress.SkippedPerSecond != -1 ? $"skipped {progress.SkippedPerSecond,ProgressLogger.SpeedPaddingLength:N0} Blk/s | " : ""; diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs index 757247346097..7096166ea6db 100644 --- a/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs +++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs @@ -154,7 +154,7 @@ public bool IsFinished(out SnapSyncBatch? nextBatch) BlockHeader? pivotHeader = _pivot.GetPivotHeader(); Hash256 rootHash = pivotHeader!.StateRoot!; - long blockNumber = pivotHeader.Number; + ulong blockNumber = pivotHeader.Number; if (!AccountsToRefresh.IsEmpty) { @@ -219,7 +219,7 @@ private SnapSyncBatch DequeCodeRequest() return new SnapSyncBatch { CodesRequest = codesToQuery }; } - private SnapSyncBatch DequeStorageToRetrieveRequest(Hash256 rootHash, long blockNumber) + private SnapSyncBatch DequeStorageToRetrieveRequest(Hash256 rootHash, ulong blockNumber) { Interlocked.Increment(ref _activeStorageRequests); // for race condition so that snap does not exit prematurely @@ -245,7 +245,7 @@ private SnapSyncBatch DequeStorageToRetrieveRequest(Hash256 rootHash, long block return new SnapSyncBatch { StorageRangeRequest = storageRange }; } - private SnapSyncBatch CreateNextSlowRangeRequest(StorageRange slotRange, Hash256 rootHash, long blockNumber) + private SnapSyncBatch CreateNextSlowRangeRequest(StorageRange slotRange, Hash256 rootHash, ulong blockNumber) { slotRange.RootHash = rootHash; slotRange.BlockNumber = blockNumber; @@ -255,7 +255,7 @@ private SnapSyncBatch CreateNextSlowRangeRequest(StorageRange slotRange, Hash256 return new SnapSyncBatch { StorageRangeRequest = slotRange }; } - private SnapSyncBatch CreateAccountRangeRequest(Hash256 rootHash, AccountRangePartition partition, long blockNumber) + private SnapSyncBatch CreateAccountRangeRequest(Hash256 rootHash, AccountRangePartition partition, ulong blockNumber) { Interlocked.Increment(ref _activeAccountRequests); diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs index ccc6cd0e9b0f..a5cccc1eff9f 100644 --- a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs @@ -67,7 +67,7 @@ public AddRangeResult AddAccountRange(AccountRange request, AccountsAndProofs re } public AddRangeResult AddAccountRange( - long blockNumber, + ulong blockNumber, in ValueHash256 expectedRootHash, in ValueHash256 startingHash, IReadOnlyList accounts, diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProviderHelper.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProviderHelper.cs index 17c82512fcc3..6ae9a2a5c071 100644 --- a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProviderHelper.cs +++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProviderHelper.cs @@ -18,7 +18,7 @@ public static class SnapProviderHelper public static (AddRangeResult result, bool moreChildrenToRight, List storageRoots, List codeHashes, Hash256 actualRootHash) AddAccountRange( ISnapTrieFactory factory, - long blockNumber, + ulong blockNumber, in ValueHash256 expectedRootHash, in ValueHash256 startingHash, in ValueHash256 limitHash, diff --git a/src/Nethermind/Nethermind.Synchronization/SyncPointers.cs b/src/Nethermind/Nethermind.Synchronization/SyncPointers.cs index 0d615bf4e228..2d1857456ae7 100644 --- a/src/Nethermind/Nethermind.Synchronization/SyncPointers.cs +++ b/src/Nethermind/Nethermind.Synchronization/SyncPointers.cs @@ -18,8 +18,8 @@ public class SyncPointers : ISyncPointers private static readonly byte[] LegacyLowestInsertedBodyNumberDbEntryAddress = ((long)0).ToBigEndianByteArrayWithoutLeadingZeros(); - private long? _lowestInsertedBodyNumber; - public long? LowestInsertedBodyNumber + private ulong? _lowestInsertedBodyNumber; + public ulong? LowestInsertedBodyNumber { get => _lowestInsertedBodyNumber; set @@ -29,9 +29,9 @@ public long? LowestInsertedBodyNumber } } - private long? _lowestInsertedReceiptBlock; + private ulong? _lowestInsertedReceiptBlock; - public long? LowestInsertedReceiptBlockNumber + public ulong? LowestInsertedReceiptBlockNumber { get => _lowestInsertedReceiptBlock; set @@ -44,9 +44,9 @@ public long? LowestInsertedReceiptBlockNumber } } - private long? _lowestInsertedBlockAccessListBlock; + private ulong? _lowestInsertedBlockAccessListBlock; - public long? LowestInsertedBlockAccessListBlockNumber + public ulong? LowestInsertedBlockAccessListBlockNumber { get => _lowestInsertedBlockAccessListBlock; set @@ -76,7 +76,7 @@ public SyncPointers( } byte[] lowestBytes = _defaultReceiptDbColumn.Get(Keccak.Zero); - _lowestInsertedReceiptBlock = lowestBytes is null ? (long?)null : new Rlp.ValueDecoderContext(lowestBytes).DecodeLong(); + _lowestInsertedReceiptBlock = lowestBytes is null ? (ulong?)null : new Rlp.ValueDecoderContext(lowestBytes).DecodeULong(); _lowestInsertedBlockAccessListBlock = ReadPointer(_metadataDb, MetadataDbKeys.LowestInsertedBlockAccessListBlockNumber); @@ -88,14 +88,14 @@ public SyncPointers( } } - private static long? ReadPointer(IDb sourceDb, int metadataKey) + private static ulong? ReadPointer(IDb sourceDb, int metadataKey) { byte[]? pointerBytes = sourceDb.Get(metadataKey); return pointerBytes is null ? null : DecodePointer(pointerBytes); } - private static long DecodePointer(byte[] pointerBytes) => - new Rlp.ValueDecoderContext(pointerBytes).DecodeLong(); + private static ulong DecodePointer(byte[] pointerBytes) => + new Rlp.ValueDecoderContext(pointerBytes).DecodeULong(); private void MigrateLegacyLowestInsertedBodyNumber(IDb blocksDb) { diff --git a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs index 01ee9cf151ee..4cedc2dd3e7b 100644 --- a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs @@ -58,7 +58,7 @@ public class SyncServer : ISyncServer private readonly LruCache _recentlySuggested = new(128, 128, "recently suggested blocks"); - private readonly long _pivotNumber; + private readonly ulong _pivotNumber; private readonly Hash256 _pivotHash; private BlockHeader? _pivotHeader; private CancellationTokenSource _rangeBroadcastCts = new(); @@ -130,7 +130,7 @@ public BlockHeader? Head } } - public long LowestBlock => Math.Min(Head?.Number ?? 0, _blockTree.GetLowestBlock()); + public ulong LowestBlock => Math.Min(Head?.Number ?? 0UL, _blockTree.GetLowestBlock()); public int GetPeerCount() => _pool.PeerCount; @@ -173,7 +173,10 @@ public void AddNewBlock(Block block, ISyncPeer nodeWhoSentTheBlock) // it delivers information about the peer's chain. bool isBlockBeforeTheSyncPivot = block.Number < _pivotNumber; - bool isBlockOlderThanMaxReorgAllows = block.Number < (_blockTree.Head?.Number ?? 0) - Sync.MaxReorgLength; + ulong headNumber = _blockTree.Head?.Number ?? 0UL; + // Guard against underflow: MaxReorgLength is long but subtraction is on ulong. + bool isBlockOlderThanMaxReorgAllows = headNumber > (ulong)Sync.MaxReorgLength && + block.Number < headNumber - (ulong)Sync.MaxReorgLength; // We skip blocks that are old if (isBlockBeforeTheSyncPivot || isBlockOlderThanMaxReorgAllows) @@ -252,7 +255,8 @@ private bool ValidateSeal(Block block, ISyncPeer syncPeer) // It is important that we only do that here, after we ensured that the block is // in the range of [Head - MaxReorganizationLength, Head]. // Otherwise we could hint incorrect ranges and cause expensive cache recalculations. - _sealValidator.HintValidationRange(_sealValidatorUserGuid, block.Number - 128, block.Number + 1024); + // HintValidationRange takes long; cast is safe for realistic block heights. + _sealValidator.HintValidationRange(_sealValidatorUserGuid, (long)block.Number - 128, (long)block.Number + 1024); return _sealValidator.ValidateSeal(block.Header, true); } @@ -357,11 +361,12 @@ private void LogBlockAuthorNicely(Block block, ISyncPeer syncPeer) _logger.Info(sb.ToString()); } - public void HintBlock(Hash256 hash, long number, ISyncPeer syncPeer) + public void HintBlock(Hash256 hash, ulong number, ISyncPeer syncPeer) { if (!_gossipPolicy.CanGossipBlocks) return; - if (number > syncPeer.HeadNumber) + // number is from the peer protocol (long); HeadNumber is ulong. Guard against negative values. + if (number >= 0 && number > syncPeer.HeadNumber) { if (_logger.IsTrace) _logger.Trace($"HINT Updating header of {syncPeer} from {syncPeer.HeadNumber} {syncPeer.TotalDifficulty} to {number}"); syncPeer.HeadNumber = number; @@ -441,7 +446,7 @@ public IByteArrayList GetNodeData(IReadOnlyList keys, CancellationToken public BlockHeader? FindHeader(Hash256 hash) => _blockTree.FindHeader(hash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); - public Hash256? FindHash(long number) + public Hash256? FindHash(ulong number) { try { @@ -535,7 +540,7 @@ private void RangeBroadcast(BlockHeader earliest, BlockHeader latest, Cancellati return; } PeerInfo peerInfo = allPeers[i]; - if (peerInfo.ShouldNotifyNewRange(earliest.Number, latest.Number)) + if (peerInfo.ShouldNotifyNewRange((long)earliest.Number, (long)latest.Number)) { NotifyOfNewRange(peerInfo, earliest, latest); Interlocked.Increment(ref counter); diff --git a/src/Nethermind/Nethermind.Synchronization/TotalDifficultyBetterPeerStrategy.cs b/src/Nethermind/Nethermind.Synchronization/TotalDifficultyBetterPeerStrategy.cs index e770a8e368ee..afc7d7d2dd82 100644 --- a/src/Nethermind/Nethermind.Synchronization/TotalDifficultyBetterPeerStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/TotalDifficultyBetterPeerStrategy.cs @@ -10,15 +10,15 @@ public class TotalDifficultyBetterPeerStrategy(ILogManager logManager) : IBetter { private readonly ILogger _logger = logManager.GetClassLogger(); - public int Compare(in (UInt256? TotalDifficulty, long Number) valueX, in (UInt256? TotalDifficulty, long Number) valueY) => + public int Compare(in (UInt256? TotalDifficulty, ulong Number) valueX, in (UInt256? TotalDifficulty, ulong Number) valueY) => valueX.TotalDifficulty is { } xTotalDifficulty && valueY.TotalDifficulty is { } yTotalDifficulty ? xTotalDifficulty.CompareTo(yTotalDifficulty) : valueX.Number.CompareTo(valueY.Number); - public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestBlock) => + public bool IsBetterThanLocalChain(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestBlock) => Compare(bestPeerInfo, bestBlock) > 0; - public bool IsDesiredPeer(in (UInt256? TotalDifficulty, long Number) bestPeerInfo, in (UInt256 TotalDifficulty, long Number) bestHeader) + public bool IsDesiredPeer(in (UInt256? TotalDifficulty, ulong Number) bestPeerInfo, in (UInt256 TotalDifficulty, ulong Number) bestHeader) { bool desiredPeerKnown = IsBetterThanLocalChain(bestPeerInfo, bestHeader) || (bestPeerInfo.TotalDifficulty is not null && bestPeerInfo.TotalDifficulty == bestHeader.TotalDifficulty && bestPeerInfo.Number > bestHeader.Number); diff --git a/src/Nethermind/Nethermind.Taiko.Test/BlockInvalidTxExecutorZkTests.cs b/src/Nethermind/Nethermind.Taiko.Test/BlockInvalidTxExecutorZkTests.cs index 07d36ba57032..d0e066117529 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/BlockInvalidTxExecutorZkTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/BlockInvalidTxExecutorZkTests.cs @@ -12,7 +12,6 @@ using Nethermind.Evm.State; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Taiko.BlockTransactionExecutors; using Nethermind.Taiko.ZkGas; @@ -44,7 +43,7 @@ private static Block MakeBlock(params Transaction[] txs) => /// Builds a valid (non-blob) transaction stub with a given nonce (for uniqueness). private static Transaction MakeTx(ulong nonce = 0) => - Build.A.Transaction.WithSenderAddress(TestItem.AddressA).WithNonce((UInt256)nonce).TestObject; + Build.A.Transaction.WithSenderAddress(TestItem.AddressA).WithNonce(nonce).TestObject; /// Builds a blob transaction stub. private static Transaction MakeBlobTx() => diff --git a/src/Nethermind/Nethermind.Taiko.Test/CertainBatchLookupTests.cs b/src/Nethermind/Nethermind.Taiko.Test/CertainBatchLookupTests.cs index 8fea5d8002a5..1719ea13a56a 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/CertainBatchLookupTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/CertainBatchLookupTests.cs @@ -260,7 +260,7 @@ public void TestBatchLookup_UnfilteredNetworks(ulong chainId) public void TestBatchLookup_MainnetScanPathBelowThresholdReturnsNull() { UInt256 batchId = 1; - long blockNumber = (long)(ZkGasSchedule.TaikoMainnetBatchLookupThreshold - 1); + ulong blockNumber = ZkGasSchedule.TaikoMainnetBatchLookupThreshold - 1; // Shasta extraData layout: [basefeeSharingPctg=0][proposalId=batchId, 6 bytes big-endian]. byte[] extraData = new byte[TaikoHeaderHelper.ShastaExtraDataLen]; @@ -283,7 +283,7 @@ public void TestBatchLookup_MainnetScanPathBelowThresholdReturnsNull() // Write the L1Origin so a missing gate would yield a non-null Data on lastL1OriginByBatchID, // proving the gate (not a missing record) is what produces the null result. - UInt256 blockId = (UInt256)(ulong)blockNumber; + UInt256 blockId = (UInt256)blockNumber; _store.WriteL1Origin(blockId, new L1Origin(blockId, Hash256.Zero, 3, Hash256.Zero, null)); // Deliberately do NOT WriteBatchToLastBlockID — forces the scan fallback. diff --git a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs index cc85528186ad..7f79ff892ecb 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs @@ -81,13 +81,15 @@ public void Setup() _surgeConfig); } - private void SetupBlockFinderWithBlocks(long headBlockNumber, long gasUsed = 1000000) + private void SetupBlockFinderWithBlocks(ulong headBlockNumber, ulong gasUsed = 1000000) { Block headBlock = Build.A.Block.WithNumber(headBlockNumber).WithGasUsed(gasUsed).TestObject; _blockFinder.Head.Returns(headBlock); - for (long i = headBlockNumber; i >= Math.Max(0, headBlockNumber - _surgeConfig.L2GasUsageWindowSize + 1); i--) + for (ulong i = headBlockNumber; i >= Math.Max(0UL, headBlockNumber - (ulong)_surgeConfig.L2GasUsageWindowSize + 1UL); i--) { + // Safe: i is bounded to [headBlockNumber - windowSize + 1, headBlockNumber], + // which is always a valid non-negative block range for the test inputs used. _blockFinder.FindBlock(i, BlockTreeLookupOptions.RequireCanonical) .Returns(Build.A.Block.WithNumber(i).WithGasUsed(gasUsed).TestObject); } @@ -314,12 +316,13 @@ public async ValueTask GetGasPriceEstimate_ComputesAverageGasFromRecentBlocks() SetupInboxContractMocks(); // Scenario 1: Low gas usage blocks (average = 100k) - const long headBlockNumber1 = 10; + const ulong headBlockNumber1 = 10; _blockFinder.Head.Returns(Build.A.Block.WithNumber(headBlockNumber1).WithGasUsed(100000).TestObject); for (int i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) { - _blockFinder.FindBlock(headBlockNumber1 - i, BlockTreeLookupOptions.RequireCanonical) - .Returns(Build.A.Block.WithNumber(headBlockNumber1 - i).WithGasUsed(100000).TestObject); + // Safe: i < L2GasUsageWindowSize (5) and headBlockNumber1 = 10, so result >= 5; no underflow. + _blockFinder.FindBlock(headBlockNumber1 - (ulong)i, BlockTreeLookupOptions.RequireCanonical) + .Returns(Build.A.Block.WithNumber(headBlockNumber1 - (ulong)i).WithGasUsed(100000).TestObject); } SurgeGasPriceOracle oracleLowGas = new( @@ -327,12 +330,13 @@ public async ValueTask GetGasPriceEstimate_ComputesAverageGasFromRecentBlocks() UInt256 gasPriceLowUsage = await oracleLowGas.GetGasPriceEstimate(); // Scenario 2: High gas usage blocks (average = 500k) - const long headBlockNumber2 = 20; + const ulong headBlockNumber2 = 20; _blockFinder.Head.Returns(Build.A.Block.WithNumber(headBlockNumber2).WithGasUsed(500000).TestObject); for (int i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) { - _blockFinder.FindBlock(headBlockNumber2 - i, BlockTreeLookupOptions.RequireCanonical) - .Returns(Build.A.Block.WithNumber(headBlockNumber2 - i).WithGasUsed(500000).TestObject); + // Safe: i < L2GasUsageWindowSize (5) and headBlockNumber2 = 20, so result >= 15; no underflow. + _blockFinder.FindBlock(headBlockNumber2 - (ulong)i, BlockTreeLookupOptions.RequireCanonical) + .Returns(Build.A.Block.WithNumber(headBlockNumber2 - (ulong)i).WithGasUsed(500000).TestObject); } SurgeGasPriceOracle oracleHighGas = new( diff --git a/src/Nethermind/Nethermind.Taiko.Test/TaikoBeaconSyncTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TaikoBeaconSyncTests.cs index 58a58669d517..94c153a7a156 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TaikoBeaconSyncTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TaikoBeaconSyncTests.cs @@ -22,10 +22,10 @@ public class TaikoBeaconSyncTests [TestCaseSource(nameof(ShouldBeInBeaconHeadersCases))] public bool ShouldBeInBeaconHeaders_HandlesBrokenBestSuggestedHeader( bool innerReturns, - long? libhNumber, - long bestSuggestedHeader, - long headNumber, - long pivotDestination, + ulong? libhNumber, + ulong bestSuggestedHeader, + ulong headNumber, + ulong pivotDestination, bool isKnownBlock, bool strictMode) { @@ -68,7 +68,7 @@ public void OtherMembers_DelegateToInner() inner.ShouldBeInBeaconModeControl().Returns(true); inner.IsBeaconSyncFinished(null).Returns(true); inner.MergeTransitionFinished.Returns(true); - inner.GetTargetBlockHeight().Returns(123L); + inner.GetTargetBlockHeight().Returns(123UL); inner.GetFinalizedHash().Returns(TestItem.KeccakA); inner.GetHeadBlockHash().Returns(TestItem.KeccakB); @@ -87,34 +87,34 @@ public void OtherMembers_DelegateToInner() Assert.That(sut.ShouldBeInBeaconModeControl(), Is.True); Assert.That(sut.IsBeaconSyncFinished(null), Is.True); Assert.That(sut.MergeTransitionFinished, Is.True); - Assert.That(sut.GetTargetBlockHeight(), Is.EqualTo(123L)); + Assert.That(sut.GetTargetBlockHeight(), Is.EqualTo(123UL)); Assert.That(sut.GetFinalizedHash(), Is.EqualTo(TestItem.KeccakA)); Assert.That(sut.GetHeadBlockHash(), Is.EqualTo(TestItem.KeccakB)); }); } - private static IBlockTree BlockTreeWith(long? libhNumber, long bestSuggestedHeader, long headNumber, bool isKnownBlock) + private static IBlockTree BlockTreeWith(ulong? libhNumber, ulong bestSuggestedHeader, ulong headNumber, bool isKnownBlock) { IBlockTree blockTree = Substitute.For(); - BlockHeader? libh = libhNumber is long l + BlockHeader? libh = libhNumber is ulong l ? Build.A.BlockHeader.WithNumber(l).WithParent(Build.A.BlockHeader.WithNumber(l - 1).TestObject).TestObject : null; blockTree.LowestInsertedBeaconHeader.Returns(libh); blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber(bestSuggestedHeader).TestObject); blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(headNumber).TestObject).TestObject); - blockTree.IsKnownBlock(Arg.Any(), Arg.Any()).Returns(isKnownBlock); + blockTree.IsKnownBlock(Arg.Any(), Arg.Any()).Returns(isKnownBlock); return blockTree; } private static IEnumerable ShouldBeInBeaconHeadersCases() { // Inner says we should not be in beacon headers. Decorator must agree. - yield return new TestCaseData(false, (long?)100L, 50L, 50L, 1L, true, false) + yield return new TestCaseData(false, (ulong?)100UL, 50UL, 50UL, 1UL, true, false) .Returns(false) .SetName("InnerSaysNo_DecoratorSaysNo"); // Inner says yes but no LIBH yet — defer to inner (return true). - yield return new TestCaseData(true, (long?)null, 0L, 0L, 1L, false, false) + yield return new TestCaseData(true, (ulong?)null, 0UL, 0UL, 1UL, false, false) .Returns(true) .SetName("LibhNull_DefersToInner"); @@ -122,37 +122,37 @@ private static IEnumerable ShouldBeInBeaconHeadersCases() // never bumped (broken on Taiko), LIBH stops at Head+1 because headers feed truncated // at the merge point, PivotDestinationNumber is below Head. Without the fix the inner // returns true here; the decorator must override to false using Head.Number. - yield return new TestCaseData(true, (long?)17728L, 0L, 17727L, 17664L, true, false) + yield return new TestCaseData(true, (ulong?)17728UL, 0UL, 17727UL, 17664UL, true, false) .Returns(false) .SetName("TaikoStallCase_BestSuggestedHeaderZero_ButHeadAdvanced_OverridesToFalse"); // LIBH walks all the way down to PivotDestinationNumber. This is the path the first // cold-start sync takes. Behavior must be the same as before the fix. - yield return new TestCaseData(true, (long?)1L, 0L, 0L, 1L, true, false) + yield return new TestCaseData(true, (ulong?)1UL, 0UL, 0UL, 1UL, true, false) .Returns(false) .SetName("ReachedDestination_FirstColdStartSync_NotInBeaconHeaders"); // LIBH still above destination AND chain not merged (mid-sync). Decorator should // agree with inner that we're still in headers stage. - yield return new TestCaseData(true, (long?)5000L, 0L, 0L, 1L, false, false) + yield return new TestCaseData(true, (ulong?)5000UL, 0UL, 0UL, 1UL, false, false) .Returns(true) .SetName("MidSync_StillNeedHeaders"); // StrictMode disables the chainMerged shortcut. With LIBH > destination, the decorator // must NOT override even if Head reaches LIBH-1. - yield return new TestCaseData(true, (long?)17728L, 0L, 17727L, 17664L, true, true) + yield return new TestCaseData(true, (ulong?)17728UL, 0UL, 17727UL, 17664UL, true, true) .Returns(true) .SetName("StrictMode_DoesNotShortCircuitOnChainMerged"); // ParentHash not known: chainMerged cannot be true even if Head.Number is high enough. - yield return new TestCaseData(true, (long?)17728L, 0L, 17727L, 17664L, false, false) + yield return new TestCaseData(true, (ulong?)17728UL, 0UL, 17727UL, 17664UL, false, false) .Returns(true) .SetName("ParentHashUnknown_NoOverride"); // Mainnet-like case (BestSuggestedHeader correctly tracks Head). LIBH at Head+1, // BestSuggestedHeader == Head. The fix must not regress this — same behavior as // before (chainMerged is true via BestSuggestedHeader, so the override is a no-op). - yield return new TestCaseData(true, (long?)17728L, 17727L, 17727L, 17664L, true, false) + yield return new TestCaseData(true, (ulong?)17728UL, 17727UL, 17727UL, 17664UL, true, false) .Returns(false) .SetName("MainnetLikeCase_BestSuggestedHeaderTracksHead_StillReturnsFalse"); } diff --git a/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs index 5e90098cad48..b0371e07972c 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs @@ -30,7 +30,7 @@ public void AddTransitions_skips_genesis_time_Shasta_and_Unzen() UnzenTimestamp = 0x69df3615, }; - SortedSet blockNumbers = []; + SortedSet blockNumbers = []; SortedSet timestamps = []; parameters.AddTransitions(blockNumbers, timestamps); @@ -52,12 +52,12 @@ public void AddTransitions_includes_post_genesis_block_transitions() ShastaTimestamp = 0x69CE6BD4, }; - SortedSet blockNumbers = []; + SortedSet blockNumbers = []; SortedSet timestamps = []; parameters.AddTransitions(blockNumbers, timestamps); - Assert.That(blockNumbers, Is.EqualTo(new[] { 0x836c0L, 0x11CAB0L })); + Assert.That(blockNumbers, Is.EqualTo(new[] { 0x836c0UL, 0x11CAB0UL })); Assert.That(timestamps, Is.EqualTo(new[] { 0x69CE6BD4ul })); } @@ -66,7 +66,7 @@ public void AddTransitions_handles_all_null_transitions() { TaikoChainSpecEngineParameters parameters = new(); - SortedSet blockNumbers = []; + SortedSet blockNumbers = []; SortedSet timestamps = []; parameters.AddTransitions(blockNumbers, timestamps); @@ -84,7 +84,7 @@ public void AddTransitions_filters_genesis_time_Rip7728_and_L1StaticCall() L1StaticCallTransitionTimestamp = 0, }; - SortedSet blockNumbers = []; + SortedSet blockNumbers = []; SortedSet timestamps = []; parameters.AddTransitions(blockNumbers, timestamps); diff --git a/src/Nethermind/Nethermind.Taiko.Test/TaikoEthSyncingInfoTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TaikoEthSyncingInfoTests.cs index a3bee76d36fa..6c7f3aaa1077 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TaikoEthSyncingInfoTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TaikoEthSyncingInfoTests.cs @@ -18,7 +18,7 @@ namespace Nethermind.Taiko.Test; public class TaikoEthSyncingInfoTests { [TestCaseSource(nameof(GetFullInfoCases))] - public SyncingResult GetFullInfo_ReturnsExpected(long? suggested, long? beacon, long? head, SyncMode innerMode) + public SyncingResult GetFullInfo_ReturnsExpected(ulong? suggested, ulong? beacon, ulong? head, SyncMode innerMode) { IEthSyncingInfo inner = Substitute.For(); inner.SyncMode.Returns(innerMode); @@ -33,8 +33,8 @@ public void UpdateAndGetSyncTime_TracksTaikoIsSyncing_NotInner() // IsSyncing(), which is `false` during the very plateau this decorator exists // to fix. The stopwatch must run on the decorator's corrected IsSyncing(). IBlockTree blockTree = Substitute.For(); - blockTree.BestSuggestedBeaconHeader.Returns(Build.A.BlockHeader.WithNumber(1000L).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(500L).TestObject).TestObject); + blockTree.BestSuggestedBeaconHeader.Returns(Build.A.BlockHeader.WithNumber(1000UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(500UL).TestObject).TestObject); IEthSyncingInfo inner = Substitute.For(); TaikoEthSyncingInfo info = new(blockTree, inner); @@ -44,7 +44,7 @@ public void UpdateAndGetSyncTime_TracksTaikoIsSyncing_NotInner() Assert.That(info.UpdateAndGetSyncTime(), Is.GreaterThan(TimeSpan.Zero), "subsequent call while syncing: elapsed"); // Head catches the beacon pivot — decorator now reports not-syncing, stopwatch stops. - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(1000L).TestObject).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(1000UL).TestObject).TestObject); Assert.That(info.UpdateAndGetSyncTime(), Is.EqualTo(TimeSpan.Zero), "after catch-up: stops"); inner.DidNotReceive().UpdateAndGetSyncTime(); } @@ -58,12 +58,12 @@ public void SyncMode_DelegatesToInner() Assert.That(new TaikoEthSyncingInfo(Substitute.For(), inner).SyncMode, Is.EqualTo(SyncMode.WaitingForBlock)); } - private static IBlockTree BlockTreeWith(long? suggested, long? beacon, long? head) + private static IBlockTree BlockTreeWith(ulong? suggested, ulong? beacon, ulong? head) { IBlockTree blockTree = Substitute.For(); - blockTree.FindBestSuggestedHeader().Returns(suggested is long s ? Build.A.BlockHeader.WithNumber(s).TestObject : null); - blockTree.BestSuggestedBeaconHeader.Returns(beacon is long b ? Build.A.BlockHeader.WithNumber(b).TestObject : null); - blockTree.Head.Returns(head is long h ? Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(h).TestObject).TestObject : null); + blockTree.FindBestSuggestedHeader().Returns(suggested is ulong s ? Build.A.BlockHeader.WithNumber(s).TestObject : null); + blockTree.BestSuggestedBeaconHeader.Returns(beacon is ulong b ? Build.A.BlockHeader.WithNumber(b).TestObject : null); + blockTree.Head.Returns(head is ulong h ? Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(h).TestObject).TestObject : null); return blockTree; } @@ -72,21 +72,21 @@ private static IEnumerable GetFullInfoCases() // Regression: BeaconSync inserts headers via BestSuggestedBeaconHeader only, so // FindBestSuggestedHeader can lag (or be null) even after Head reaches the pivot. // Before the fix, isSyncing stuck at true once Head caught up. - yield return new TestCaseData((long?)null, (long?)1000L, (long?)1000L, SyncMode.None) + yield return new TestCaseData((ulong?)null, (ulong?)1000UL, (ulong?)1000UL, SyncMode.None) .Returns(SyncingResult.NotSyncing) .SetName("BeaconPivot_HeadCaughtUp_NotSyncing"); - yield return new TestCaseData((long?)null, (long?)1000L, (long?)500L, SyncMode.FastSync) - .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 500L, HighestBlock = 1000L, SyncMode = SyncMode.FastSync }) + yield return new TestCaseData((ulong?)null, (ulong?)1000UL, (ulong?)500UL, SyncMode.FastSync) + .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 500UL, HighestBlock = 1000UL, SyncMode = SyncMode.FastSync }) .SetName("BeaconPivot_HeadBehind_Syncing"); - yield return new TestCaseData((long?)null, (long?)null, (long?)null, SyncMode.None) - .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 0L, HighestBlock = 0L, SyncMode = SyncMode.None }) + yield return new TestCaseData((ulong?)null, (ulong?)null, (ulong?)null, SyncMode.None) + .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 0UL, HighestBlock = 0UL, SyncMode = SyncMode.None }) .SetName("Genesis_Syncing"); // Both pointers populated — decorator must take max(suggested, beacon). - yield return new TestCaseData((long?)2000L, (long?)1000L, (long?)500L, SyncMode.None) - .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 500L, HighestBlock = 2000L, SyncMode = SyncMode.None }) + yield return new TestCaseData((ulong?)2000UL, (ulong?)1000UL, (ulong?)500UL, SyncMode.None) + .Returns(new SyncingResult { IsSyncing = true, CurrentBlock = 500UL, HighestBlock = 2000UL, SyncMode = SyncMode.None }) .SetName("TakesMaxOfBothPointers"); } } diff --git a/src/Nethermind/Nethermind.Taiko.Test/Tdx/TdxRpcModuleTests.cs b/src/Nethermind/Nethermind.Taiko.Test/Tdx/TdxRpcModuleTests.cs index 4493d56b785f..a04ea974643e 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/Tdx/TdxRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/Tdx/TdxRpcModuleTests.cs @@ -61,7 +61,7 @@ public async Task SignBlockHeader_returns_error_when_block_not_found() { _config.TdxEnabled.Returns(true); _tdxService.IsBootstrapped.Returns(true); - _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns((BlockHeader?)null); + _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns((BlockHeader?)null); ResultWrapper result = await _rpcModule.taiko_tdxSignBlockHeader(new BlockParameter(1)); @@ -76,7 +76,7 @@ public async Task SignBlockHeader_returns_signature_when_successful() _tdxService.IsBootstrapped.Returns(true); BlockHeader header = Build.A.BlockHeader.WithStateRoot(TestItem.KeccakA).TestObject; - _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns(header); + _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns(header); TdxBlockHeaderSignature signature = new() { @@ -101,7 +101,7 @@ public async Task SignBlockHeader_returns_error_on_signing_failure() _tdxService.IsBootstrapped.Returns(true); BlockHeader header = Build.A.BlockHeader.TestObject; - _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns(header); + _blockFinder.FindHeader(Arg.Any(), Arg.Any()).Returns(header); _tdxService.SignBlockHeader(header).Returns(_ => throw new TdxException("Signing failed")); ResultWrapper result = await _rpcModule.taiko_tdxSignBlockHeader(new BlockParameter(1)); diff --git a/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs index c1aa8ce88ff2..3bb88e685536 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs @@ -60,7 +60,7 @@ public void TearDown() => [TestCaseSource(nameof(FeesDistributionTests))] public void Fees_distributed_correctly(byte basefeeSharingPct, UInt256 goesToTreasury, UInt256 goesToBeneficiary, ulong gasPrice) { - long gasLimit = 100000; + ulong gasLimit = 100000; Address beneficiaryAddress = TestItem.AddressC; Transaction tx = Build.A.Transaction @@ -119,7 +119,7 @@ static object[] Typed(int basefeeSharingPct, ulong goesToTreasury, ulong goesToB [TestCase(false)] public void Transaction_tip_and_base_fee_handling(bool isAnchorTx) { - long gasLimit = 21000; + ulong gasLimit = 21000; UInt256 gasPrice = 20; UInt256 baseFee = 5; UInt256 tipFee = gasPrice - baseFee; diff --git a/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs index c9cb92adefc5..375aab1831a2 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs @@ -41,7 +41,7 @@ public int[][] Test_TxLists_AreConstructed( txPool.GetPendingTransactionsBySender().ReturnsForAnyArgs(transactions); IBlockFinder blockFinder = Substitute.For(); - Block block = Build.A.Block.WithHeader(Build.A.BlockHeader.WithGasLimit((long)blockGasLimit).TestObject).TestObject; + Block block = Build.A.Block.WithHeader(Build.A.BlockHeader.WithGasLimit(blockGasLimit).TestObject).TestObject; blockFinder.Head.Returns(block); BlockExecutionContext? currentContext = null; @@ -178,10 +178,10 @@ public void MaxGasLimitRatio_FiltersHighGasLimitTransactions(int maxGasLimitRati Assert.That(totalTxCount, Is.EqualTo(expectedTxCount)); } - [TestCase(21_000, 120, 0, 2, TestName = "Batch is full by bytes")] - [TestCase(2_100_000, 100_000, 10, 1, TestName = "Surge filter rejects transaction")] + [TestCase(21_000UL, 120, 0, 2, TestName = "Batch is full by bytes")] + [TestCase(2_100_000UL, 100_000, 10, 1, TestName = "Surge filter rejects transaction")] public void GasUsed_IsNotInflated_WhenTxIsRejectedAfterExecution( - int tx1GasLimit, int maxBytesPerTxList, + ulong tx1GasLimit, int maxBytesPerTxList, int surgeMaxGasLimitRatio, int expectedBatchCount) { // tx1 is rejected after successful execution, tx2 is accepted diff --git a/src/Nethermind/Nethermind.Taiko/BlockMetadata.cs b/src/Nethermind/Nethermind.Taiko/BlockMetadata.cs index aa0e44fe736b..d07c18e9a91c 100644 --- a/src/Nethermind/Nethermind.Taiko/BlockMetadata.cs +++ b/src/Nethermind/Nethermind.Taiko/BlockMetadata.cs @@ -13,7 +13,7 @@ public class BlockMetadata { public required Address Beneficiary { get; set; } - public required long GasLimit { get; set; } + public required ulong GasLimit { get; set; } public required ulong Timestamp { get; set; } public required Hash256 MixHash { get; set; } diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs b/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs index ef24fa99f999..44cdc140680d 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs @@ -194,14 +194,14 @@ private ulong GetAverageGasUsagePerBlock() ulong totalGasUsed = 0; int count = 0; - long currentBlockNumber = headBlock.Number; + ulong currentBlockNumber = headBlock.Number; while (count < _surgeConfig.L2GasUsageWindowSize && currentBlockNumber >= 0) { Block? block = _blockFinder.FindBlock(currentBlockNumber, BlockTreeLookupOptions.RequireCanonical); if (block != null) { - totalGasUsed += (ulong)block.GasUsed; + totalGasUsed += block.GasUsed; count++; } currentBlockNumber--; diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs index 29f0bc392d6c..87610f563fc3 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs @@ -198,7 +198,7 @@ public Task> engine_newPayloadV2(TaikoExecutionPa beneficiary, UInt256.Zero, head!.Number + 1, - (long)blockMaxGasLimit, + blockMaxGasLimit, head.Timestamp + 1, []) { @@ -220,7 +220,7 @@ private PreBuiltTxList[] ProcessTransactions(ITransactionProcessor txProcessor, void CommitAndDisposeBatch(Batch batch) { Batches.Add(new PreBuiltTxList(batch.Transactions.Select(tx => TransactionForRpc.FromTransaction(tx)).ToArray(), - (ulong)blockHeader.GasUsed, + blockHeader.GasUsed, batch.GetCompressedTxsLength())); blockHeader.GasUsed = 0; batch.Dispose(); @@ -230,7 +230,7 @@ void CommitAndDisposeBatch(Batch batch) Batch batch = new(maxBytesPerTxList, txSource.Length, txDecoder); - void Restore(Snapshot snapshot, long gasUsed) + void Restore(Snapshot snapshot, ulong gasUsed) { worldState.Restore(snapshot); blockHeader.GasUsed = gasUsed; @@ -242,7 +242,7 @@ void Restore(Snapshot snapshot, long gasUsed) { Transaction tx = txSource[i]; Snapshot snapshot = worldState.TakeSnapshot(true); - long gasUsedBefore = blockHeader.GasUsed; + ulong gasUsedBefore = blockHeader.GasUsed; try { @@ -271,7 +271,7 @@ void Restore(Snapshot snapshot, long gasUsed) } // For Surge, filter out any transaction with very high gas limit - if (surgeConfig.MaxGasLimitRatio > 0 && tx.GasLimit > tx.SpentGas * surgeConfig.MaxGasLimitRatio) + if (surgeConfig.MaxGasLimitRatio > 0 && tx.GasLimit > tx.SpentGas * (ulong)surgeConfig.MaxGasLimitRatio) { Restore(snapshot, gasUsedBefore); while (i < txSource.Length && txSource[i].SenderAddress == tx.SenderAddress) i++; diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoForkchoiceUpdatedHandler.cs index ecddeee2feb8..740cbb9ab2aa 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoForkchoiceUpdatedHandler.cs @@ -63,7 +63,7 @@ protected override bool IsOnMainChainBehindFinalized(BlockHeader newHeadHeader, // on finalized (Casper FFG monotonicity) and safe (safe >= finalized) don't apply. Keep the // ancestry check via the base call; pass lowerBound=0 to disable the numeric bound. protected override ResultWrapper? RejectIfInconsistent( - BlockHeader? header, long lowerBound, string label, BlockHeader newHeadHeader, string requestStr) + BlockHeader? header, ulong lowerBound, string label, BlockHeader newHeadHeader, string requestStr) => base.RejectIfInconsistent(header, 0, label, newHeadHeader, requestStr); protected override BlockHeader? ValidateBlockHash(ref Hash256 blockHash, out string? errorMessage, bool skipZeroHash = true) diff --git a/src/Nethermind/Nethermind.Taiko/TaikoBeaconHeadAdvancer.cs b/src/Nethermind/Nethermind.Taiko/TaikoBeaconHeadAdvancer.cs index c0bac2f7ff9e..079707881174 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoBeaconHeadAdvancer.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoBeaconHeadAdvancer.cs @@ -103,7 +103,7 @@ private async Task TryAdvanceOnceAsync(CancellationToken ct) // Take the higher of cached driver target and BestSuggestedBeaconHeader so // Head keeps climbing on headers that arrive between driver FCUs. Block? target = null; - long bestNumber = -1L; + ulong? bestNumber = null; Hash256? cachedHash = _blockCacheService.HeadBlockHash; if (cachedHash is not null && cachedHash != Keccak.Zero) @@ -117,30 +117,34 @@ private async Task TryAdvanceOnceAsync(CancellationToken ct) } BlockHeader? beaconHead = _blockTree.BestSuggestedBeaconHeader; - if (beaconHead is not null && beaconHead.Hash is not null && beaconHead.Number > bestNumber) + if (beaconHead is not null) { - Block? beaconBlock = _blockTree.FindBlock(beaconHead.Hash, BlockTreeLookupOptions.DoNotCreateLevelIfMissing); - if (beaconBlock is not null) + Hash256? beaconHash = beaconHead.Hash; + if (beaconHash is not null && (bestNumber is null || beaconHead.Number > bestNumber.Value)) { - target = beaconBlock; - bestNumber = beaconBlock.Number; + Block? beaconBlock = _blockTree.FindBlock(beaconHash, BlockTreeLookupOptions.DoNotCreateLevelIfMissing); + if (beaconBlock is not null) + { + target = beaconBlock; + bestNumber = beaconBlock.Number; + } } } if (target is null) return; - long headNumber = _blockTree.Head?.Number ?? 0; + ulong headNumber = _blockTree.Head?.Number ?? 0UL; if (target.Number <= headNumber) return; // 2. Enqueue any unprocessed ancestor for processing. The processing queue is FIFO and // BlockchainProcessor walks back to the nearest canonical ancestor automatically, so // enqueuing the highest unprocessed block is enough — but we walk explicitly so that // progress logs show one-by-one advancement. - long firstToEnqueue = headNumber + 1; - long lastToEnqueue = target.Number; + ulong firstToEnqueue = headNumber + 1; + ulong lastToEnqueue = target.Number; int enqueued = 0; - for (long n = firstToEnqueue; n <= lastToEnqueue; n++) + for (ulong n = firstToEnqueue; n <= lastToEnqueue; n++) { if (ct.IsCancellationRequested) break; diff --git a/src/Nethermind/Nethermind.Taiko/TaikoBeaconSync.cs b/src/Nethermind/Nethermind.Taiko/TaikoBeaconSync.cs index 5b619e3a8d85..7e9765c7b9e2 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoBeaconSync.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoBeaconSync.cs @@ -43,16 +43,17 @@ public bool ShouldBeInBeaconHeaders() BlockHeader? lowestInsertedBeaconHeader = blockTree.LowestInsertedBeaconHeader; if (lowestInsertedBeaconHeader is null) return true; - long suggested = blockTree.BestSuggestedHeader?.Number ?? long.MinValue; - long head = blockTree.Head?.Number ?? long.MinValue; - long bestKnownNumber = Math.Max(suggested, head); - // Mirror the original `?? long.MaxValue` sentinel: with no header at all the + ulong suggested = blockTree.BestSuggestedHeader?.Number ?? 0UL; + ulong head = blockTree.Head?.Number ?? 0UL; + ulong bestKnownNumber = Math.Max(suggested, head); + // Mirror the original `?? ulong.MaxValue` sentinel: with no header at all the // numeric comparison should pass trivially so chainMerged is gated only by IsKnownBlock. - if (bestKnownNumber == long.MinValue) bestKnownNumber = long.MaxValue; + if (bestKnownNumber == 0UL) bestKnownNumber = ulong.MaxValue; bool reachedDestination = lowestInsertedBeaconHeader.Number <= beaconPivot.PivotDestinationNumber; bool chainMerged = !syncConfig.StrictMode + && lowestInsertedBeaconHeader.Number > 0UL && (lowestInsertedBeaconHeader.Number - 1) <= bestKnownNumber && blockTree.IsKnownBlock(lowestInsertedBeaconHeader.Number - 1, lowestInsertedBeaconHeader.ParentHash!); @@ -82,7 +83,7 @@ public bool ShouldBeInBeaconHeaders() public bool MergeTransitionFinished => inner.MergeTransitionFinished; /// - public long? GetTargetBlockHeight() => inner.GetTargetBlockHeight(); + public ulong? GetTargetBlockHeight() => inner.GetTargetBlockHeight(); /// public Hash256? GetFinalizedHash() => inner.GetFinalizedHash(); diff --git a/src/Nethermind/Nethermind.Taiko/TaikoBlockValidator.cs b/src/Nethermind/Nethermind.Taiko/TaikoBlockValidator.cs index c871a19f07af..53c7416687f2 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoBlockValidator.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoBlockValidator.cs @@ -31,8 +31,8 @@ public class TaikoBlockValidator( public static readonly Address GoldenTouchAccount = new("0x0000777735367b36bC9B61C50022d9D0700dB4Ec"); - private const long AnchorGasLimit = 250_000; - private const long AnchorV3V4GasLimit = 1_000_000; + private const ulong AnchorGasLimit = 250_000UL; + private const ulong AnchorV3V4GasLimit = 1_000_000UL; // Blob transactions are explicitly rejected in ValidateTransactions below; no extra EIP-4844 field // validation is needed on Taiko L2. @@ -93,7 +93,7 @@ private bool ValidateAnchorTransaction(Transaction tx, Block block, ITaikoReleas return false; } - if (!tx.ValueRef.IsZero) + if (tx.ValueRef != 0) { errorMessage = "Anchor transaction must have value of 0"; return false; diff --git a/src/Nethermind/Nethermind.Taiko/TaikoEthSyncingInfo.cs b/src/Nethermind/Nethermind.Taiko/TaikoEthSyncingInfo.cs index 3f91148d8f97..5eefec3543eb 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoEthSyncingInfo.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoEthSyncingInfo.cs @@ -34,10 +34,10 @@ public sealed class TaikoEthSyncingInfo( public SyncingResult GetFullInfo() { - long suggestedHeader = blockTree.FindBestSuggestedHeader()?.Number ?? 0; - long beaconSuggestedHeader = blockTree.BestSuggestedBeaconHeader?.Number ?? 0; - long bestSuggestedNumber = Math.Max(suggestedHeader, beaconSuggestedHeader); - long headNumberOrZero = blockTree.Head?.Number ?? 0; + ulong suggestedHeader = blockTree.FindBestSuggestedHeader()?.Number ?? 0; + ulong beaconSuggestedHeader = blockTree.BestSuggestedBeaconHeader?.Number ?? 0; + ulong bestSuggestedNumber = Math.Max(suggestedHeader, beaconSuggestedHeader); + ulong headNumberOrZero = blockTree.Head?.Number ?? 0; bool isSyncing = bestSuggestedNumber == 0 || bestSuggestedNumber > headNumberOrZero + EthSyncingInfo.MaxDistanceForSynced; if (isSyncing) @@ -46,7 +46,7 @@ public SyncingResult GetFullInfo() { CurrentBlock = headNumberOrZero, HighestBlock = bestSuggestedNumber, - StartingBlock = 0L, + StartingBlock = 0UL, SyncMode = inner.SyncMode, IsSyncing = true }; diff --git a/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs b/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs index b78e07c8db8e..b8a3ec177787 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs @@ -130,12 +130,12 @@ private static UInt256 CalculateEip4396BaseFee(BlockHeader parent, ulong parentB } IEip1559Spec eip1559Spec = spec; - ulong parentGasTarget = (ulong)(parent.GasLimit / eip1559Spec.ElasticityMultiplier); + ulong parentGasTarget = parent.GasLimit / (ulong)eip1559Spec.ElasticityMultiplier; ulong parentAdjustedGasTarget = Math.Min(parentGasTarget * parentBlockTime / BlockTimeTarget, - (ulong)parent.GasLimit * MaxGasTargetPercentage / 100); + parent.GasLimit * MaxGasTargetPercentage / 100); // If the parent gasUsed is the same as the adjusted target, the baseFee remains unchanged - if ((ulong)parent.GasUsed == parentAdjustedGasTarget) + if (parent.GasUsed == parentAdjustedGasTarget) { return parent.BaseFeePerGas; } @@ -143,7 +143,7 @@ private static UInt256 CalculateEip4396BaseFee(BlockHeader parent, ulong parentB UInt256 baseFee; UInt256 baseFeeChangeDenominator = eip1559Spec.BaseFeeMaxChangeDenominator; - if ((ulong)parent.GasUsed > parentAdjustedGasTarget) + if (parent.GasUsed > parentAdjustedGasTarget) { // If the parent block used more gas than its target, the baseFee should increase // max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) @@ -154,7 +154,7 @@ private static UInt256 CalculateEip4396BaseFee(BlockHeader parent, ulong parentB } else { - UInt256 gasUsedDelta = (ulong)parent.GasUsed - parentAdjustedGasTarget; + UInt256 gasUsedDelta = parent.GasUsed - parentAdjustedGasTarget; feeDelta = parent.BaseFeePerGas * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator; if (feeDelta < 1) { @@ -175,7 +175,7 @@ private static UInt256 CalculateEip4396BaseFee(BlockHeader parent, ulong parentB } else { - UInt256 gasUsedDelta = parentAdjustedGasTarget - (ulong)parent.GasUsed; + UInt256 gasUsedDelta = parentAdjustedGasTarget - parent.GasUsed; feeDelta = parent.BaseFeePerGas * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator; } diff --git a/src/Nethermind/Nethermind.Taiko/TaikoPayloadAttributes.cs b/src/Nethermind/Nethermind.Taiko/TaikoPayloadAttributes.cs index 77398776dd2b..28e34af26537 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoPayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoPayloadAttributes.cs @@ -27,7 +27,7 @@ public class TaikoPayloadAttributes : PayloadAttributes private string? _taikoPayloadId; - public override long? GetGasLimit() => BlockMetadata!.GasLimit; + public override ulong? GetGasLimit() => BlockMetadata!.GasLimit; /// /// Computes the Taiko-canonical payload id so it matches the buildPayloadArgsId stored diff --git a/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecBasedSpecProvider.cs index 110960fa74df..6defa66c73fb 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecBasedSpecProvider.cs @@ -19,12 +19,12 @@ public class TaikoChainSpecBasedSpecProvider(ChainSpec chainSpec, TaikoL2Address = Address.Zero }; - protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releaseStartBlock, ulong? releaseStartTimestamp = null) + protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, ulong releaseStartBlock, ulong? releaseStartTimestamp = null) { TaikoReleaseSpec releaseSpec = (TaikoReleaseSpec)base.CreateReleaseSpec(chainSpec, releaseStartBlock, releaseStartTimestamp); - releaseSpec.IsOntakeEnabled = (chainSpecEngineParameters.OntakeTransition ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsPacayaEnabled = (chainSpecEngineParameters.PacayaTransition ?? long.MaxValue) <= releaseStartBlock; + releaseSpec.IsOntakeEnabled = (chainSpecEngineParameters.OntakeTransition ?? ulong.MaxValue) <= releaseStartBlock; + releaseSpec.IsPacayaEnabled = (chainSpecEngineParameters.PacayaTransition ?? ulong.MaxValue) <= releaseStartBlock; releaseSpec.IsShastaEnabled = (chainSpecEngineParameters.ShastaTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsUnzenEnabled = (chainSpecEngineParameters.UnzenTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.UnzenBlockZkGasLimit = chainSpecEngineParameters.UnzenBlockZkGasLimit ?? ZkGasSchedule.BlockZkGasLimit; diff --git a/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecEngineParameters.cs index 4df0f11e7611..255b1496aa36 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoSpec/TaikoChainSpecEngineParameters.cs @@ -11,8 +11,8 @@ public class TaikoChainSpecEngineParameters : IChainSpecEngineParameters { public string EngineName => SealEngineType; public string SealEngineType => Core.SealEngineType.Taiko; - public long? OntakeTransition { get; set; } - public long? PacayaTransition { get; set; } + public ulong? OntakeTransition { get; set; } + public ulong? PacayaTransition { get; set; } public ulong? ShastaTimestamp { get; set; } public ulong? UnzenTimestamp { get; set; } public ulong? UnzenBlockZkGasLimit { get; set; } @@ -23,7 +23,7 @@ public class TaikoChainSpecEngineParameters : IChainSpecEngineParameters public Address TaikoL2Address { get; set; } = new("0x1670000000000000000000000000000000010001"); - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { // Filter activations at or before genesis. Taiko chainspecs always have genesis // timestamp 0 (see taiko-alethia.json, taiko-hoodi.json, gavin's nmc-devnet.json), diff --git a/src/Nethermind/Nethermind.Taiko/TaikoSyncProgressResolver.cs b/src/Nethermind/Nethermind.Taiko/TaikoSyncProgressResolver.cs index 209d7dbbc754..7ad7f68dda93 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoSyncProgressResolver.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoSyncProgressResolver.cs @@ -31,33 +31,33 @@ public sealed class TaikoSyncProgressResolver( IBlockTree blockTree, ISyncProgressResolver inner) : ISyncProgressResolver { - public long FindBestHeader() + public ulong FindBestHeader() { - long suggested = blockTree.BestSuggestedHeader?.Number ?? 0; - long beaconSuggested = blockTree.BestSuggestedBeaconHeader?.Number ?? 0; - long head = blockTree.Head?.Number ?? 0; + ulong suggested = blockTree.BestSuggestedHeader?.Number ?? 0; + ulong beaconSuggested = blockTree.BestSuggestedBeaconHeader?.Number ?? 0; + ulong head = blockTree.Head?.Number ?? 0; return Math.Max(Math.Max(suggested, beaconSuggested), head); } - public long FindBestFullBlock() + public ulong FindBestFullBlock() { - long body = blockTree.BestSuggestedBody?.Number ?? 0; - long head = blockTree.Head?.Number ?? 0; + ulong body = blockTree.BestSuggestedBody?.Number ?? 0; + ulong head = blockTree.Head?.Number ?? 0; return Math.Max(body, head); } - public long FindBestFullState() => inner.FindBestFullState(); + public ulong FindBestFullState() => inner.FindBestFullState(); public bool IsFastBlocksHeadersFinished() => inner.IsFastBlocksHeadersFinished(); public bool IsFastBlocksBodiesFinished() => inner.IsFastBlocksBodiesFinished(); public bool IsFastBlocksReceiptsFinished() => inner.IsFastBlocksReceiptsFinished(); public bool IsFastBlockAccessListsFinished() => inner.IsFastBlockAccessListsFinished(); public bool IsLoadingBlocksFromDb() => inner.IsLoadingBlocksFromDb(); - public long FindBestProcessedBlock() => inner.FindBestProcessedBlock(); + public ulong FindBestProcessedBlock() => inner.FindBestProcessedBlock(); public UInt256 ChainDifficulty => inner.ChainDifficulty; // On Taiko TotalDifficulty is always 0; the default resolver does // best.TotalDifficulty - best.Difficulty which underflows UInt256 // when Difficulty carries the per-block zk-gas value. public UInt256? GetTotalDifficulty(Hash256 blockHash) => UInt256.Zero; public void RecalculateProgressPointers() => inner.RecalculateProgressPointers(); - public (long BlockNumber, Hash256 BlockHash) SyncPivot => inner.SyncPivot; + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot => inner.SyncPivot; } diff --git a/src/Nethermind/Nethermind.Taiko/TaikoTransactionProcessor.cs b/src/Nethermind/Nethermind.Taiko/TaikoTransactionProcessor.cs index 44533d247edd..77cad26d62da 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoTransactionProcessor.cs @@ -43,7 +43,7 @@ protected override TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, I } protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, - in TransactionSubstate substate, long spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) + in TransactionSubstate substate, ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) { UInt256 tipFees = (UInt256)spentGas * premiumPerGas; UInt256 baseFees = (UInt256)spentGas * header.BaseFeePerGas; @@ -87,7 +87,7 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec protected override TransactionResult IncrementNonce(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts) { if (tx.IsAnchorTx) - WorldState.CreateAccountIfNotExists(tx.SenderAddress!, UInt256.Zero, UInt256.Zero); + WorldState.CreateAccountIfNotExists(tx.SenderAddress!, UInt256.Zero, 0UL); return base.IncrementNonce(tx, header, spec, tracer, opts); } diff --git a/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs b/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs index 1ea8d74af80c..d9b45378cf19 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs @@ -54,7 +54,7 @@ protected override CallResult ExecutePrecompileCall( { TGasPolicy gas = state.Gas; PrecompileExtras extras = new( - remainingGas: TGasPolicy.GetRemainingGas(in gas), + remainingGas: (long)TGasPolicy.GetRemainingGas(in gas), l1Origin: _blockL1Origin); Result<(byte[] returnValue, long gasConsumed)> output; @@ -77,7 +77,7 @@ protected override CallResult ExecutePrecompileCall( // Deduct dynamic gas (e.g. actual L1 consumption) regardless of success/failure. // On L1 OOG the user loses the full gas limit — matching standard EVM sub-call semantics. long gasConsumed = output.Data.gasConsumed; - if (gasConsumed > 0 && !TGasPolicy.UpdateGas(ref gas, gasConsumed)) + if (gasConsumed > 0 && !TGasPolicy.UpdateGas(ref gas, (ulong)gasConsumed)) { return new(default, precompileSuccess: false, shouldRevert: true, EvmExceptionType.OutOfGas); } diff --git a/src/Nethermind/Nethermind.Taiko/Tdx/BlockHeaderForRpc.cs b/src/Nethermind/Nethermind.Taiko/Tdx/BlockHeaderForRpc.cs index bb1653509987..a556aad31d55 100644 --- a/src/Nethermind/Nethermind.Taiko/Tdx/BlockHeaderForRpc.cs +++ b/src/Nethermind/Nethermind.Taiko/Tdx/BlockHeaderForRpc.cs @@ -58,10 +58,10 @@ public BlockHeaderForRpc(BlockHeader header) public UInt256 Difficulty { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public long Number { get; set; } + public ulong Number { get; set; } - public long GasLimit { get; set; } - public long GasUsed { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } public UInt256 Timestamp { get; set; } public byte[] ExtraData { get; set; } = []; public Hash256? MixHash { get; set; } diff --git a/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs b/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs index 10d4ae10bbec..0ffc44591afd 100644 --- a/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs +++ b/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs @@ -29,7 +29,7 @@ public sealed class ZkGasTxTracer : TxTracer // Per-opcode step tracking private byte _currentOpcode; - private long _currentGasStart; + private ulong _currentGasStart; private bool _stepActive; // Deferred spawn opcode charging @@ -42,7 +42,7 @@ public sealed class ZkGasTxTracer : TxTracer // Precompile tracking private bool _pendingPrecompile; private byte _precompileAddressByte; - private long _precompileGasStart; + private ulong _precompileGasStart; /// /// Creates a new ZK gas tracer backed by the provided meter. @@ -58,7 +58,7 @@ public ZkGasTxTracer(ZkGasMeter meter) /// Captures the opcode and pre-execution gas for the current step. /// Flushes any previously deferred spawn opcode charge first. /// - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { FlushDeferredStep(); @@ -72,15 +72,14 @@ public override void StartOperation(int pc, Instruction opcode, long gas, in Exe /// charging until we learn whether child work was dispatched. For all other /// opcodes, charges immediately. /// - public override void ReportOperationRemainingGas(long gas) + public override void ReportOperationRemainingGas(ulong gas) { if (!_stepActive) return; _stepActive = false; - long delta = _currentGasStart - gas; - ulong rawGas = delta > 0 ? (ulong)delta : 0; + ulong rawGas = _currentGasStart > gas ? _currentGasStart - gas : 0UL; if (IsSpawnOpcode(_currentOpcode)) { @@ -106,7 +105,7 @@ public override void ReportOperationRemainingGas(long gas) /// Tracks call/create actions. Marks the deferred spawn opcode as spawned and /// captures precompile gas start for separate precompile charging. /// - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { // Mark the deferred step as having actually spawned child work if (_hasDeferredStep) @@ -126,7 +125,7 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address /// Charges precompile ZK gas when a precompile call completes successfully. /// Also flushes the deferred spawn step since the action is now resolved. ///
- public override void ReportActionEnd(long gas, ReadOnlyMemory output) + public override void ReportActionEnd(ulong gas, ReadOnlyMemory output) { FlushDeferredStep(); ChargePrecompileIfPending(gas); @@ -136,7 +135,7 @@ public override void ReportActionEnd(long gas, ReadOnlyMemory output) /// Charges precompile ZK gas when a create-type action ends. /// Also flushes the deferred spawn step since the action is now resolved. /// - public override void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + public override void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { FlushDeferredStep(); ChargePrecompileIfPending(gas); @@ -219,7 +218,7 @@ public override void ReportOperationError(EvmExceptionType error) /// Charges precompile ZK gas on revert. /// Also flushes the deferred spawn step. /// - public override void ReportActionRevert(long gas, ReadOnlyMemory output) + public override void ReportActionRevert(ulong gas, ReadOnlyMemory output) { FlushDeferredStep(); ChargePrecompileIfPending(gas); @@ -253,16 +252,16 @@ private void FlushDeferredStep() _meter.ChargeOpcode(_deferredOpcode, rawGas); } - private void ChargePrecompileIfPending(long gasRemaining) + private void ChargePrecompileIfPending(ulong gasRemaining) { if (!_pendingPrecompile) return; _pendingPrecompile = false; - long gasUsed = _precompileGasStart - gasRemaining; + ulong gasUsed = _precompileGasStart > gasRemaining ? _precompileGasStart - gasRemaining : 0UL; if (gasUsed > 0) { - _meter.ChargePrecompile(_precompileAddressByte, (ulong)gasUsed); + _meter.ChargePrecompile(_precompileAddressByte, gasUsed); } } diff --git a/src/Nethermind/Nethermind.Test.Runner/BlockchainTestStreamingTracer.cs b/src/Nethermind/Nethermind.Test.Runner/BlockchainTestStreamingTracer.cs index edef092641d5..7aaa1a123ad5 100644 --- a/src/Nethermind/Nethermind.Test.Runner/BlockchainTestStreamingTracer.cs +++ b/src/Nethermind/Nethermind.Test.Runner/BlockchainTestStreamingTracer.cs @@ -31,7 +31,7 @@ public class BlockchainTestStreamingTracer(GethTraceOptions options, Stream? out // Track metrics for test end marker private int _transactionCount; private int _blockCount; - private long _totalGasUsed; + private ulong _totalGasUsed; public bool IsTracingRewards => false; diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs index 95bf57f109bc..83a421fcbe02 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs @@ -94,7 +94,7 @@ public IEnumerable RunTests() StateTestTxTrace txTrace = txTracer.BuildResult(); txTrace.Result.Time = result.TimeInMs; txTrace.State.StateRoot = result.StateRoot; - txTrace.Result.GasUsed -= IntrinsicGasCalculator.Calculate(test.Transaction, test.Fork).Standard; + txTrace.Result.GasUsed -= (ulong)IntrinsicGasCalculator.Calculate(test.Transaction, test.Fork).Standard; WriteErr(txTrace); } diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceEntry.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceEntry.cs index 81f2372a1332..75b1c34924f5 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceEntry.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceEntry.cs @@ -15,9 +15,9 @@ public class StateTestTxTraceEntry [JsonPropertyName("op")] public byte Operation { get; set; } - public long Gas { get; set; } + public ulong Gas { get; set; } - public long GasCost { get; set; } + public ulong GasCost { get; set; } public string Memory { get; set; } diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceResult.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceResult.cs index eb247d02335e..6562b2685f1b 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceResult.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTraceResult.cs @@ -8,7 +8,7 @@ namespace Nethermind.Test.Runner public class StateTestTxTraceResult { public byte[] Output { get; set; } - public long GasUsed { get; set; } + public ulong GasUsed { get; set; } public double Time { get; set; } public string Error { get; set; } } diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs index 51b4d78aa73b..369e198d6614 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs @@ -50,7 +50,7 @@ public void MarkAsFailed(Address recipient, in GasConsumed gasSpent, byte[] outp _trace.Result.GasUsed = gasSpent; } - public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { _gasAlreadySetForCurrentOp = false; _traceEntry = new StateTestTxTraceEntry @@ -84,7 +84,7 @@ public void ReportOperationError(EvmExceptionType error) _ => "Error" }; - public void ReportOperationRemainingGas(long gas) + public void ReportOperationRemainingGas(ulong gas) { if (_traceEntry is null) return; @@ -183,21 +183,21 @@ public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnly public void ReportStorageRead(in StorageCell storageCell) => throw new NotImplementedException(); - public void ReportAction(long gas, UInt256 value, Address @from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new NotSupportedException(); + public void ReportAction(ulong gas, UInt256 value, Address @from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) => throw new NotSupportedException(); - public void ReportActionEnd(long gas, ReadOnlyMemory output) => throw new NotSupportedException(); + public void ReportActionEnd(ulong gas, ReadOnlyMemory output) => throw new NotSupportedException(); public void ReportActionError(EvmExceptionType exceptionType) => throw new NotSupportedException(); - public void ReportActionRevert(long gas, ReadOnlyMemory output) => throw new NotSupportedException(); + public void ReportActionRevert(ulong gas, ReadOnlyMemory output) => throw new NotSupportedException(); - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new NotSupportedException(); + public void ReportActionEnd(ulong gas, Address deploymentAddress, ReadOnlyMemory deployedCode) => throw new NotSupportedException(); public void ReportBlockHash(Hash256 blockHash) => throw new NotImplementedException(); public void ReportByteCode(ReadOnlyMemory byteCode) => throw new NotSupportedException(); - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + public void ReportGasUpdateForVmTrace(ulong refund, ulong gasAvailable) { } @@ -207,7 +207,7 @@ public void ReportRefundForVmTrace(long refund, long gasAvailable) public void ReportRefund(long refund) => _traceEntry.Refund = (int)refund; - public void ReportExtraGasPressure(long extraGasPressure) => throw new NotImplementedException(); + public void ReportExtraGasPressure(ulong extraGasPressure) => throw new NotImplementedException(); public void ReportAccess(IEnumerable
accessedAddresses, IEnumerable accessedStorageCells) => throw new NotImplementedException(); diff --git a/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs b/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs index eebd22c89b81..82338c01b38a 100644 --- a/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs +++ b/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs @@ -9,14 +9,14 @@ namespace Nethermind.Trie.Test; internal static class IFullTrieStoreExtensions { // Small utility to not having to double wrap - public static ICommitter BeginStateBlockCommit(this ITrieStore trieStore, long blockNumber, TrieNode? root, WriteFlags writeFlags = WriteFlags.None) + public static ICommitter BeginStateBlockCommit(this ITrieStore trieStore, ulong blockNumber, TrieNode? root, WriteFlags writeFlags = WriteFlags.None) { IBlockCommitter blockCommitter = trieStore.BeginBlockCommit(blockNumber); ICommitter stateTreeCommitter = trieStore.GetTrieStore(null).BeginCommit(root, writeFlags: writeFlags); return new CommitterWithBlockCommitter(blockCommitter, stateTreeCommitter); } - public static void CommitPatriciaTrie(this ITrieStore trieStore, long blockNumber, PatriciaTree patriciaTree) + public static void CommitPatriciaTrie(this ITrieStore trieStore, ulong blockNumber, PatriciaTree patriciaTree) { using (trieStore.BeginBlockCommit(blockNumber)) { patriciaTree.Commit(); } } diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs index 0df9e60ae8f6..f08283b307cb 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs @@ -26,8 +26,8 @@ public void Setup() [Test] public void ShouldPruneDirtyNode_should_return_true_when_block_difference_exceeds_max_block_from_persisted() { - long latestCommittedBlock = 100; - long lastPersistedBlock = latestCommittedBlock - PruneBoundary - MaxBlockFromPersisted; + ulong latestCommittedBlock = 100; + ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MaxBlockFromPersisted; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(false); @@ -37,8 +37,8 @@ public void ShouldPruneDirtyNode_should_return_true_when_block_difference_exceed [Test] public void ShouldPruneDirtyNode_should_delegate_to_base_strategy_when_block_difference_is_less_than_max_block_from_persisted() { - long latestCommittedBlock = 100; - long lastPersistedBlock = latestCommittedBlock - PruneBoundary - MaxBlockFromPersisted + 1; + ulong latestCommittedBlock = 100; + ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MaxBlockFromPersisted + 1; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs index d48f469b6d2b..e2741b6f3cde 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs @@ -27,8 +27,8 @@ public void Setup() [Test] public void ShouldPruneDirtyNode_should_return_false_when_block_difference_is_less_than_min_block_from_persisted() { - long latestCommittedBlock = 100; - long lastPersistedBlock = latestCommittedBlock - PruneBoundary - MinBlockFromPersisted + 1; + ulong latestCommittedBlock = 100; + ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MinBlockFromPersisted + 1; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); @@ -38,8 +38,8 @@ public void ShouldPruneDirtyNode_should_return_false_when_block_difference_is_le [Test] public void ShouldPruneDirtyNode_should_delegate_to_base_strategy_when_block_difference_is_greater_than_or_equal_to_min_block_from_persisted() { - long latestCommittedBlock = 100; - long lastPersistedBlock = latestCommittedBlock - PruneBoundary - MinBlockFromPersisted; + ulong latestCommittedBlock = 100; + ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MinBlockFromPersisted; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs index 9a1b28f0bc49..70284c77d6d2 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs @@ -14,7 +14,7 @@ public class TestPruningStrategy( public bool DeleteObsoleteKeys => deleteObsoleteKeys; public bool ShouldPruneDirtyNode(TrieStoreState state) { - if (pruneInterval is not null && state.LatestCommittedBlock % pruneInterval == 0) + if (pruneInterval is not null && state.LatestCommittedBlock % (ulong)pruneInterval.Value == 0) { return true; } diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs index 6c68b7bea7f4..dd5afe9b39c8 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs @@ -51,7 +51,7 @@ private TrieStore CreateTrieStore( TrackPastKeys = false // Default disable }; - finalizedStateProvider ??= new TestFinalizedStateProvider(pruningConfig.PruningBoundary); + finalizedStateProvider ??= new TestFinalizedStateProvider((ulong)pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(kvStore, scheme, requirePath: scheme == INodeStorage.KeyScheme.HalfPath), pruningStrategy, @@ -108,7 +108,7 @@ public async Task Flush_ShouldBeCalledOnEachPersist() using (IDisposable _ = fullTrieStore.BeginScope(baseBlock)) { pt.Set(TestItem.KeccakA.BytesToArray(), TestItem.Keccaks[i].BytesToArray()); - using (fullTrieStore.BeginStateBlockCommit(i + 1, trieNode)) + using (fullTrieStore.BeginStateBlockCommit((ulong)(i + 1), trieNode)) { pt.Commit(); } @@ -151,7 +151,7 @@ public void Should_always_announce_zero_when_not_persisting() long reorgBoundaryCount = 0L; using TrieStore fullTrieStore = CreateTrieStore(); - fullTrieStore.ReorgBoundaryReached += (_, e) => reorgBoundaryCount += e.BlockNumber; + fullTrieStore.ReorgBoundaryReached += (_, e) => reorgBoundaryCount += (long)e.BlockNumber; fullTrieStore.BeginStateBlockCommit(1, trieNode).Dispose(); fullTrieStore.BeginStateBlockCommit(2, trieNode).Dispose(); fullTrieStore.BeginStateBlockCommit(3, trieNode).Dispose(); @@ -347,7 +347,7 @@ public void Dispatcher_will_always_try_to_clear_memory() { TrieNode fakeRoot = new(NodeType.Leaf, []); // 192B fakeRoot.ResolveKey(NullTrieNodeResolver.Instance, ref emptyPath); - using (ICommitter committer = fullTrieStore.BeginStateBlockCommit(i, fakeRoot)) + using (ICommitter committer = fullTrieStore.BeginStateBlockCommit((ulong)i, fakeRoot)) { for (int j = 0; j < 1 + i % 3; j++) { @@ -922,9 +922,9 @@ public void HasRoot_with_block_number_rejects_pruned_state() Hash256[] rootHashes = new Hash256[10]; for (int i = 0; i < 10; i++) { - using (trieStore.BeginBlockCommit(i)) + using (trieStore.BeginBlockCommit((ulong)i)) { - stateTree.Set(TestItem.AddressA, new Account((UInt256)(i + 1))); + stateTree.Set(TestItem.AddressA, new Account((ulong)(i + 1))); stateTree.Commit(); } rootHashes[i] = stateTree.RootHash; @@ -936,16 +936,16 @@ public void HasRoot_with_block_number_rejects_pruned_state() testPruningStrategy.ShouldPruneEnabled = false; Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(0)); - long lastPersisted = trieStore.LastPersistedBlockNumber; + ulong lastPersisted = trieStore.LastPersistedBlockNumber; // Block within boundary: should return true - Assert.That(trieStore.HasRoot(rootHashes[lastPersisted], lastPersisted), Is.True); + Assert.That(trieStore.HasRoot(rootHashes[(int)lastPersisted], lastPersisted), Is.True); // Block outside boundary: should return false - long oldBlock = lastPersisted - pruningBoundary - 1; - if (oldBlock >= 0) + if (lastPersisted > (ulong)pruningBoundary + 1UL) { - Assert.That(trieStore.HasRoot(rootHashes[oldBlock], oldBlock), Is.False); + ulong oldBlock = lastPersisted - (ulong)pruningBoundary - 1UL; + Assert.That(trieStore.HasRoot(rootHashes[(int)oldBlock], oldBlock), Is.False); } trieStore.Dispose(); @@ -977,9 +977,9 @@ public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] Hash256[] rootHashes = new Hash256[startBlock + blockCount]; for (int i = startBlock; i < startBlock + blockCount; i++) { - using (trieStore.BeginBlockCommit(i)) + using (trieStore.BeginBlockCommit((ulong)i)) { - stateTree.Set(TestItem.AddressA, new Account((UInt256)(i + 1))); + stateTree.Set(TestItem.AddressA, new Account((ulong)(i + 1))); stateTree.Commit(); } rootHashes[i] = stateTree.RootHash; @@ -988,13 +988,13 @@ public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] trieStore.WaitForPruning(); Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(pruningBoundary + startBlock)); - long lastPersisted = trieStore.LastPersistedBlockNumber; + ulong lastPersisted = trieStore.LastPersistedBlockNumber; // Block within boundary: should return true - Assert.That(trieStore.HasRoot(rootHashes[lastPersisted], lastPersisted), Is.True); + Assert.That(trieStore.HasRoot(rootHashes[(int)lastPersisted], lastPersisted), Is.True); // Block 1 is well outside the pruning boundary but should still be accessible in archive mode - Assert.That(trieStore.HasRoot(rootHashes[startBlock], startBlock), Is.True); + Assert.That(trieStore.HasRoot(rootHashes[startBlock], (ulong)startBlock), Is.True); trieStore.Dispose(); } @@ -1021,7 +1021,7 @@ public async Task Will_RemovePastKeys_OnSnapshot() for (int i = 0; i < 64; i++) { TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i], new CappedArray(new byte[2])); - using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit(i, node)) + using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit((ulong)i, node)) { committer.CommitNode(ref emptyPath, node); } @@ -1056,7 +1056,7 @@ public void Will_Trigger_ReorgBoundaryEvent_On_Prune() }); long reorgBoundary = 0; - fullTrieStore.ReorgBoundaryReached += (sender, reached) => reorgBoundary = reached.BlockNumber; + fullTrieStore.ReorgBoundaryReached += (sender, reached) => reorgBoundary = (long)reached.BlockNumber; IScopedTrieStore trieStore = fullTrieStore.GetTrieStore(null); TreePath emptyPath = TreePath.Empty; @@ -1064,7 +1064,7 @@ public void Will_Trigger_ReorgBoundaryEvent_On_Prune() for (int i = 0; i < 64; i++) { TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i], new CappedArray(new byte[2])); - using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit(i, node)) + using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit((ulong)i, node)) { committer.CommitNode(ref emptyPath, node); } @@ -1104,7 +1104,7 @@ public void Will_NotRemove_ReCommittedNode() for (int i = 0; i < 64; i++) { TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i % 4], new CappedArray(new byte[2])); - using (ICommitter committer = fullTrieStore.BeginStateBlockCommit(i, node)) + using (ICommitter committer = fullTrieStore.BeginStateBlockCommit((ulong)i, node)) { committer.CommitNode(ref emptyPath, node); } @@ -1195,7 +1195,7 @@ public Task When_Prune_ClearRecommittedPersistedNode() for (int i = 0; i < 64; i++) { TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i], new CappedArray(new byte[2])); - using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit(i, node)) + using (ICommitter? committer = fullTrieStore.BeginStateBlockCommit((ulong)i, node)) { committer.CommitNode(ref emptyPath, node); } @@ -1233,7 +1233,7 @@ public void OnDispose_PersistAtLeastOneCommitSet() for (int i = 0; i < 2; i++) { TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i % 4], new CappedArray(new byte[2])); - using (ICommitter committer = fullTrieStore.BeginStateBlockCommit(i + 1, node)) + using (ICommitter committer = fullTrieStore.BeginStateBlockCommit((ulong)(i + 1), node)) { committer.CommitNode(ref emptyPath, node); } @@ -1277,7 +1277,7 @@ void WriteRandomData(int seed) for (int i = 0; i < 10; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { if (i == 0) { @@ -1290,7 +1290,7 @@ void WriteRandomData(int seed) for (int i = 10; i < 15; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i); } @@ -1298,7 +1298,7 @@ void WriteRandomData(int seed) // Do a branch for (int i = 10; i < 15; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i * 10); } @@ -1307,7 +1307,7 @@ void WriteRandomData(int seed) for (int i = 15; i < 20; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i); } @@ -1361,7 +1361,7 @@ void WriteRandomData(int seed) for (int i = 0; i < 16; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i); } @@ -1430,7 +1430,7 @@ void VerifyAllTrie() Hash256 parentRoot = ptree.RootHash ?? Keccak.EmptyTreeHash; using (fullTrieStore.BeginScope(baseBlock)) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { ptree.RootHash = parentRoot; WriteRandomData(seed); @@ -1443,7 +1443,7 @@ void VerifyAllTrie() { using (fullTrieStore.BeginScope(baseBlock)) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { ptree.RootHash = parentRoot; WriteRandomData(seed * 10); @@ -1509,7 +1509,7 @@ void WriteRandomData(int seed) for (int i = 0; i < 10; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { if (i == 0) { @@ -1531,7 +1531,7 @@ void WriteRandomData(int seed) // Write a bit more for (int i = 10; i < 12; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i); } @@ -1555,7 +1555,7 @@ void WriteRandomData(int seed) using (fullTrieStore.BeginScope(Build.A.BlockHeader.WithStateRoot(ptree.RootHash).TestObject)) { Assert.That(fullTrieStore.IsInCommitBufferMode, Is.True); - using (fullTrieStore.BeginBlockCommit(12)) + using (fullTrieStore.BeginBlockCommit(12UL)) { WriteRandomData(5); Assert.That(ptree.RootHash, Is.EqualTo(persistedRootHash)); @@ -1573,7 +1573,7 @@ void WriteRandomData(int seed) // Write a bit more for (int i = 13; i < 13 + pruningBoundary; i++) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { WriteRandomData(i); } @@ -1610,7 +1610,7 @@ public void Will_KeepAllState_IfFinalizedLagsBehind() TrackPastKeys = true }; - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); TrieStore fullTrieStore = CreateTrieStore( kvStore: memDb, @@ -1660,7 +1660,7 @@ void VerifyAllTrieExceptGenesis() Hash256 parentRoot = ptree.RootHash ?? Keccak.EmptyTreeHash; using (fullTrieStore.BeginScope(baseBlock)) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { ptree.RootHash = parentRoot; WriteRandomData(seed); @@ -1674,7 +1674,7 @@ void VerifyAllTrieExceptGenesis() { using (fullTrieStore.BeginScope(baseBlock)) { - using (fullTrieStore.BeginBlockCommit(i)) + using (fullTrieStore.BeginBlockCommit((ulong)i)) { ptree.RootHash = parentRoot; WriteRandomData(seed * 1000); @@ -1719,7 +1719,7 @@ public void BlockCommitSet_IsSealed_after_Seal_with_null_root() { // This test verifies the fix for networks that have an empty genesis state. // When the state trie is empty, the root is null, but the commit set should still be sealed. - BlockCommitSet commitSet = new(0); + BlockCommitSet commitSet = new(0UL); Assert.That(commitSet.IsSealed, Is.False); @@ -1755,11 +1755,11 @@ public void Consecutive_block_commits_work_when_first_has_null_root() [Parallelizable(ParallelScope.All)] public class TreeStoreInternalBehaviorTests { - [TestCase(false, false, 4, 2, false, 4, TestName = "Dirty_node_record_merge_keeps_current_when_neither_persisted")] - [TestCase(false, false, 2, 5, false, 5, TestName = "Dirty_node_record_merge_advances_last_commit_from_candidate")] - [TestCase(true, false, 1, 3, true, 3, TestName = "Dirty_node_record_merge_replaces_persisted_node_with_dirty_candidate")] - [TestCase(false, true, 4, 6, false, 6, TestName = "Dirty_node_record_merge_keeps_current_when_candidate_is_persisted")] - public void Dirty_node_record_merge_selects_expected_node_and_last_commit(bool currentPersisted, bool candidatePersisted, long currentLastCommit, long candidateLastCommit, bool expectCandidateNode, long expectedLastCommit) + [TestCase(false, false, 4UL, 2UL, false, 4UL, TestName = "Dirty_node_record_merge_keeps_current_when_neither_persisted")] + [TestCase(false, false, 2UL, 5UL, false, 5UL, TestName = "Dirty_node_record_merge_advances_last_commit_from_candidate")] + [TestCase(true, false, 1UL, 3UL, true, 3UL, TestName = "Dirty_node_record_merge_replaces_persisted_node_with_dirty_candidate")] + [TestCase(false, true, 4UL, 6UL, false, 6UL, TestName = "Dirty_node_record_merge_keeps_current_when_candidate_is_persisted")] + public void Dirty_node_record_merge_selects_expected_node_and_last_commit(bool currentPersisted, bool candidatePersisted, ulong currentLastCommit, ulong candidateLastCommit, bool expectCandidateNode, ulong expectedLastCommit) { TrieNode currentNode = CreateNode(currentPersisted); TrieNode candidateNode = CreateNode(candidatePersisted); @@ -1822,6 +1822,6 @@ public void Incomplete_persisted_prune_warning_is_rate_limited() private static TrieNode CreateNode(bool isPersisted) => new(NodeType.Unknown, TestItem.KeccakA) { IsPersisted = isPersisted }; - private static TrieStoreDirtyNodesCache.NodeRecord CreateRecord(TrieNode node, long lastCommit) => new(node, lastCommit); + private static TrieStoreDirtyNodesCache.NodeRecord CreateRecord(TrieNode node, ulong lastCommit) => new(node, lastCommit); } } diff --git a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs index b103137f2ea0..9f8d17bedfbe 100644 --- a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs @@ -227,7 +227,7 @@ private PruningContext(TestPruningStrategy pruningStrategy, IPersistenceStrategy _pruningStrategy = pruningStrategy; _pruningConfig = pruningConfig ?? new PruningConfig() { TrackPastKeys = false }; - _finalizedStateProvider = new TestFinalizedStateProvider(_pruningConfig.PruningBoundary); + _finalizedStateProvider = new TestFinalizedStateProvider((ulong)_pruningConfig.PruningBoundary); _trieStore = new TrieStore(new NodeStorage(_stateDb), _pruningStrategy, _persistenceStrategy, _finalizedStateProvider, _pruningConfig, _logManager); _finalizedStateProvider.TrieStore = _trieStore; @@ -430,7 +430,7 @@ public PruningContext DisposeAndRecreate() { _worldStateCloser!.Dispose(); _trieStore.Dispose(); - TestFinalizedStateProvider finalizedStateProvider = new(_pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)_pruningConfig.PruningBoundary); _trieStore = new TrieStore(new NodeStorage(_stateDb), _pruningStrategy, _persistenceStrategy, finalizedStateProvider, _pruningConfig, _logManager); _stateProvider = new WorldState( new TrieStoreScopeProvider(_trieStore, _codeDb, _logManager), _logManager); @@ -1059,7 +1059,7 @@ public void Keep_OnlySomeDepth(int maxDepth) [NonParallelizable] public void When_Reorg_OldValueIsNotRemoved() { - long previousMaxDepth = Reorganization.MaxDepth; + ulong previousMaxDepth = Reorganization.MaxDepth; Reorganization.MaxDepth = 2; try diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs index 1f46b5add652..0f70481bc3d1 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs @@ -756,7 +756,7 @@ public TrieStore CreateTrieStore() TrackPastKeys = TrackPastKeys, PruningBoundary = LookupLimit, }; - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(new MemDb()), pruneStrategy, @@ -848,7 +848,7 @@ public void Fuzz_accounts( accounts[accountIndex] = key; } - for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) + for (uint blockNumber = 0; blockNumber < blocksCount; blockNumber++) { bool isEmptyBlock = _random.Next(5) == 0; if (!isEmptyBlock) @@ -970,7 +970,7 @@ public void Fuzz_accounts_with_reorganizations( } int blockCount = 0; - for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) + for (uint blockNumber = 0; blockNumber < blocksCount; blockNumber++) { int reorgDepth = _random.Next(Math.Min(5, blockCount)); _logger.Debug($"Reorganizing {reorgDepth}"); @@ -1123,7 +1123,7 @@ public void Fuzz_accounts_with_storage( } BlockHeader? baseBlock = null; - for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) + for (uint blockNumber = 0; blockNumber < blocksCount; blockNumber++) { using IDisposable _ = stateProvider.BeginScope(baseBlock); @@ -1155,7 +1155,7 @@ public void Fuzz_accounts_with_storage( address, existing.Balance - account.Balance, MuirGlacier.Instance); } - stateProvider.IncrementNonce(address, UInt256.One); + stateProvider.IncrementNonce(address, 1UL); } byte[] storage = new byte[1]; @@ -1183,7 +1183,7 @@ public void Fuzz_accounts_with_storage( baseBlock = Build.A.BlockHeader.WithStateRoot(stateProvider.StateRoot).WithNumber(blockNumber) .TestObject; - if (blockNumber > blocksCount - Reorganization.MaxDepth) + if (blockNumber > (ulong)blocksCount - Reorganization.MaxDepth) { rootQueue.Enqueue(baseBlock); } @@ -1233,7 +1233,7 @@ public void Can_parallel_read_trees() int repetition = 100; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); using TrieStore trieStore = new( new NodeStorage(new MemDb()), new TestPruningStrategy(shouldPrune: true), diff --git a/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs b/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs index 65cb15aca10c..5dd979a8e8d5 100644 --- a/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs @@ -37,7 +37,7 @@ public void Visitors_state(VisitingOptions options, INodeStorage.KeyScheme schem raw.Clear(); raw[i / 2] = (byte)(1 << (4 * (1 - i % 2))); - patriciaTree.Set(raw, Rlp.Encode(new Account(10, (UInt256)(10_000_000 + i)))); + patriciaTree.Set(raw, Rlp.Encode(new Account(10UL, (ulong)(10_000_000 + i)))); } using (trieStore.BeginBlockCommit(0)) { patriciaTree.Commit(); } @@ -98,7 +98,7 @@ public void Visitors_storage(VisitingOptions options, INodeStorage.KeyScheme sch stateKey.BytesAsSpan[i / 2] = (byte)(1 << (4 * (1 - i % 2))); stateTree.Set(stateKey, - new Account(10, (UInt256)(10_000_000 + i), stateRootHash, Keccak.OfAnEmptySequenceRlp)); + new Account(10UL, (ulong)(10_000_000 + i), stateRootHash, Keccak.OfAnEmptySequenceRlp)); } stateTree.Commit(); diff --git a/src/Nethermind/Nethermind.Trie/PreCachedTrieStore.cs b/src/Nethermind/Nethermind.Trie/PreCachedTrieStore.cs index bdf77c4e0719..a236467df296 100644 --- a/src/Nethermind/Nethermind.Trie/PreCachedTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/PreCachedTrieStore.cs @@ -33,11 +33,11 @@ public PreCachedTrieStore(ITrieStore inner, NodeStorageCache cache) public ICommitter BeginCommit(Hash256? address, TrieNode? root, WriteFlags writeFlags) => _inner.BeginCommit(address, root, writeFlags); - public IBlockCommitter BeginBlockCommit(long blockNumber) => _inner.BeginBlockCommit(blockNumber); + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => _inner.BeginBlockCommit(blockNumber); public bool HasRoot(Hash256 stateRoot) => _inner.HasRoot(stateRoot); - public bool HasRoot(Hash256 stateRoot, long blockNumber) => _inner.HasRoot(stateRoot, blockNumber); + public bool HasRoot(Hash256 stateRoot, ulong blockNumber) => _inner.HasRoot(stateRoot, blockNumber); public IDisposable BeginScope(BlockHeader? baseBlock) => _inner.BeginScope(baseBlock); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs b/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs index 98c85d5e73c4..1e5b9c9e44e6 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs @@ -9,7 +9,7 @@ private Archive() { } public static Archive Instance { get; } = new(); - public bool ShouldPersist(long blockNumber) => true; + public bool ShouldPersist(ulong blockNumber) => true; public bool IsFullPruning => false; } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/BlockCommitSet.cs b/src/Nethermind/Nethermind.Trie/Pruning/BlockCommitSet.cs index 1df8cfa11a2a..2fc4ae9c2dbc 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/BlockCommitSet.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/BlockCommitSet.cs @@ -7,9 +7,9 @@ namespace Nethermind.Trie.Pruning { - public class BlockCommitSet(long blockNumber) : IComparable + public class BlockCommitSet(ulong blockNumber) : IComparable { - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; public TrieNode? Root { get; private set; } public Hash256 StateRoot => Root?.Keccak ?? Keccak.EmptyTreeHash; diff --git a/src/Nethermind/Nethermind.Trie/Pruning/CommitSetQueue.cs b/src/Nethermind/Nethermind.Trie/Pruning/CommitSetQueue.cs index a6c0af079f8c..be59bfbc8019 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/CommitSetQueue.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/CommitSetQueue.cs @@ -23,7 +23,7 @@ public int Count } public bool IsEmpty => Count == 0; - public long? MinBlockNumber + public ulong? MinBlockNumber { get { @@ -31,7 +31,7 @@ public long? MinBlockNumber } } - public long? MaxBlockNumber + public ulong? MaxBlockNumber { get { @@ -75,7 +75,7 @@ public bool TryDequeue(out BlockCommitSet? blockCommitSet) } } - public ArrayPoolListRef GetCommitSetsAtBlockNumber(long blockNumber) + public ArrayPoolListRef GetCommitSetsAtBlockNumber(ulong blockNumber) { lock (_queue) { @@ -90,7 +90,7 @@ public ArrayPoolListRef GetCommitSetsAtBlockNumber(long blockNum } } - public ArrayPoolListRef GetAndDequeueCommitSetsBeforeOrAt(long blockNumber) + public ArrayPoolListRef GetAndDequeueCommitSetsBeforeOrAt(ulong blockNumber) { lock (_queue) { diff --git a/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs index 0bcfb8f2972f..8e8c690d35b5 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs @@ -18,5 +18,5 @@ public IPersistenceStrategy AddStrategy(IPersistenceStrategy strategy) return this; } - public bool ShouldPersist(long blockNumber) => _strategies.Any(strategy => strategy.ShouldPersist(blockNumber)); + public bool ShouldPersist(ulong blockNumber) => _strategies.Any(strategy => strategy.ShouldPersist(blockNumber)); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ConstantInterval.cs b/src/Nethermind/Nethermind.Trie/Pruning/ConstantInterval.cs index dbcbfb741e00..9c77d6ce973a 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ConstantInterval.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ConstantInterval.cs @@ -5,7 +5,7 @@ namespace Nethermind.Trie.Pruning { public class ConstantInterval(long snapshotInterval) : IPersistenceStrategy { - public bool ShouldPersist(long blockNumber) => blockNumber % snapshotInterval == 0; + public bool ShouldPersist(ulong blockNumber) => blockNumber % (ulong)snapshotInterval == 0; public bool IsFullPruning => false; } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/IFinalizedStateProvider.cs b/src/Nethermind/Nethermind.Trie/Pruning/IFinalizedStateProvider.cs index 7959a026a9f2..3abcfdb3c573 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/IFinalizedStateProvider.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/IFinalizedStateProvider.cs @@ -7,6 +7,6 @@ namespace Nethermind.Trie.Pruning; public interface IFinalizedStateProvider { - long FinalizedBlockNumber { get; } - Hash256? GetFinalizedStateRootAt(long blockNumber); + ulong FinalizedBlockNumber { get; } + Hash256? GetFinalizedStateRootAt(ulong blockNumber); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs index 69ce05438ca2..5c7fca92c31e 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs @@ -5,6 +5,6 @@ namespace Nethermind.Trie.Pruning { public interface IPersistenceStrategy { - bool ShouldPersist(long blockNumber); + bool ShouldPersist(ulong blockNumber); } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ITrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/ITrieStore.cs index a9af996a0641..267c6764a31e 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ITrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ITrieStore.cs @@ -20,7 +20,7 @@ public interface ITrieStore : IDisposable, IScopableTrieStore /// (i.e., not partially pruned). Implementations that perform pruning should reject blocks /// whose state may have been partially pruned. /// - bool HasRoot(Hash256 stateRoot, long blockNumber) => HasRoot(stateRoot); + bool HasRoot(Hash256 stateRoot, ulong blockNumber) => HasRoot(stateRoot); IDisposable BeginScope(BlockHeader? baseBlock); @@ -32,7 +32,7 @@ public interface ITrieStore : IDisposable, IScopableTrieStore /// /// /// - IBlockCommitter BeginBlockCommit(long blockNumber); + IBlockCommitter BeginBlockCommit(ulong blockNumber); } public interface IScopableTrieStore diff --git a/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs index ac2272bf0f87..88431e7ed1e5 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs @@ -9,9 +9,9 @@ public class MaxBlockInCachePruneStrategy(IPruningStrategy baseStrategy, long ma public bool ShouldPruneDirtyNode(TrieStoreState state) { - long reorgBoundary = state.LatestCommittedBlock - pruneBoundary; + ulong reorgBoundary = state.LatestCommittedBlock - (ulong)pruneBoundary; // Persist snapshot if the last persisted block is too old. Prevent very long memory prune - if (reorgBoundary - state.LastPersistedBlock >= maxBlockFromPersisted) return true; + if (reorgBoundary - state.LastPersistedBlock >= (ulong)maxBlockFromPersisted) return true; return baseStrategy.ShouldPruneDirtyNode(state); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/Metrics.cs b/src/Nethermind/Nethermind.Trie/Pruning/Metrics.cs index ee6858de4ed6..ad78c25a22a4 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/Metrics.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/Metrics.cs @@ -74,7 +74,7 @@ public static class Metrics [GaugeMetric] [Description("Last persisted block number (snapshot).")] - public static long LastPersistedBlockNumber { get; set; } + public static ulong LastPersistedBlockNumber { get; set; } [GaugeMetric] [Description("Estimated memory used by cache.")] diff --git a/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs index 329816513fd2..fc1149623780 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs @@ -9,9 +9,9 @@ public class MinBlockInCachePruneStrategy(IPruningStrategy baseStrategy, long mi public bool ShouldPruneDirtyNode(TrieStoreState state) { - long reorgBoundary = state.LatestCommittedBlock - pruneBoundary; + ulong reorgBoundary = state.LatestCommittedBlock - (ulong)pruneBoundary; // Never persist snapshot if too little block in cache. Prevent taking snapshot too often. - if (reorgBoundary - state.LastPersistedBlock < minBlockFromPersisted) return false; + if (reorgBoundary - state.LastPersistedBlock < (ulong)minBlockFromPersisted) return false; return baseStrategy.ShouldPruneDirtyNode(state); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs b/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs index 7a986394a587..516952d3f76a 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs @@ -9,7 +9,7 @@ private NoPersistence() { } public static NoPersistence Instance { get; } = new(); - public bool ShouldPersist(long blockNumber) => false; + public bool ShouldPersist(ulong blockNumber) => false; public bool IsFullPruning => false; } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs index f1d7a437c470..6704dd39c39d 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -37,7 +37,7 @@ public TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256 public INodeStorage.KeyScheme Scheme => baseStore.Scheme; - public IBlockCommitter BeginBlockCommit(long blockNumber) => NullCommitter.Instance; + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => NullCommitter.Instance; // Write directly to _nodeStorage, which goes to db provider. public ICommitter BeginCommit(Hash256? address, TrieNode? root, WriteFlags writeFlags) => new RawScopedTrieStore.Committer(_nodeStorage, address, writeFlags); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs index 99bea61a0b6a..7665b9fd5d13 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs @@ -25,7 +25,7 @@ public byte[] LoadRlp(Hash256? address, in TreePath treePath, Hash256 hash, Read public ICommitter BeginCommit(Hash256? address, TrieNode? root, WriteFlags writeFlags) => NullCommitter.Instance; - public IBlockCommitter BeginBlockCommit(long blockNumber) => NullCommitter.Instance; + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => NullCommitter.Instance; public IDisposable BeginScope(BlockHeader? baseBlock) => new Reactive.AnonymousDisposable(() => { }); // Noop @@ -33,7 +33,7 @@ public byte[] LoadRlp(Hash256? address, in TreePath treePath, Hash256 hash, Read public bool HasRoot(Hash256 stateRoot) => _trieStore.HasRoot(stateRoot); - public bool HasRoot(Hash256 stateRoot, long blockNumber) => _trieStore.HasRoot(stateRoot, blockNumber); + public bool HasRoot(Hash256 stateRoot, ulong blockNumber) => _trieStore.HasRoot(stateRoot, blockNumber); public void Dispose() { } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ReorgBoundaryReached.cs b/src/Nethermind/Nethermind.Trie/Pruning/ReorgBoundaryReached.cs index bfe8191f7563..ed58c8a8215c 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ReorgBoundaryReached.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ReorgBoundaryReached.cs @@ -8,8 +8,8 @@ namespace Nethermind.Trie.Pruning /// /// Tells which number is safe to mark as a checkpoint if it was persisted before. /// - public class ReorgBoundaryReached(long blockNumber) : EventArgs + public class ReorgBoundaryReached(ulong blockNumber) : EventArgs { - public long BlockNumber { get; } = blockNumber; + public ulong BlockNumber { get; } = blockNumber; } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index 0589baa9ce43..9f42ed57857c 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -66,7 +66,7 @@ public sealed class TrieStore : ITrieStore, IPruningTrieStore private readonly bool _pastKeyTrackingEnabled = false; private bool _lastPersistedReachedReorgBoundary; - private long _toBePersistedBlockNumber = -1; + private ulong _toBePersistedBlockNumber = ulong.MinValue; private static readonly long IncompletePersistedPruneWarnIntervalTicks = Stopwatch.Frequency * 5 * 60; private long _incompletePersistedPruneWarnNextTicks; @@ -117,7 +117,7 @@ public TrieStore( private IScopedTrieStore GetTrieStoreForPruning(Hash256? address) => new ScopedTrieStore(new InPruningTrieStore(this), address); - public long LastPersistedBlockNumber + public ulong LastPersistedBlockNumber { get => _latestPersistedBlockNumber; private set @@ -219,7 +219,7 @@ public long DirtyCachedNodesCount } } - private TrieNode CommitAndInsertToDirtyNodes(long blockNumber, Hash256? address, ref TreePath path, TrieNode node) + private TrieNode CommitAndInsertToDirtyNodes(ulong blockNumber, Hash256? address, ref TreePath path, TrieNode node) { if (_logger.IsTrace) Trace(blockNumber, in node); if (!node.IsBoundaryProofNode) @@ -241,7 +241,7 @@ private TrieNode CommitAndInsertToDirtyNodes(long blockNumber, Hash256? address, return node; [MethodImpl(MethodImplOptions.NoInlining)] - void Trace(long blockNumber, in TrieNode node) => _logger.Trace($"Committing {node} at {blockNumber}"); + void Trace(ulong blockNumber, in TrieNode node) => _logger.Trace($"Committing {node} at {blockNumber}"); [DoesNotReturn, StackTraceHidden] static void ThrowUnknownHash(TrieNode node) => throw new TrieStoreException($"The hash of {node} should be known at the time of committing."); @@ -296,7 +296,7 @@ private TrieNode SaveOrReplaceInDirtyNodesCache( Hash256? address, ref TreePath path, TrieNode node, - long blockNumber) + ulong blockNumber) { TrieStoreDirtyNodesCache shard = _dirtyNodes[GetNodeShardIdx(path, node.Keccak)]; return SaveOrReplaceInDirtyNodesCache(shard, address, ref path, node, blockNumber); @@ -307,11 +307,11 @@ private TrieNode SaveOrReplaceInDirtyNodesCache( Hash256? address, ref TreePath path, TrieNode node, - long blockNumber + ulong blockNumber ) { TrieStoreDirtyNodesCache.Key key = new(address, path, node.Keccak); - TrieNode cachedNodeCopy = shard.GetOrAdd(in key, new TrieStoreDirtyNodesCache.NodeRecord(node, blockNumber)).Node; + TrieNode cachedNodeCopy = shard.GetOrAdd(in key, new TrieStoreDirtyNodesCache.NodeRecord(node, ToNodeRecordCommit(blockNumber))).Node; if (!ReferenceEquals(cachedNodeCopy, node)) { Metrics.ReplacedNodesCount++; @@ -346,8 +346,8 @@ public IDisposable BeginScope(BlockHeader? baseBlock) if (_commitBuffer is null) { - long persistedBoundary = Interlocked.Read(ref _toBePersistedBlockNumber); - if (persistedBoundary == -1) + ulong persistedBoundary = Interlocked.Read(ref _toBePersistedBlockNumber); + if (persistedBoundary == ulong.MinValue) { // This can happen in the tiny time in between pruningLock was acquired but the exact block to // persist was not determined yet. @@ -445,7 +445,7 @@ ICommitter IScopableTrieStore.BeginCommit(Hash256? address, TrieNode? root, Writ return _currentBlockCommitter.GetTrieCommitter(address, root, writeFlags); } - public IBlockCommitter BeginBlockCommit(long blockNumber) + public IBlockCommitter BeginBlockCommit(ulong blockNumber) { if (_currentBlockCommitter is not null) throw new InvalidOperationException("Cannot start a new block commit when an existing one is still not closed"); @@ -609,9 +609,9 @@ private void SyncPruneNonLocked() { // When `_pruningLock` is held, the begin commit will check for _toBePersistedBlockNumber in order // to decide which block to be used as the boundary for the commit buffer. This number was re-set - // to -1 in `PersistAndPruneDirtyCache`. So we need to re-set it here, otherwise `BeginScope` will hang - // until the prune persisted node loop is completed. - _toBePersistedBlockNumber = LastPersistedBlockNumber; + // to MinValue in `PersistAndPruneDirtyCache`. So we need to re-set it here, otherwise `BeginScope` + // will hang until the prune persisted node loop is completed. + _toBePersistedBlockNumber = ToPersistedBlockBoundary(LastPersistedBlockNumber); // `PrunePersistedNodes` only work on part of the partition at any one time. With commit buffer, // it is possible that the commit buffer once flushed will immediately trigger another prune, which @@ -639,7 +639,7 @@ private void SyncPruneNonLocked() } finally { - _toBePersistedBlockNumber = -1; + _toBePersistedBlockNumber = ulong.MinValue; } } } @@ -681,7 +681,7 @@ internal void PersistAndPruneDirtyCache() } finally { - _toBePersistedBlockNumber = -1; + _toBePersistedBlockNumber = ulong.MinValue; } } @@ -692,7 +692,7 @@ private void SaveSnapshot() int count = _commitSetQueue?.Count ?? 0; if (count == 0) return; - (ArrayPoolList candidateSets, long? finalizedBlockNumber) = DetermineCommitSetToPersistInSnapshot(count); + (ArrayPoolList candidateSets, ulong? finalizedBlockNumber) = DetermineCommitSetToPersistInSnapshot(count); using ArrayPoolList _ = candidateSets; bool shouldTrackPastKey = @@ -725,12 +725,12 @@ private void SaveSnapshot() if (candidateSets.Count > 0) { - long minToBePersistedBlock = long.MaxValue; + ulong minToBePersistedBlock = ulong.MaxValue; foreach (BlockCommitSet blockCommitSet in candidateSets) { minToBePersistedBlock = Math.Min(minToBePersistedBlock, blockCommitSet.BlockNumber); } - _toBePersistedBlockNumber = minToBePersistedBlock; + _toBePersistedBlockNumber = ToPersistedBlockBoundary(minToBePersistedBlock); } Action persistedNodeRecorder = shouldTrackPastKey ? _persistedNodeRecorder : _persistedNodeRecorderNoop; @@ -759,7 +759,7 @@ private void SaveSnapshot() /// /// /// A tuple of the block to be committed and the canonical block number if known. - private (ArrayPoolList, long?) DetermineCommitSetToPersistInSnapshot(int count) + private (ArrayPoolList, ulong?) DetermineCommitSetToPersistInSnapshot(int count) { ArrayPoolList candidateSets = new(count); try @@ -770,12 +770,11 @@ private void SaveSnapshot() return (candidateSets, null); } - long finalizedBlockNumber = _finalizedStateProvider.FinalizedBlockNumber; - long pruningBoundaryBlockNumber = _commitSetQueue.MaxBlockNumber.Value - _maxDepth; - long effectiveFinalizedBlockNumber = Math.Min(pruningBoundaryBlockNumber, finalizedBlockNumber); - effectiveFinalizedBlockNumber = Math.Max(0, effectiveFinalizedBlockNumber); + ulong finalizedBlockNumber = _finalizedStateProvider.FinalizedBlockNumber; + ulong pruningBoundaryBlockNumber = _commitSetQueue.MaxBlockNumber!.Value - (ulong)_maxDepth; + ulong effectiveFinalizedBlockNumber = Math.Min(pruningBoundaryBlockNumber, Math.Max(0UL, finalizedBlockNumber)); - if (effectiveFinalizedBlockNumber < _commitSetQueue.MinBlockNumber) + if (effectiveFinalizedBlockNumber < _commitSetQueue.MinBlockNumber!.Value) { // Finalized block number far behind any commit. Persist everything so that it can be pruned, but not after // pruning boundary point as snap sync need it. @@ -797,7 +796,7 @@ private void SaveSnapshot() using ArrayPoolListRef commitSetsAtFinalizedBlock = _commitSetQueue.GetCommitSetsAtBlockNumber(effectiveFinalizedBlockNumber); BlockCommitSet? finalizedBlockCommitSet = null; - Hash256? finalizedStateRoot = _finalizedStateProvider.GetFinalizedStateRootAt(effectiveFinalizedBlockNumber); + Hash256? finalizedStateRoot = _finalizedStateProvider.GetFinalizedStateRootAt(ToPersistedBlockBoundary(effectiveFinalizedBlockNumber)); if (finalizedStateRoot is not null) { foreach (BlockCommitSet blockCommitSet in commitSetsAtFinalizedBlock) @@ -1048,14 +1047,22 @@ internal void FlushNonBlockingBuffer() private int _persistedNodesCount; - private long _latestPersistedBlockNumber; + private ulong _latestPersistedBlockNumber; private BlockCommitter? _currentBlockCommitter = null; - public long LatestCommittedBlockNumber { get; set; } + public ulong LatestCommittedBlockNumber { get; set; } public INodeStorage.KeyScheme Scheme => _nodeStorage.Scheme; - private void VerifyNewCommitSet(long blockNumber) + // Returns blockNumber unchanged. NodeRecord.LastCommit is ulong; this helper exists + // so call sites remain readable and the type is explicit. + private static ulong ToNodeRecordCommit(ulong blockNumber) => blockNumber; + + // No-op: input is already ulong so no clamping is needed. Kept as a named helper + // for symmetry with call sites that previously clamped long->ulong. + private static ulong ToPersistedBlockBoundary(ulong blockNumber) => blockNumber; + + private void VerifyNewCommitSet(ulong blockNumber) { if (_lastCommitSet is not null) { @@ -1161,7 +1168,7 @@ void TopLevelPersist(TrieNode tn, Hash256? address2, TreePath path) } private async Task PersistNodeStartingFrom(TrieNode tn, Hash256 address2, TreePath path, - long blockNumber, + ulong blockNumber, Action persistedNodeRecorder, WriteFlags writeFlags, Channel disposeQueue) { @@ -1185,7 +1192,7 @@ async ValueTask DoPersist(TrieNode node, Hash256? address3, TreePath path2) await disposeQueue.Writer.WriteAsync(writeBatch); } - private void PersistNode(Hash256? address, in TreePath path, TrieNode currentNode, long blockNumber, INodeStorage.IWriteBatch writeBatch, WriteFlags writeFlags = WriteFlags.None) + private void PersistNode(Hash256? address, in TreePath path, TrieNode currentNode, ulong blockNumber, INodeStorage.IWriteBatch writeBatch, WriteFlags writeFlags = WriteFlags.None) { ArgumentNullException.ThrowIfNull(currentNode); @@ -1194,7 +1201,7 @@ private void PersistNode(Hash256? address, in TreePath path, TrieNode currentNod TrieStoreDirtyNodesCache.Key key = new(address, path, currentNode.Keccak); // Unpersisted note may have lower commit number than its parent. This can when its child is created // on a different block than its parent. - GetDirtyNodeShard(key).GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(currentNode, blockNumber)); + GetDirtyNodeShard(key).GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(currentNode, ToNodeRecordCommit(blockNumber))); if (_logger.IsTrace) _logger.Trace($"Persisting {nameof(TrieNode)} {currentNode}."); writeBatch.Set(address, path, currentNode.Keccak, currentNode.FullRlp.AsSpan(), writeFlags); @@ -1208,8 +1215,14 @@ private void PersistNode(Hash256? address, in TreePath path, TrieNode currentNod } } - public bool IsNoLongerNeeded(long lastCommit) => lastCommit < LastPersistedBlockNumber - && lastCommit < LatestCommittedBlockNumber - _maxDepth; + // Non-trivial cast: NodeRecord.LastCommit is ulong, so callers that previously passed a + // long block number now receive a ulong. The only remaining call site in this file passes + // a genuine ulong block number, so no overflow is possible here. External call sites that + // stored a long block number must be audited to ensure they do not pass negative values. + public bool IsNoLongerNeeded(ulong lastCommit) => + lastCommit < LastPersistedBlockNumber && + LatestCommittedBlockNumber >= (ulong)_maxDepth && + lastCommit < LatestCommittedBlockNumber - (ulong)_maxDepth; private void AnnounceReorgBoundaries() { @@ -1229,7 +1242,7 @@ private void AnnounceReorgBoundaries() // in such case we would try to continue at Head - 1200010 // because head is loaded if there is no persistence checkpoint // so we need to force the persistence checkpoint - long baseBlock = Math.Max(0, LatestCommittedBlockNumber - 1); + ulong baseBlock = LatestCommittedBlockNumber > 0 ? LatestCommittedBlockNumber - 1 : 0; LastPersistedBlockNumber = baseBlock; shouldAnnounceReorgBoundary = true; } @@ -1237,7 +1250,7 @@ private void AnnounceReorgBoundaries() { // even after we persist a block we do not really remember it as a safe checkpoint // until max reorgs blocks after - if (LatestCommittedBlockNumber >= LastPersistedBlockNumber + _maxDepth) + if (LatestCommittedBlockNumber >= LastPersistedBlockNumber + (ulong)_maxDepth) { shouldAnnounceReorgBoundary = true; } @@ -1254,7 +1267,7 @@ private void PersistOnShutdown() { if (_commitSetQueue.IsEmpty) return; - (ArrayPoolList candidateSets, long? finalizedBlockNumber) = DetermineCommitSetToPersistInSnapshot(_commitSetQueue.Count); + (ArrayPoolList candidateSets, ulong? finalizedBlockNumber) = DetermineCommitSetToPersistInSnapshot(_commitSetQueue.Count); using ArrayPoolList _ = candidateSets; if (LastPersistedBlockNumber == 0 && candidateSets.Count == 0 && _commitSetQueue.TryDequeue(out BlockCommitSet anyCommitSet)) { @@ -1421,15 +1434,15 @@ public bool HasRoot(Hash256 stateRoot) return true; } - public bool HasRoot(Hash256 stateRoot, long blockNumber) + public bool HasRoot(Hash256 stateRoot, ulong blockNumber) { if (!HasRoot(stateRoot)) return false; // Reject blocks whose state may have been partially pruned (root exists but child nodes don't) if (_deleteOldNodes) { - long lastPersisted = LastPersistedBlockNumber; - if (lastPersisted > 0 && blockNumber < lastPersisted - _maxDepth) + ulong lastPersisted = LastPersistedBlockNumber; + if (lastPersisted > 0 && blockNumber < lastPersisted - (ulong)_maxDepth) { return false; } @@ -1471,7 +1484,7 @@ public bool TryRequestConcurrencyQuota() private class PruningTrieStoreCommitter( BlockCommitter blockCommitter, TrieStore trieStore, - long blockNumber, + ulong blockNumber, Hash256? address, TrieNode? root ) : ICommitter @@ -1631,9 +1644,13 @@ private class CommitBuffer private readonly ILogger _logger; public int CommitCount => _commitSetQueueBuffer.Count; - private long _minCommitBlockNumber; - public CommitBuffer(TrieStore trieStore, long minCommitBlockNumber) + // Sentinel ulong.MaxValue means "always newer than any real block boundary", + // i.e. nodes added via the commit buffer are always considered live. + // Previously this was encoded as long -1 before NodeRecord.LastCommit became ulong. + private ulong _minCommitBlockNumber; + + public CommitBuffer(TrieStore trieStore, ulong minCommitBlockNumber) { _minCommitBlockNumber = minCommitBlockNumber; _trieStore = trieStore; @@ -1645,7 +1662,7 @@ public CommitBuffer(TrieStore trieStore, long minCommitBlockNumber) } } - public void Reset(long minCommitBlockNumber) => _minCommitBlockNumber = minCommitBlockNumber; + public void Reset(ulong minCommitBlockNumber) => _minCommitBlockNumber = minCommitBlockNumber; public void EnqueueCommitSet(BlockCommitSet set) => _commitSetQueueBuffer.Enqueue(set); @@ -1672,7 +1689,7 @@ public void FlushToDirtyNodes() private TrieStoreDirtyNodesCache GetDirtyNodeShard(in TreePath path, Hash256 keccak) => _dirtyNodesBuffer[_trieStore.GetNodeShardIdx(path, keccak)]; - public TrieNode SaveOrReplaceInDirtyNodesCache(Hash256? address, ref TreePath path, in TrieNode node, long blockNumber) + public TrieNode SaveOrReplaceInDirtyNodesCache(Hash256? address, ref TreePath path, in TrieNode node, ulong blockNumber) { // Change the shard to the one from commit buffer. TrieStoreDirtyNodesCache shard = GetDirtyNodeShard(path, node.Keccak); @@ -1704,7 +1721,9 @@ public TrieNode FindCachedOrUnknown(TrieStoreDirtyNodesCache.Key key, bool isRea // in disk, or a node that will be deleted. We must never get a node that will be deleted. if (nodeRecord.LastCommit >= _minCommitBlockNumber) { - bufferShard.GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(nodeRecord.Node, -1)); + // ulong.MaxValue sentinel: this node came from the commit buffer itself and has no + // real block number. It is always considered live regardless of _minCommitBlockNumber. + bufferShard.GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(nodeRecord.Node, ulong.MaxValue)); return nodeRecord.Node; } } @@ -1712,7 +1731,8 @@ public TrieNode FindCachedOrUnknown(TrieStoreDirtyNodesCache.Key key, bool isRea { // If it is not persisted, then its child is still referred directly. // The child will not get unreferred until after later it and all its children was persisted. - bufferShard.GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(nodeRecord.Node, -1)); + // ulong.MaxValue sentinel: same reasoning as above. + bufferShard.GetOrAdd(key, new TrieStoreDirtyNodesCache.NodeRecord(nodeRecord.Node, ulong.MaxValue)); return nodeRecord.Node; } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs index 497ae5e50c6b..e92b5a7f9c16 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs @@ -121,10 +121,10 @@ public bool IsNodeCached(in Key key) return _byKeyObjectCache.ContainsKey(key); } - public readonly struct NodeRecord(TrieNode node, long lastCommit) : IEquatable + public readonly struct NodeRecord(TrieNode node, ulong lastCommit) : IEquatable { public readonly TrieNode Node = node; - public readonly long LastCommit = lastCommit; + public readonly ulong LastCommit = lastCommit; public bool Equals(NodeRecord other) => other.Node == Node && other.LastCommit == LastCommit; } @@ -161,18 +161,24 @@ public bool TryGetRecord(Key key, out NodeRecord nodeRecord) => _storeByHash ? _byHashObjectCache.TryGetValue(key.Keccak, out nodeRecord) : _byKeyObjectCache.TryGetValue(key, out nodeRecord); + // Sentinel value: ulong.MaxValue means "no real block number assigned yet" (node was + // just discovered/created, not committed from a numbered block). This replaces the + // previous long -1 sentinel. IsNoLongerNeeded treats this as always-live because + // ulong.MaxValue will never be < LastPersistedBlockNumber for any real chain height. + private const ulong NoCommitSentinel = ulong.MaxValue; + private NodeRecord GetOrAdd(in Key key, TrieStoreDirtyNodesCache cache) => _storeByHash ? _byHashObjectCache.GetOrAdd(key.Keccak, static (keccak, cache) => { TrieNode trieNode = new(NodeType.Unknown, keccak); cache.IncrementMemory(trieNode); - return new NodeRecord(trieNode, -1); + return new NodeRecord(trieNode, NoCommitSentinel); }, cache) : _byKeyObjectCache.GetOrAdd(key, static (key, cache) => { TrieNode trieNode = new(NodeType.Unknown, key.Keccak); cache.IncrementMemory(trieNode); - return new NodeRecord(trieNode, -1); + return new NodeRecord(trieNode, NoCommitSentinel); }, cache); public NodeRecord GetOrAdd(in Key key, NodeRecord record) => _storeByHash @@ -207,7 +213,10 @@ private static NodeRecord GetOrAdd(ConcurrentDictionary [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static NodeRecord MergeRecords(NodeRecord current, NodeRecord candidate) { - long lastCommit = current.LastCommit; + // Preserve the higher LastCommit. Both are ulong; ulong.MaxValue (NoCommitSentinel) + // sorts last, which is correct — a real block number always wins over the sentinel + // because real block numbers are far below ulong.MaxValue. + ulong lastCommit = current.LastCommit; if (candidate.LastCommit > lastCommit) { lastCommit = candidate.LastCommit; @@ -312,7 +321,7 @@ public void PruneCache( foreach ((Key key, NodeRecord nodeRecord) in AllNodes) { TrieNode node = nodeRecord.Node; - long lastCommit = nodeRecord.LastCommit; + ulong lastCommit = nodeRecord.LastCommit; if (node.IsPersisted) { // Remove persisted node based on `persistedHashes` if available. @@ -331,9 +340,11 @@ public void PruneCache( if (prunePersisted) { - // If its persisted and has last seen meaning it was recommitted, - // we keep it to prevent key removal from removing it from DB. - if (lastCommit == -1 || forceRemovePersistedNodes) + // NoCommitSentinel means the node was added to the buffer without a real block + // number. It has no real commit boundary, so treat it as purgeable when + // forceRemovePersistedNodes is requested; otherwise keep it (same semantics as + // the previous lastCommit == -1 guard). + if (lastCommit == NoCommitSentinel || forceRemovePersistedNodes) { if (_logger.IsTrace) LogPersistedNodeRemoval(node); @@ -416,7 +427,10 @@ private void Delete(Key key, ConcurrentNodeWriteBatcher? writeBatch) writeBatch?.Set(key.Address, key.Path, key.Keccak, default, WriteFlags.DisableWAL); } - bool CanDelete(in Key key, long lastCommit, Hash256? currentlyPersistingKeccak) + // Non-trivial: lastCommit is ulong; NoCommitSentinel (ulong.MaxValue) is never < LastPersistedBlockNumber + // for any real chain height (~20M blocks as of 2025), so sentinel nodes are always treated as live here, + // which is the correct behaviour — they were never committed to a numbered block. + bool CanDelete(in Key key, ulong lastCommit, Hash256? currentlyPersistingKeccak) { // Multiple current hash that we don't keep track for simplicity. Just ignore this case. if (currentlyPersistingKeccak is null) return false; @@ -491,7 +505,7 @@ internal readonly struct Key(Hash256? address, in TreePath path, Hash256 keccak) [SkipLocalsInit] public override int GetHashCode() { - ulong chainedHash = ((ulong)(uint)Path.GetHashCode() << 32) | (uint)(Address?.GetHashCode() ?? 1); + ulong chainedHash = (ulong)Path.GetHashCode() << 32 | (uint)(Address?.GetHashCode() ?? 1); return Keccak.ValueHash256.GetChainedHashCode(chainedHash); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreState.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreState.cs index f86dbc0f2b6a..2a608b6aee3f 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreState.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreState.cs @@ -6,5 +6,5 @@ namespace Nethermind.Trie.Pruning; public record TrieStoreState( long PersistedCacheMemory, long DirtyCacheMemory, - long LatestCommittedBlock, - long LastPersistedBlock); + ulong LatestCommittedBlock, + ulong LastPersistedBlock); diff --git a/src/Nethermind/Nethermind.Trie/RawTrieStore.cs b/src/Nethermind/Nethermind.Trie/RawTrieStore.cs index a5a77358f907..1b55bdc1e31b 100644 --- a/src/Nethermind/Nethermind.Trie/RawTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/RawTrieStore.cs @@ -40,5 +40,5 @@ public TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256 public IScopedTrieStore GetTrieStore(Hash256? address) => new RawScopedTrieStore(nodeStorage, address); - public IBlockCommitter BeginBlockCommit(long blockNumber) => NullCommitter.Instance; + public IBlockCommitter BeginBlockCommit(ulong blockNumber) => NullCommitter.Instance; } diff --git a/src/Nethermind/Nethermind.Trie/TrieNode.cs b/src/Nethermind/Nethermind.Trie/TrieNode.cs index b5c45ecf5bd9..75cc56962866 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNode.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNode.cs @@ -84,7 +84,7 @@ internal void WriteRlp(CappedArray value) while (true) { ulong current = Volatile.Read(ref _rlpSeqAndLength); - uint seq = (uint)(current >> 32); + ulong seq = current >> 32; if ((seq & 1) != 0) { // Another writer is active — spin until it completes @@ -92,13 +92,13 @@ internal void WriteRlp(CappedArray value) continue; } // Set lock bit (odd) — seq | 1 is always odd regardless of overflow - ulong writing = (ulong)(seq | 1) << 32; + ulong writing = (seq | 1) << 32; if (Interlocked.CompareExchange(ref _rlpSeqAndLength, writing, current) == current) { Volatile.Write(ref _rlpArray, value.UnderlyingArray); // Advance sequence by 2 and clear lock bit (even), store final length - uint doneSeq = (seq + 2) & 0xFFFFFFFE; - Volatile.Write(ref _rlpSeqAndLength, (ulong)doneSeq << 32 | (uint)value.Length); + ulong doneSeq = (seq + 2) & 0xFFFFFFFE; + Volatile.Write(ref _rlpSeqAndLength, doneSeq << 32 | (uint)value.Length); return; } spin.SpinOnce(); // CAS failed — another writer raced; back off before retry diff --git a/src/Nethermind/Nethermind.Trie/VisitorProgressTracker.cs b/src/Nethermind/Nethermind.Trie/VisitorProgressTracker.cs index 7fe989313a4b..5b4b63c32929 100644 --- a/src/Nethermind/Nethermind.Trie/VisitorProgressTracker.cs +++ b/src/Nethermind/Nethermind.Trie/VisitorProgressTracker.cs @@ -121,7 +121,7 @@ private void LogProgress() return; } - long progressValue = (long)(progress * 10000); + ulong progressValue = (ulong)(progress * 10000); _logger.Update(progressValue); _logger.LogProgress(); diff --git a/src/Nethermind/Nethermind.TxPool.Test/BlobTxStorageTests.cs b/src/Nethermind/Nethermind.TxPool.Test/BlobTxStorageTests.cs index 3ae8dd648725..8aec20ed8555 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/BlobTxStorageTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/BlobTxStorageTests.cs @@ -61,7 +61,7 @@ public void TryGetMany_should_batch_retrieve_stored_transactions() .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .SignedAndResolved(ecdsa, TestItem.PrivateKeys[i]).TestObject; blobTxStorage.Add(txs[i]); @@ -91,7 +91,7 @@ public void TryGetMany_should_handle_mix_of_existing_and_missing_keys() .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .SignedAndResolved(ecdsa, TestItem.PrivateKeys[i]).TestObject; blobTxStorage.Add(txs[i]); diff --git a/src/Nethermind/Nethermind.TxPool.Test/Collections/DistinctValueSortedPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/Collections/DistinctValueSortedPoolTests.cs index 734ab3744604..7716cb0c93e9 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/Collections/DistinctValueSortedPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/Collections/DistinctValueSortedPoolTests.cs @@ -29,11 +29,11 @@ public class DistinctValueSortedPoolTests private const int Capacity = 16; private ITransactionComparerProvider _transactionComparerProvider; - private static Transaction[] GenerateTransactions(int count = Capacity, UInt256? gasPrice = null, Address address = null, UInt256? nonce = null) => + private static Transaction[] GenerateTransactions(int count = Capacity, UInt256? gasPrice = null, Address address = null, ulong? nonce = null) => Enumerable.Range(0, count).Select(i => { UInt256 iUint256 = (UInt256)i; - Transaction transaction = Build.A.Transaction.WithGasPrice(gasPrice ?? iUint256).WithNonce(nonce ?? iUint256) + Transaction transaction = Build.A.Transaction.WithGasPrice(gasPrice ?? iUint256).WithNonce(nonce ?? (ulong)i) .WithSenderAddress(address ?? TestItem.Addresses[i]).TestObject; transaction.Hash = Keccak.Compute(i.ToString()); return transaction; diff --git a/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs index ca4bfd591e4a..16b61d0b7dc8 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs @@ -116,7 +116,7 @@ private static IEnumerable VisitBucketCases() } [TestCaseSource(nameof(VisitBucketCases))] - public void VisitBucket_visits_expected_nonces(int[] insertNonces, int stopAfterNonce, int[] expectedVisited) + public void VisitBucket_visits_expected_nonces(ulong[] insertNonces, int stopAfterNonce, int[] expectedVisited) { InsertNonces(TestItem.AddressA, insertNonces); @@ -139,12 +139,12 @@ public void VisitBucket_throws_on_null_visitor() Assert.That(act, Throws.TypeOf()); } - private void InsertNonces(Address sender, ReadOnlySpan nonces) + private void InsertNonces(Address sender, ReadOnlySpan nonces) { - foreach (int nonce in nonces) + foreach (ulong nonce in nonces) { Transaction tx = Build.A.Transaction - .WithNonce((UInt256)nonce) + .WithNonce(nonce) .WithSenderAddress(sender) .TestObject; tx.Hash = tx.CalculateHash(); diff --git a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs index 2de57e35fe32..c2e765ae6c1f 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs @@ -6,7 +6,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs.Forks; using Nethermind.Evm.State; @@ -98,14 +97,14 @@ public void Accept_SenderIsDelegatedWithNoTransactionsInPool_ReturnsAccepted() }; [TestCaseSource(nameof(DelegatedWithTxInPoolCases))] - public void Accept_SenderIsDelegatedWithOneTransactionInPool(int txNonce, AcceptTxResult expected) + public void Accept_SenderIsDelegatedWithOneTransactionInPool(ulong txNonce, AcceptTxResult expected) { (TxDistinctSortedPool standardPool, TxDistinctSortedPool blobPool) = CreatePools(); Transaction inPool = Build.A.Transaction.SignedAndResolved(Ecdsa, TestItem.PrivateKeyA).TestObject; standardPool.TryInsert(inPool.Hash, inPool); TestReadOnlyStateProvider stateProvider = CreateDelegatedStateProvider(); DelegatedAccountFilter filter = CreateFilter(Prague.Instance, standardPool, blobPool, stateProvider); - Transaction transaction = Build.A.Transaction.WithNonce((UInt256)txNonce).SignedAndResolved(Ecdsa, TestItem.PrivateKeyA).TestObject; + Transaction transaction = Build.A.Transaction.WithNonce(txNonce).SignedAndResolved(Ecdsa, TestItem.PrivateKeyA).TestObject; TxFilteringState state = new(transaction, stateProvider); AcceptTxResult result = filter.Accept(transaction, ref state, TxHandlingOptions.None); @@ -144,13 +143,13 @@ public void Accept_Eip7702IsNotActivated_ReturnsExpected(bool isActive, AcceptTx }; [TestCaseSource(nameof(PendingDelegationNonceCases))] - public void Accept_SenderHasPendingDelegation_OnlyAcceptsIfNonceIsExactMatch(int nonce, AcceptTxResult expected) + public void Accept_SenderHasPendingDelegation_OnlyAcceptsIfNonceIsExactMatch(ulong nonce, AcceptTxResult expected) { (TxDistinctSortedPool standardPool, TxDistinctSortedPool blobPool) = CreatePools(); DelegationCache pendingDelegations = new(); pendingDelegations.IncrementDelegationCount(TestItem.AddressA); DelegatedAccountFilter filter = CreateFilter(Prague.Instance, standardPool, blobPool, delegationCache: pendingDelegations); - Transaction transaction = Build.A.Transaction.WithNonce((UInt256)nonce).SignedAndResolved(Ecdsa, TestItem.PrivateKeyA).TestObject; + Transaction transaction = Build.A.Transaction.WithNonce(nonce).SignedAndResolved(Ecdsa, TestItem.PrivateKeyA).TestObject; TestReadOnlyStateProvider stateProvider = new(); stateProvider.CreateAccount(TestItem.AddressA, 0, 1); TxFilteringState state = new(transaction, stateProvider); diff --git a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs index 4f752f7b9cc8..07a349f69fd6 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs @@ -48,43 +48,43 @@ public void Setup() [Test] public void should_increment_own_transaction_nonces_locally_when_requesting_reservations() { - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)1)); + Assert.That(nonce, Is.EqualTo(1UL)); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)1)); + Assert.That(nonce, Is.EqualTo(1UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)1)); + Assert.That(nonce, Is.EqualTo(1UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)2)); + Assert.That(nonce, Is.EqualTo(2UL)); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressB, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)2)); + Assert.That(nonce, Is.EqualTo(2UL)); locker.Accept(); } } @@ -95,38 +95,38 @@ public void should_increment_own_transaction_nonces_locally_when_requesting_rese { const int reservationsCount = 1000; - ConcurrentQueue nonces = new(); + ConcurrentQueue nonces = new(); ParallelLoopResult result = Parallel.For(0, reservationsCount, i => { - using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce); + using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce); locker.Accept(); nonces.Enqueue(nonce); }); Assert.That(result.IsCompleted, Is.True); - using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce); + using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce); nonces.Enqueue(nonce); - Assert.That(nonce, Is.EqualTo(new UInt256(reservationsCount))); - Assert.That(nonces.OrderBy(n => n), Is.EqualTo(Enumerable.Range(0, reservationsCount + 1).Select(i => new UInt256((uint)i)))); + Assert.That(nonce, Is.EqualTo((ulong)reservationsCount)); + Assert.That(nonces.OrderBy(n => n), Is.EqualTo(Enumerable.Range(0, reservationsCount + 1).Select(i => (ulong)i))); } [Test] public void should_pick_account_nonce_as_initial_value() { IAccountStateProvider accountStateProvider = Substitute.For(); - accountStateProvider.GetNonce(TestItem.AddressA).Returns(UInt256.Zero); + accountStateProvider.GetNonce(TestItem.AddressA).Returns(0UL); _nonceManager = new NonceManager(accountStateProvider); - using (_nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (_nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); } - accountStateProvider.GetNonce(TestItem.AddressA).Returns((UInt256)10); - using (_nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + accountStateProvider.GetNonce(TestItem.AddressA).Returns(10UL); + using (_nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)10)); + Assert.That(nonce, Is.EqualTo(10UL)); } } @@ -138,15 +138,15 @@ public void ReserveNonce_should_skip_nonce_if_TxWithNonceReceived() locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)1)); + Assert.That(nonce, Is.EqualTo(1UL)); locker.Accept(); } @@ -155,15 +155,15 @@ public void ReserveNonce_should_skip_nonce_if_TxWithNonceReceived() locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)3)); + Assert.That(nonce, Is.EqualTo(3UL)); locker.Accept(); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)5)); + Assert.That(nonce, Is.EqualTo(5UL)); locker.Accept(); } } @@ -171,22 +171,22 @@ public void ReserveNonce_should_skip_nonce_if_TxWithNonceReceived() [Test] public void should_reuse_nonce_if_tx_rejected() { - using (_nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (_nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(nonce, Is.EqualTo(0UL)); locker.Accept(); } using (_nonceManager.TxWithNonceReceived(TestItem.AddressA, 1)) { } - using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce)) + using (NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce)) { - Assert.That(nonce, Is.EqualTo((UInt256)1)); + Assert.That(nonce, Is.EqualTo(1UL)); locker.Accept(); } } @@ -195,11 +195,11 @@ public void should_reuse_nonce_if_tx_rejected() [Repeat(2)] public void should_lock_on_same_account() { - using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce); - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce); + Assert.That(nonce, Is.EqualTo(0UL)); Task task = Task.Run(() => { - using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 _); + using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong _); }); task.Wait(TimeSpan.FromMilliseconds(1_000)); Assert.That(task.IsCompleted, Is.EqualTo(false)); @@ -209,12 +209,12 @@ public void should_lock_on_same_account() [Repeat(3)] public void should_not_lock_on_different_accounts() { - using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out UInt256 nonce); - Assert.That(nonce, Is.EqualTo(UInt256.Zero)); + using NonceLocker locker = _nonceManager.ReserveNonce(TestItem.AddressA, out ulong nonce); + Assert.That(nonce, Is.EqualTo(0UL)); Task task = Task.Run(() => { - using NonceLocker locker2 = _nonceManager.ReserveNonce(TestItem.AddressB, out UInt256 nonce2); - Assert.That(nonce2, Is.EqualTo(UInt256.Zero)); + using NonceLocker locker2 = _nonceManager.ReserveNonce(TestItem.AddressB, out ulong nonce2); + Assert.That(nonce2, Is.EqualTo(0UL)); }); task.Wait(TimeSpan.FromMilliseconds(10_000)); Assert.That(task.IsCompleted, Is.EqualTo(true)); diff --git a/src/Nethermind/Nethermind.TxPool.Test/TestBlockTree.cs b/src/Nethermind/Nethermind.TxPool.Test/TestBlockTree.cs index 3a19bf4c743f..d8c2e7c8ffa1 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TestBlockTree.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TestBlockTree.cs @@ -41,17 +41,17 @@ public event EventHandler? OnForkChoiceUpd public Hash256? PendingHash => null; public Hash256? FinalizedHash => null; public Hash256? SafeHash => null; - public long? BestPersistedState { get; set; } + public ulong? BestPersistedState { get; set; } - public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => null; - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => null; - public bool HasBlock(long blockNumber, Hash256 blockHash) => false; - public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => null; - public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) => null; - public Hash256? FindBlockHash(long blockNumber) => null; + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => null; + public Block? FindBlock(ulong blockNumber, BlockTreeLookupOptions options) => null; + public bool HasBlock(ulong blockNumber, Hash256 blockHash) => false; + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, ulong? blockNumber = null) => null; + public BlockHeader? FindHeader(ulong blockNumber, BlockTreeLookupOptions options) => null; + public Hash256? FindBlockHash(ulong blockNumber) => null; public bool IsMainChain(BlockHeader blockHeader) => false; public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) => false; - public long GetLowestBlock() => 0; + public ulong GetLowestBlock() => 0; // IBlockTree implementation public ulong NetworkId => 1; @@ -61,10 +61,10 @@ public event EventHandler? OnForkChoiceUpd public BlockHeader? BestSuggestedBeaconHeader => null; public BlockHeader? LowestInsertedHeader { get; set; } public BlockHeader? LowestInsertedBeaconHeader { get; set; } - public long BestKnownNumber => Head?.Number ?? 0; - public long BestKnownBeaconNumber => 0; + public ulong BestKnownNumber => Head?.Number ?? 0; + public ulong BestKnownBeaconNumber => 0; public bool CanAcceptNewBlocks => true; - public (long BlockNumber, Hash256 BlockHash) SyncPivot { get; set; } + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot { get; set; } public bool IsProcessingBlock { get; set; } public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) @@ -77,29 +77,29 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc => AddBlockResult.Added; public void UpdateHeadBlock(Hash256 blockHash) { } - public void NewOldestBlock(long oldestBlock) { } + public void NewOldestBlock(ulong oldestBlock) { } public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => AddBlockResult.Added; public ValueTask SuggestBlockAsync(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => ValueTask.FromResult(AddBlockResult.Added); public AddBlockResult SuggestHeader(BlockHeader header) => AddBlockResult.Added; - public bool IsKnownBlock(long number, Hash256 blockHash) => false; - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => false; - public bool WasProcessed(long number, Hash256 blockHash) => false; + public bool IsKnownBlock(ulong number, Hash256 blockHash) => false; + public bool IsKnownBeaconBlock(ulong number, Hash256 blockHash) => false; + public bool WasProcessed(ulong number, Hash256 blockHash) => false; public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) { } public void MarkChainAsProcessed(IReadOnlyList blocks) { } public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) => Task.CompletedTask; - public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) => (null, null); - public ChainLevelInfo? FindLevel(long number) => null; - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => null!; - public Hash256? FindHash(long blockNumber) => null; + public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(ulong number, Hash256 blockHash) => (null, null); + public ChainLevelInfo? FindLevel(ulong number) => null; + public BlockInfo FindCanonicalBlockInfo(ulong blockNumber) => null!; + public Hash256? FindHash(ulong blockNumber) => null; public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => new ArrayPoolList(0); public void DeleteInvalidBlock(Block invalidBlock) { } - public void DeleteOldBlock(long blockNumber, Hash256 blockHash) { } + public void DeleteOldBlock(ulong blockNumber, Hash256 blockHash) { } public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) { } - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) => 0; + public int DeleteChainSlice(in ulong startNumber, ulong? endNumber = null, bool force = false) => 0; public bool IsBetterThanHead(BlockHeader? header) => false; - public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, long clearBeaconMainChainStartPoint) { } + public void UpdateBeaconMainChain(IReadOnlyList? blockInfos, ulong clearBeaconMainChainStartPoint) { } public void RecalculateTreeLevels() { } - public void HealCanonicalChain(Hash256 startHash, long maxBlockDepth) { } + public void HealCanonicalChain(Hash256 startHash, ulong maxBlockDepth) { } } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TestChainHeadInfoProvider.cs b/src/Nethermind/Nethermind.TxPool.Test/TestChainHeadInfoProvider.cs index 36670f39195c..aa6e8fe614b9 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TestChainHeadInfoProvider.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TestChainHeadInfoProvider.cs @@ -19,8 +19,8 @@ internal class TestChainHeadInfoProvider : IChainHeadInfoProvider { public IChainHeadSpecProvider SpecProvider { get; set; } = null!; public IReadOnlyStateProvider ReadOnlyStateProvider { get; set; } = null!; - public long HeadNumber { get; set; } - public long? BlockGasLimit { get; set; } = 30_000_000; + public ulong HeadNumber { get; set; } + public ulong? BlockGasLimit { get; set; } = 30_000_000; public UInt256 CurrentBaseFee { get; set; } public UInt256 CurrentFeePerBlobGas { get; set; } public ProofVersion CurrentProofVersion { get; set; } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TransactionExtensionsTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TransactionExtensionsTests.cs index 6cd27b5d127d..9fdded87e2ce 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TransactionExtensionsTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TransactionExtensionsTests.cs @@ -31,11 +31,11 @@ public class TransactionPayableGasPrice { public int Lp { get; set; } public UInt256 BaseFee { get; set; } - public UInt256 FeeCap { get; set; } + public ulong FeeCap { get; set; } public UInt256 GasPrice { get; set; } public TxType Type { get; set; } - public long GasLimit { get; set; } - public UInt256 Value { get; set; } + public ulong GasLimit { get; set; } + public ulong Value { get; set; } public bool IsEip1559Enabled { get; set; } public UInt256 AccountBalance { get; set; } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxBroadcasterTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxBroadcasterTests.cs index 7436ad0dca2e..2444db4ae17e 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxBroadcasterTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxBroadcasterTests.cs @@ -439,7 +439,7 @@ public void should_pick_tx_with_lowest_nonce_from_bucket() Parallel.For(0, addedTxsCount, i => { transactions[i] = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice(i.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA) .TestObject; @@ -652,7 +652,7 @@ public void should_rebroadcast_all_persistent_transactions_if_PeerNotificationTh Parallel.For(0, _txPoolConfig.Size, i => { Transaction tx = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .SignedAndResolved(TestItem.PrivateKeyA).TestObject; _broadcaster.Broadcast(tx, true); }); @@ -662,7 +662,7 @@ public void should_rebroadcast_all_persistent_transactions_if_PeerNotificationTh for (int i = 0; i < pickedTxs.Length; i++) { - Assert.That(pickedTxs[i].Nonce, Is.EqualTo((UInt256)i)); + Assert.That(pickedTxs[i].Nonce, Is.EqualTo((ulong)i)); } } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolInfoProviderTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolInfoProviderTests.cs index 2bcd45b77c80..4a9ebf4f6a73 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolInfoProviderTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolInfoProviderTests.cs @@ -5,7 +5,6 @@ using System.Linq; using Nethermind.Core; using Nethermind.Core.Test.Builders; -using Nethermind.Int256; using NSubstitute; using NUnit.Framework; @@ -66,7 +65,7 @@ public void should_return_valid_pending_and_queued_transactions() [Test] public void GetInfo_WhenSenderHasStandardAndBlobTransactions_OmitsBlobs() { - _stateReader.GetNonce(_address).Returns((UInt256)0); + _stateReader.GetNonce(_address).Returns(0UL); Transaction[] standard = BuildTransactions([0, 2]); Transaction[] blobs = BuildTransactions([1, 3]); _txPool.GetPendingTransactionsBySender() @@ -90,7 +89,7 @@ public void GetInfo_WhenSenderHasOnlyBlobTransactions_DoesNotAppearInResult() // NotContainKey assertions. Today the blob mock is unconsulted (matches geth's // BlobPool.Content() empty-stub behaviour), so the address is absent because the // standard-pool dictionary has no entry for it. - _stateReader.GetNonce(_address).Returns((UInt256)0); + _stateReader.GetNonce(_address).Returns(0UL); Transaction[] blobs = BuildTransactions([0, 1]); _txPool.GetPendingLightBlobTransactionsBySender() .Returns(new Dictionary { { _address, blobs } }); @@ -125,7 +124,7 @@ private static IEnumerable SenderInfoCases() => [TestCaseSource(nameof(SenderInfoCases))] public void GetSenderInfo_WhenSenderHasTransactions_SplitsByNonceAgainstAccount(SenderScenario scenario) { - _stateReader.GetNonce(_address).Returns((UInt256)scenario.AccountNonce); + _stateReader.GetNonce(_address).Returns(scenario.AccountNonce); _txPool.GetPendingTransactionsBySender(_address).Returns(BuildTransactions(scenario.TxNonces)); TxPoolSenderInfo senderInfo = _infoProvider.GetSenderInfo(_address); @@ -145,7 +144,7 @@ public void GetSenderInfo_WhenSenderHasNoTransactions_ReturnsEmpty() [Test] public void GetSenderInfo_WhenSenderHasStandardAndBlobTransactions_OmitsBlobs() { - _stateReader.GetNonce(_address).Returns((UInt256)0); + _stateReader.GetNonce(_address).Returns(0UL); _txPool.GetPendingTransactionsBySender(_address).Returns(BuildTransactions([0, 2])); // Blob bucket is populated to make the exclusion semantics explicit; GetSenderInfo // does not consult the blob pool, so these nonces must not appear in the output. @@ -164,7 +163,7 @@ public void GetSenderInfo_WhenSenderHasOnlyBlobTransactions_ReturnsEmpty() // mock here becomes live and the result stops being TxPoolSenderInfo.Empty, failing // the assertion. Today the blob mock is unconsulted (matches geth's BlobPool.Content() // empty-stub behaviour), so the empty result comes from the standard pool being empty. - _stateReader.GetNonce(_address).Returns((UInt256)0); + _stateReader.GetNonce(_address).Returns(0UL); _txPool.GetPendingLightBlobTransactionsBySender(_address).Returns(BuildTransactions([0, 1])); TxPoolSenderInfo senderInfo = _infoProvider.GetSenderInfo(_address); @@ -202,7 +201,7 @@ private static IEnumerable CountCases() => [TestCaseSource(nameof(CountCases))] public void GetCounts_WhenPoolHasOneSender_ReturnsPendingAndQueuedTotals(SenderScenario scenario) { - _stateReader.GetNonce(_address).Returns((UInt256)scenario.AccountNonce); + _stateReader.GetNonce(_address).Returns(scenario.AccountNonce); _txPool.GetPendingTransactionsBySender() .Returns(new Dictionary { { _address, BuildTransactions(scenario.TxNonces) } }); @@ -215,7 +214,7 @@ public void GetCounts_WhenPoolHasOneSender_ReturnsPendingAndQueuedTotals(SenderS [Test] public void GetCounts_WhenSenderHasStandardAndBlob_CountsAcrossBothPools() { - _stateReader.GetNonce(_address).Returns((UInt256)0); + _stateReader.GetNonce(_address).Returns(0UL); _txPool.GetPendingTransactionsBySender() .Returns(new Dictionary { { _address, BuildTransactions([0, 2]) } }); _txPool.GetPendingLightBlobTransactionsBySender() @@ -228,7 +227,7 @@ public void GetCounts_WhenSenderHasStandardAndBlob_CountsAcrossBothPools() } private void VerifyNonceAndTransactions(IDictionary transactionNonce, ulong nonce) => - Assert.That(transactionNonce[nonce].Nonce, Is.EqualTo((UInt256)nonce)); + Assert.That(transactionNonce[nonce].Nonce, Is.EqualTo(nonce)); private Transaction[] GetTransactions() => BuildTransactions([1, 2, 3, 4, 5, 8, 9]); diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs index 2cdc1fcc96fe..1e2c53b2db90 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs @@ -39,7 +39,7 @@ public void should_reject_blob_tx_if_blobs_not_supported([Values(true, false)] b _txPool = CreatePool(txPoolConfig, GetCancunSpecProvider()); Transaction tx = Build.A.Transaction - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) @@ -103,7 +103,7 @@ public void blob_pool_size_should_be_correct([Values(true, false)] bool persiste for (int i = 0; i < poolSize; i++) { Transaction tx = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei + (UInt256)(100 - i)) .WithMaxPriorityFeePerGas(1.GWei + (UInt256)(100 - i)) @@ -137,7 +137,7 @@ public void should_reject_txs_with_nonce_too_far_in_future(TxType txType, int ma Parallel.For(0, txPoolConfig.Size, (nonce) => { txs[nonce] = Build.A.Transaction - .WithNonce((UInt256)nonce) + .WithNonce((ulong)nonce) .WithType(txType) .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei) @@ -172,7 +172,7 @@ public void should_reject_tx_with_FeeTooLow_even_if_is_blob_type([Values(true, f for (int i = 0; i < poolSize; i++) { Transaction tx = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithType(isBlob ? TxType.Blob : TxType.EIP1559) .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei + (UInt256)(100 - i)) @@ -185,7 +185,7 @@ public void should_reject_tx_with_FeeTooLow_even_if_is_blob_type([Values(true, f Assert.That(_txPool.GetPendingBlobTransactionsCount(), Is.EqualTo(isBlob ? poolSize : 0)); Transaction feeTooLowTx = Build.A.Transaction - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithType(isBlob ? TxType.Blob : TxType.EIP1559) .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei + UInt256.One) @@ -211,7 +211,7 @@ public void should_add_blob_tx_and_return_when_requested([Values(true, false)] b .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Assert.That(_txPool.SubmitTx(blobTxAdded, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); @@ -313,7 +313,7 @@ public void should_not_add_nonce_gap_blob_tx_even_to_not_full_TxPool([Values(tru .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction nonceGapTx = Build.A.Transaction @@ -321,7 +321,7 @@ public void should_not_add_nonce_gap_blob_tx_even_to_not_full_TxPool([Values(tru .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce((UInt256)2) + .WithNonce((ulong)2) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Assert.That(_txPool.SubmitTx(firstTx, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); @@ -331,7 +331,7 @@ public void should_not_add_nonce_gap_blob_tx_even_to_not_full_TxPool([Values(tru [Test] public void should_not_allow_to_have_pending_transactions_of_both_blob_type_and_other([Values(true, false)] bool firstIsBlob, [Values(true, false)] bool secondIsBlob) { - Transaction GetTx(bool isBlob, UInt256 nonce) => Build.A.Transaction + Transaction GetTx(bool isBlob, ulong nonce) => Build.A.Transaction .WithType(isBlob ? TxType.Blob : TxType.EIP1559) .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei) @@ -342,8 +342,8 @@ Transaction GetTx(bool isBlob, UInt256 nonce) => Build.A.Transaction _txPool = CreatePool(new TxPoolConfig() { BlobsSupport = BlobsSupportMode.InMemory, Size = 128 }, GetCancunSpecProvider()); EnsureSenderBalance(TestItem.AddressA, UInt256.MaxValue); - Transaction firstTx = GetTx(firstIsBlob, UInt256.Zero); - Transaction secondTx = GetTx(secondIsBlob, UInt256.One); + Transaction firstTx = GetTx(firstIsBlob, 0UL); + Transaction secondTx = GetTx(secondIsBlob, 1UL); Assert.That(_txPool.SubmitTx(firstTx, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); Assert.That(_txPool.SubmitTx(secondTx, TxHandlingOptions.None), Is.EqualTo(firstIsBlob ^ secondIsBlob ? AcceptTxResult.PendingTxsOfConflictingType : AcceptTxResult.Accepted)); @@ -363,14 +363,14 @@ public void should_remove_replaced_blob_tx_from_persistent_storage_and_cache() Transaction oldTx = Build.A.Transaction .WithShardBlobTxTypeAndFields() - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction newTx = Build.A.Transaction .WithShardBlobTxTypeAndFields() - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(oldTx.MaxFeePerGas * 2) .WithMaxPriorityFeePerGas(oldTx.MaxPriorityFeePerGas * 2) .WithMaxFeePerBlobGas(oldTx.MaxFeePerBlobGas * 2) @@ -406,7 +406,7 @@ public void should_keep_in_memory_only_light_blob_tx_equivalent_if_persistent_st Transaction tx = Build.A.Transaction .WithShardBlobTxTypeAndFields() - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) .WithMaxFeePerBlobGas(UInt256.One) @@ -437,7 +437,7 @@ public void should_dump_GasBottleneck_of_blob_tx_to_zero_if_MaxFeePerBlobGas_is_ Transaction tx = Build.A.Transaction .WithType(isBlob ? TxType.Blob : TxType.EIP1559) .WithShardBlobTxTypeAndFieldsIfBlobTx() - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) .WithMaxFeePerBlobGas(isBlob ? UInt256.One : null) @@ -471,14 +471,14 @@ public void should_not_allow_to_replace_blob_tx_by_tx_with_less_blobs([Values(1, Transaction firstTx = Build.A.Transaction .WithShardBlobTxTypeAndFields(blobsInFirstTx) - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction secondTx = Build.A.Transaction .WithShardBlobTxTypeAndFields(blobsInSecondTx) - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(firstTx.MaxFeePerGas * 2) .WithMaxPriorityFeePerGas(firstTx.MaxPriorityFeePerGas * 2) .WithMaxFeePerBlobGas(firstTx.MaxFeePerBlobGas * 2) @@ -520,14 +520,14 @@ public void should_allow_to_replace_blob_tx_by_the_one_with_network_wrapper_in_h Transaction firstTx = Build.A.Transaction .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = false }) - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction secondTx = Build.A.Transaction .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(2.GWei) .WithMaxPriorityFeePerGas(1.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; @@ -559,7 +559,7 @@ public void should_discard_tx_when_data_gas_cost_cause_overflow([Values(false, t Transaction firstTransaction = Build.A.Transaction .WithShardBlobTxTypeAndFields() .WithMaxFeePerBlobGas(UInt256.Zero) - .WithNonce(UInt256.Zero) + .WithNonce(0) .WithMaxFeePerGas(halfOfMaxGasPriceWithoutOverflow) .WithMaxPriorityFeePerGas(halfOfMaxGasPriceWithoutOverflow) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; @@ -570,7 +570,7 @@ public void should_discard_tx_when_data_gas_cost_cause_overflow([Values(false, t .WithMaxFeePerBlobGas(supportsBlobs ? UInt256.One : UInt256.Zero) - .WithNonce(UInt256.One) + .WithNonce(1) .WithMaxFeePerGas(halfOfMaxGasPriceWithoutOverflow) .WithMaxPriorityFeePerGas(halfOfMaxGasPriceWithoutOverflow) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; @@ -581,7 +581,7 @@ public void should_discard_tx_when_data_gas_cost_cause_overflow([Values(false, t [Test] public async Task should_allow_to_have_pending_transaction_of_other_type_if_conflicting_one_was_included([Values(true, false)] bool firstIsBlob, [Values(true, false)] bool secondIsBlob) { - Transaction GetTx(bool isBlob, UInt256 nonce) => Build.A.Transaction + Transaction GetTx(bool isBlob, ulong nonce) => Build.A.Transaction .WithType(isBlob ? TxType.Blob : TxType.EIP1559) .WithShardBlobTxTypeAndFieldsIfBlobTx() .WithMaxFeePerGas(1.GWei) @@ -592,8 +592,8 @@ Transaction GetTx(bool isBlob, UInt256 nonce) => Build.A.Transaction _txPool = CreatePool(new TxPoolConfig() { BlobsSupport = BlobsSupportMode.InMemory, Size = 128 }, GetCancunSpecProvider()); EnsureSenderBalance(TestItem.AddressA, UInt256.MaxValue); - Transaction firstTx = GetTx(firstIsBlob, UInt256.Zero); - Transaction secondTx = GetTx(secondIsBlob, UInt256.One); + Transaction firstTx = GetTx(firstIsBlob, 0UL); + Transaction secondTx = GetTx(secondIsBlob, 1UL); Assert.That(_txPool.SubmitTx(firstTx, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); @@ -636,7 +636,7 @@ public void RecoverAddress_should_work_correctly() [Test] public async Task should_add_processed_txs_to_db() { - const long blockNumber = 358; + const ulong blockNumber = 358; BlobTxStorage blobTxStorage = new(); ITxPoolConfig txPoolConfig = new TxPoolConfig() @@ -677,7 +677,7 @@ public async Task should_add_processed_txs_to_db() [Test] public async Task should_bring_back_reorganized_blob_txs() { - const long blockNumber = 358; + const ulong blockNumber = 358; BlobTxStorage blobTxStorage = new(); ITxPoolConfig txPoolConfig = new TxPoolConfig() @@ -838,7 +838,7 @@ public void should_handle_indexing_blobs_when_adding_txs_in_parallel([Values(tru for (int i = 0; i < txsPerSender; i++) { Transaction tx = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) @@ -890,7 +890,7 @@ public void should_add_blob_tx_in_eip7594_form_and_return_when_requested([Values .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = hasTxCellProofs }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; AcceptTxResult result = _txPool.SubmitTx(blobTxAdded, TxHandlingOptions.None); @@ -943,7 +943,7 @@ public void should_convert_blob_proofs_to_cell_proofs_if_enabled([Values(true, f .WithShardBlobTxTypeAndFields() .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; AcceptTxResult result = _txPool.SubmitTx(blobTxAdded, TxHandlingOptions.None); @@ -985,7 +985,7 @@ public async Task should_evict_based_on_proof_version_and_fork(BlobsSupport } }); - UInt256 nonce = 0; + ulong nonce = 0; TxPoolConfig txPoolConfig = new() { BlobsSupport = poolMode, Size = 10 }; _txPool = CreatePool(txPoolConfig, provider); @@ -1049,7 +1049,7 @@ private async Task AddEmptyBlock() await RaiseBlockAddedToMainAndWaitForNewHead(block, _blockTree.Head); } - private Transaction CreateBlobTx(PrivateKey sender, UInt256 nonce = default, int blobCount = 1, IReleaseSpec releaseSpec = default) => Build.A.Transaction + private Transaction CreateBlobTx(PrivateKey sender, ulong nonce = default, int blobCount = 1, IReleaseSpec releaseSpec = default) => Build.A.Transaction .WithShardBlobTxTypeAndFields(blobCount: blobCount, spec: releaseSpec) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) @@ -1161,14 +1161,14 @@ public void should_batch_return_blobs_and_proofs_v1_from_persistent_storage() .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction tx2 = Build.A.Transaction .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyB).TestObject; Assert.That(_txPool.SubmitTx(tx1, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); @@ -1206,7 +1206,7 @@ public void should_batch_return_partial_blobs_when_some_missing() .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Assert.That(_txPool.SubmitTx(tx1, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); @@ -1245,14 +1245,14 @@ public void should_batch_return_blobs_from_cache_and_db() .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; Transaction tx2 = Build.A.Transaction .WithShardBlobTxTypeAndFields(spec: new ReleaseSpec() { IsEip7594Enabled = true }) .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyB).TestObject; Assert.That(_txPool.SubmitTx(tx1, TxHandlingOptions.None), Is.EqualTo(AcceptTxResult.Accepted)); diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs index d3daab6a6fdc..b1d6b8868799 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs @@ -459,8 +459,8 @@ public void should_handle_adding_tx_to_full_txPool_properly(int gasPrice, int va Transaction tx = Build.A.Transaction .WithGasPrice((UInt256)gasPrice) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; - tx.Value = (UInt256)(value * tx.GasLimit); - EnsureSenderBalance(tx.SenderAddress, (UInt256)(15 * tx.GasLimit)); + tx.Value = (ulong)value * tx.GasLimit; + EnsureSenderBalance(tx.SenderAddress, (UInt256)(15UL * tx.GasLimit)); Assert.That(_txPool.GetPendingTransactionsCount(), Is.EqualTo(30)); AcceptTxResult result = _txPool.SubmitTx(tx, TxHandlingOptions.None); Assert.That(result.ToString(), Does.Contain(expected)); @@ -502,8 +502,8 @@ public void should_handle_adding_1559_tx_to_full_txPool_properly(int gasPremium, .WithMaxPriorityFeePerGas((UInt256)gasPremium) .WithChainId(TestBlockchainIds.ChainId) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; - tx.Value = (UInt256)(value * tx.GasLimit); - EnsureSenderBalance(tx.SenderAddress, (UInt256)(15 * tx.GasLimit)); + tx.Value = (ulong)value * tx.GasLimit; + EnsureSenderBalance(tx.SenderAddress, (UInt256)(15UL * tx.GasLimit)); Assert.That(_txPool.GetPendingTransactionsCount(), Is.EqualTo(30)); AcceptTxResult result = _txPool.SubmitTx(tx, TxHandlingOptions.None); Assert.That(_txPool.GetPendingTransactionsCount(), Is.EqualTo(30)); @@ -561,7 +561,7 @@ public void should_not_add_tx_if_already_pending_lower_nonces_are_exhausting_bal { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)gasPrice) .WithGasLimit(TxGasLimit) .WithValue(value) @@ -595,7 +595,7 @@ public void should_not_count_txs_with_stale_nonces_when_calculating_cumulative_c { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)gasPrice) .WithGasLimit(TxGasLimit) .WithValue(value) @@ -615,7 +615,7 @@ public void should_not_count_txs_with_stale_nonces_when_calculating_cumulative_c int numberOfTxsInTxPool = _txPool.GetPendingTransactionsCount(); Assert.That(numberOfTxsInTxPool, Is.EqualTo(numberOfTxsPossibleToExecuteBeforeGasExhaustion)); - Assert.That(_txPool.GetPendingTransactions()[numberOfTxsInTxPool - 1].Nonce, Is.EqualTo((UInt256)(numberOfTxsInTxPool - 1 + numberOfStaleTxsInBucket))); + Assert.That(_txPool.GetPendingTransactions()[numberOfTxsInTxPool - 1].Nonce, Is.EqualTo((ulong)(numberOfTxsInTxPool - 1 + numberOfStaleTxsInBucket))); } [Test] @@ -634,7 +634,7 @@ public void should_add_tx_if_cost_of_executing_all_txs_in_bucket_exceeds_balance { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)gasPrice) .WithGasLimit(TxGasLimit) .WithValue(value) @@ -650,13 +650,13 @@ public void should_add_tx_if_cost_of_executing_all_txs_in_bucket_exceeds_balance } Assert.That(_txPool.GetPendingTransactionsCount(), Is.EqualTo(8)); // nonces 0-6 and 8 - Assert.That(_txPool.GetPendingTransactions().Last().Nonce, Is.EqualTo((UInt256)8)); + Assert.That(_txPool.GetPendingTransactions().Last().Nonce, Is.EqualTo(8UL)); Assert.That(_txPool.SubmitTx(transactions[8], TxHandlingOptions.PersistentBroadcast), Is.EqualTo(AcceptTxResult.AlreadyKnown)); Assert.That(_txPool.SubmitTx(transactions[7], TxHandlingOptions.PersistentBroadcast), Is.EqualTo(AcceptTxResult.Accepted)); Assert.That(_txPool.GetPendingTransactionsCount(), Is.EqualTo(8)); // nonces 0-7 - 8 was removed because of not enough balance - Assert.That(_txPool.GetPendingTransactions().Last().Nonce, Is.EqualTo((UInt256)7)); + Assert.That(_txPool.GetPendingTransactions().Last().Nonce, Is.EqualTo(7UL)); Assert.That(_txPool.GetPendingTransactions(), Is.EqualTo(transactions.SkipLast(2))); } @@ -675,7 +675,7 @@ public void should_discard_tx_because_of_overflow_of_cumulative_cost_of_this_tx_ { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice(halfOfMaxGasPriceWithoutOverflow) .WithGasLimit(GasCostOf.Transaction) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; @@ -701,7 +701,7 @@ public async Task should_not_dump_GasBottleneck_of_all_txs_in_bucket_if_first_tx { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)(i + 2)) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; _txPool.SubmitTx(transactions[i], TxHandlingOptions.PersistentBroadcast); @@ -732,7 +732,7 @@ public async Task should_not_fail_if_there_is_no_current_nonce_in_bucket() { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i + 4) + .WithNonce((ulong)i + 4) .WithGasPrice((UInt256)(i + 2)) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; _txPool.SubmitTx(transactions[i], TxHandlingOptions.PersistentBroadcast); @@ -783,7 +783,7 @@ public void should_calculate_gasBottleneck_properly() { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)(i + 2)) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; }); @@ -809,7 +809,7 @@ public async Task should_remove_txs_with_old_nonces_when_updating_GasBottleneck( { transactions[i] = Build.A.Transaction .WithSenderAddress(TestItem.AddressA) - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasPrice((UInt256)(i + 2)) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).TestObject; _txPool.SubmitTx(transactions[i], TxHandlingOptions.PersistentBroadcast); @@ -862,7 +862,7 @@ public async Task should_remove_stale_txs_from_persistent_transactions(int numbe Parallel.For(0, numberOfTxs, i => { transactions[i] = Build.A.Transaction - .WithNonce((UInt256)i) + .WithNonce((ulong)i) .WithGasLimit(GasCostOf.Transaction) .WithGasPrice(10.GWei) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA) @@ -949,7 +949,7 @@ public void should_add_transactions_concurrently() { for (uint i = 0; i < 100; i++) { - Transaction tx = GetTransaction(i, GasCostOf.Transaction, 10.GWei, TestItem.AddressA, [], k); + Transaction tx = GetTransaction((ulong)i, GasCostOf.Transaction, 10.GWei, TestItem.AddressA, [], k); _txPool.SubmitTx(tx, TxHandlingOptions.None); } }); @@ -1090,7 +1090,7 @@ public void should_notify_added_peer_of_own_tx_when_we_are_synced([Values(0, 1)] _txPool = CreatePool(); _ = AddTransactionToPool(); ITxPoolPeer txPoolPeer = Substitute.For(); - txPoolPeer.HeadNumber.Returns(headNumber); + txPoolPeer.HeadNumber.Returns((ulong)headNumber); txPoolPeer.Id.Returns(TestItem.PublicKeyA); _txPool.AddPeer(txPoolPeer); txPoolPeer.Received(headNumber).SendNewTransactions(Arg.Any>(), false); @@ -1550,7 +1550,7 @@ public void Should_not_replace_better_txs_by_worse_ones() Parallel.For(0, txPoolConfig.Size, i => { txs[i] = Build.A.Transaction - .WithNonce((UInt256)(i + 1)) + .WithNonce((ulong)(i + 1)) .WithValue(0) .WithGasPrice(1000) .WithTo(TestItem.AddressB) @@ -1618,7 +1618,7 @@ public void Should_not_replace_ready_txs_by_nonce_gap_ones() Parallel.For(0, txPoolConfig.Size, i => { txs2[i] = Build.A.Transaction - .WithNonce((UInt256)(i + 1 + nonceGap)) + .WithNonce((ulong)(i + 1 + nonceGap)) .WithGasPrice(1000) .SignedAndResolved(_ethereumEcdsa, privateKeyOfAttacker).TestObject; }); @@ -1774,7 +1774,7 @@ private static IEnumerable DifferentOrderNonces() } [TestCaseSource(nameof(DifferentOrderNonces))] - public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(int firstNonce, int secondNonce, AcceptTxResult firstExpectation, AcceptTxResult secondExpectation) + public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(uint firstNonce, int secondNonce, AcceptTxResult firstExpectation, AcceptTxResult secondExpectation) { ISpecProvider specProvider = GetPragueSpecProvider(); TxPoolConfig txPoolConfig = new() { Size = 30, PersistentBlobStorageSize = 0 }; @@ -1786,7 +1786,7 @@ public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(in _stateProvider.InsertCode(signer.Address, delegation.AsMemory(), Prague.Instance); Transaction firstTx = Build.A.Transaction - .WithNonce((UInt256)firstNonce) + .WithNonce((ulong)firstNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(9.GWei) .WithMaxPriorityFeePerGas(9.GWei) @@ -1798,7 +1798,7 @@ public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(in Assert.That(result, Is.EqualTo(firstExpectation)); Transaction secondTx = Build.A.Transaction - .WithNonce((UInt256)secondNonce) + .WithNonce((ulong)secondNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(9.GWei) .WithMaxPriorityFeePerGas(9.GWei) @@ -1853,7 +1853,7 @@ public void Tx_with_conflicting_pending_delegation_is_rejected_then_is_accepted_ } Transaction secondTx = Build.A.Transaction - .WithNonce((UInt256)secondNonce) + .WithNonce((ulong)secondNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(12.GWei) .WithMaxPriorityFeePerGas(12.GWei) @@ -2233,7 +2233,7 @@ private Transaction[] GetTransactions(IDictionary peers private Transaction GetTransaction(PrivateKey privateKey, Address to = null, UInt256? nonce = null) { - Transaction transaction = GetTransaction(nonce ?? UInt256.Zero, GasCostOf.Transaction, (nonce ?? 999) + 1, to, [], privateKey); + Transaction transaction = GetTransaction((ulong)(nonce ?? UInt256.Zero), GasCostOf.Transaction, (nonce ?? 999) + 1, to, [], privateKey); EnsureSenderBalance(transaction); return transaction; } @@ -2269,7 +2269,7 @@ private void EnsureSenderBalance(Transaction transaction) private void EnsureSenderBalance(Address address, UInt256 balance) => _stateProvider.CreateAccount(address, balance); - private Transaction GetTransaction(UInt256 nonce, long gasLimit, UInt256 gasPrice, Address to, byte[] data, + private Transaction GetTransaction(ulong nonce, ulong gasLimit, UInt256 gasPrice, Address to, byte[] data, PrivateKey privateKey) => Build.A.Transaction .WithNonce(nonce) @@ -2315,7 +2315,7 @@ private async Task RaiseBlockAddedToMainAndWaitForNewHead(Block block, Block pre [Test] public async Task should_bring_back_reorganized_txs() { - const long blockNumber = 358; + const ulong blockNumber = 358; ITxPoolConfig txPoolConfig = new TxPoolConfig() { @@ -2368,7 +2368,7 @@ public async Task should_bring_back_reorganized_txs() [Test] public async Task should_return_fresh_pending_transactions_snapshot_after_head_change() { - const long blockNumber = 358; + const ulong blockNumber = 358; ITxPoolConfig txPoolConfig = new TxPoolConfig() { @@ -2404,7 +2404,7 @@ public async Task should_return_fresh_pending_transactions_snapshot_after_head_c [Test] public async Task should_return_valid_snapshot_when_reading_concurrently_during_head_change() { - const long blockNumber = 358; + const ulong blockNumber = 358; const int maxTryCount = 5; for (int attempt = 0; attempt < maxTryCount; attempt++) @@ -2476,7 +2476,7 @@ private static void AssertTransactionsEquivalent( private Transaction GetTx(PrivateKey sender) => Build.A.Transaction .WithMaxFeePerGas(1.GWei) .WithMaxPriorityFeePerGas(1.GWei) - .WithNonce(UInt256.Zero) + .WithNonce(0UL) .SignedAndResolved(_ethereumEcdsa, sender).TestObject; } } diff --git a/src/Nethermind/Nethermind.TxPool/BlobTxStorage.cs b/src/Nethermind/Nethermind.TxPool/BlobTxStorage.cs index 611181dabe29..ac4ad77130dd 100644 --- a/src/Nethermind/Nethermind.TxPool/BlobTxStorage.cs +++ b/src/Nethermind/Nethermind.TxPool/BlobTxStorage.cs @@ -111,7 +111,7 @@ public void Delete(in ValueHash256 hash, in UInt256 timestamp) _lightBlobTxsDb.Remove(hash.BytesAsSpan); } - public void AddBlobTransactionsFromBlock(long blockNumber, in ArrayPoolListRef blockBlobTransactions) + public void AddBlobTransactionsFromBlock(ulong blockNumber, in ArrayPoolListRef blockBlobTransactions) { if (blockBlobTransactions.Count == 0) { @@ -121,7 +121,7 @@ public void AddBlobTransactionsFromBlock(long blockNumber, in ArrayPoolListRef _processedBlobTxsDb.Delete(blockNumber); private static bool TryDecodeFullTx(byte[]? txBytes, Address sender, out Transaction? transaction) @@ -184,7 +184,7 @@ private void EncodeAndSaveTx(Transaction transaction, IDb db, Span txHashP db.PutSpan(txHashPrefixed, rlpStream.AsSpan()); } - private void EncodeAndSaveTxs(in ArrayPoolListRef blockBlobTransactions, IDb db, long blockNumber) + private void EncodeAndSaveTxs(in ArrayPoolListRef blockBlobTransactions, IDb db, ulong blockNumber) { using NettyRlpStream rlpStream = _txDecoder.EncodeToNewNettyStream(blockBlobTransactions!, RlpBehaviors.InMempoolForm); db.PutSpan(blockNumber.ToBigEndianSpanWithoutLeadingZeros(out _), rlpStream.AsSpan()); diff --git a/src/Nethermind/Nethermind.TxPool/Comparison/CompareReplacedTxByFee.cs b/src/Nethermind/Nethermind.TxPool/Comparison/CompareReplacedTxByFee.cs index c401b6709be9..fd5f3fa821b4 100644 --- a/src/Nethermind/Nethermind.TxPool/Comparison/CompareReplacedTxByFee.cs +++ b/src/Nethermind/Nethermind.TxPool/Comparison/CompareReplacedTxByFee.cs @@ -18,7 +18,7 @@ private CompareReplacedTxByFee() { } // To replace old transaction, new transaction needs to have fee higher by at least 10% (1/10) of current fee. // It is required to avoid acceptance and propagation of transaction with almost the same fee as replaced one. - private const int PartOfFeeRequiredToIncrease = 10; + private const ulong PartOfFeeRequiredToIncrease = 10; public int Compare(Transaction? newTx, Transaction? oldTx) { @@ -27,11 +27,11 @@ public int Compare(Transaction? newTx, Transaction? oldTx) if (newTx is null) return TxComparisonResult.TakeNew; // always allow replacement of zero fee txs (in legacy txs MaxFeePerGas equals GasPrice) - if (oldTx.MaxFeePerGas.IsZero) return TxComparisonResult.TakeNew; + if (oldTx.MaxFeePerGas == 0) return TxComparisonResult.TakeNew; if (!newTx.Supports1559 && !oldTx.Supports1559) { - oldTx.GasPrice.Divide(PartOfFeeRequiredToIncrease, out UInt256 bumpGasPrice); + UInt256 bumpGasPrice = oldTx.GasPrice / PartOfFeeRequiredToIncrease; int gasPriceResult = (oldTx.GasPrice + bumpGasPrice).CompareTo(newTx.GasPrice); // return TakeNew if fee bump is exactly by PartOfFeeRequiredToIncrease // never return NotDecided - it's allowed or not @@ -42,10 +42,10 @@ public int Compare(Transaction? newTx, Transaction? oldTx) /* MaxFeePerGas for legacy will be GasPrice and MaxPriorityFeePerGas will be GasPrice too so we can compare legacy txs without any problems */ - oldTx.MaxFeePerGas.Divide(PartOfFeeRequiredToIncrease, out UInt256 bumpMaxFeePerGas); + UInt256 bumpMaxFeePerGas = oldTx.MaxFeePerGas / PartOfFeeRequiredToIncrease; if (oldTx.MaxFeePerGas + bumpMaxFeePerGas > newTx.MaxFeePerGas) return TxComparisonResult.KeepOld; - oldTx.MaxPriorityFeePerGas.Divide(PartOfFeeRequiredToIncrease, out UInt256 bumpMaxPriorityFeePerGas); + UInt256 bumpMaxPriorityFeePerGas = oldTx.MaxPriorityFeePerGas / PartOfFeeRequiredToIncrease; int result = (oldTx.MaxPriorityFeePerGas + bumpMaxPriorityFeePerGas).CompareTo(newTx.MaxPriorityFeePerGas); // return TakeNew if fee bump is exactly by PartOfFeeRequiredToIncrease // never return NotDecided - it's allowed or not diff --git a/src/Nethermind/Nethermind.TxPool/Filters/GapNonceFilter.cs b/src/Nethermind/Nethermind.TxPool/Filters/GapNonceFilter.cs index 94a7e34a6a0b..8b55527de394 100644 --- a/src/Nethermind/Nethermind.TxPool/Filters/GapNonceFilter.cs +++ b/src/Nethermind/Nethermind.TxPool/Filters/GapNonceFilter.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.TxPool.Collections; @@ -30,8 +29,9 @@ public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandl int numberOfSenderTxsInPending = tx.SupportsBlobs ? _blobTxs.GetBucketCount(tx.SenderAddress!) : _txs.GetBucketCount(tx.SenderAddress!); // since unknownSenderFilter will run before this one - UInt256 currentNonce = state.SenderAccount.Nonce; - long nextNonceInOrder = (long)currentNonce + numberOfSenderTxsInPending; + ulong currentNonce = state.SenderAccount.Nonce; + // Cast numberOfSenderTxsInPending to ulong is safe; bucket counts are always non-negative and small. + ulong nextNonceInOrder = currentNonce + (ulong)numberOfSenderTxsInPending; bool isTxNonceNextInOrder = tx.Nonce <= nextNonceInOrder; if (!isTxNonceNextInOrder) { diff --git a/src/Nethermind/Nethermind.TxPool/Filters/GasLimitTxFilter.cs b/src/Nethermind/Nethermind.TxPool/Filters/GasLimitTxFilter.cs index 03d7ee6683a2..99aeec27974b 100644 --- a/src/Nethermind/Nethermind.TxPool/Filters/GasLimitTxFilter.cs +++ b/src/Nethermind/Nethermind.TxPool/Filters/GasLimitTxFilter.cs @@ -14,11 +14,11 @@ internal sealed class GasLimitTxFilter(IChainHeadInfoProvider chainHeadInfoProvi : IIncomingTxFilter { private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly long _configuredGasLimit = txPoolConfig.GasLimit ?? long.MaxValue; + private readonly ulong _configuredGasLimit = txPoolConfig.GasLimit ?? ulong.MaxValue; public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandlingOptions handlingOptions) { - long gasLimit = Math.Min(chainHeadInfoProvider.BlockGasLimit ?? long.MaxValue, _configuredGasLimit); + ulong gasLimit = Math.Min(chainHeadInfoProvider.BlockGasLimit ?? ulong.MaxValue, _configuredGasLimit); if (tx.GasLimit > gasLimit) { Metrics.PendingTransactionsGasLimitTooHigh++; diff --git a/src/Nethermind/Nethermind.TxPool/IBlobTxStorage.cs b/src/Nethermind/Nethermind.TxPool/IBlobTxStorage.cs index 44ffac43dbc9..efbd99b5f585 100644 --- a/src/Nethermind/Nethermind.TxPool/IBlobTxStorage.cs +++ b/src/Nethermind/Nethermind.TxPool/IBlobTxStorage.cs @@ -8,7 +8,7 @@ namespace Nethermind.TxPool; public interface IBlobTxStorage : ITxStorage { - bool TryGetBlobTransactionsFromBlock(long blockNumber, out Transaction[]? blockBlobTransactions); - void AddBlobTransactionsFromBlock(long blockNumber, in ArrayPoolListRef blockBlobTransactions); - void DeleteBlobTransactionsFromBlock(long blockNumber); + bool TryGetBlobTransactionsFromBlock(ulong blockNumber, out Transaction[]? blockBlobTransactions); + void AddBlobTransactionsFromBlock(ulong blockNumber, in ArrayPoolListRef blockBlobTransactions); + void DeleteBlobTransactionsFromBlock(ulong blockNumber); } diff --git a/src/Nethermind/Nethermind.TxPool/IChainHeadInfoProvider.cs b/src/Nethermind/Nethermind.TxPool/IChainHeadInfoProvider.cs index b673bf3eeadd..f5b0612b3d25 100644 --- a/src/Nethermind/Nethermind.TxPool/IChainHeadInfoProvider.cs +++ b/src/Nethermind/Nethermind.TxPool/IChainHeadInfoProvider.cs @@ -15,9 +15,9 @@ public interface IChainHeadInfoProvider IReadOnlyStateProvider ReadOnlyStateProvider { get; } - long HeadNumber { get; } + ulong HeadNumber { get; } - long? BlockGasLimit { get; } + ulong? BlockGasLimit { get; } UInt256 CurrentBaseFee { get; } diff --git a/src/Nethermind/Nethermind.TxPool/INonceManager.cs b/src/Nethermind/Nethermind.TxPool/INonceManager.cs index 4056ed54c484..656b364d0046 100644 --- a/src/Nethermind/Nethermind.TxPool/INonceManager.cs +++ b/src/Nethermind/Nethermind.TxPool/INonceManager.cs @@ -2,12 +2,11 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; -using Nethermind.Int256; namespace Nethermind.TxPool; public interface INonceManager { - NonceLocker ReserveNonce(Address address, out UInt256 reservedNonce); - NonceLocker TxWithNonceReceived(Address address, UInt256 nonce); + NonceLocker ReserveNonce(Address address, out ulong reservedNonce); + NonceLocker TxWithNonceReceived(Address address, ulong nonce); } diff --git a/src/Nethermind/Nethermind.TxPool/ITxPool.cs b/src/Nethermind/Nethermind.TxPool/ITxPool.cs index 18d24657306d..98f7e756b798 100644 --- a/src/Nethermind/Nethermind.TxPool/ITxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/ITxPool.cs @@ -61,7 +61,7 @@ bool TryGetBlobAndProofV1(byte[] blobVersionedHash, [NotNullWhen(true)] out byte[][]? cellProofs); int TryGetBlobsAndProofsV1(byte[][] requestedBlobVersionedHashes, byte[]?[] blobs, ReadOnlyMemory[] proofs); - UInt256 GetLatestPendingNonce(Address address); + ulong GetLatestPendingNonce(Address address); event EventHandler NewDiscovered; event EventHandler NewPending; event EventHandler RemovedPending; diff --git a/src/Nethermind/Nethermind.TxPool/ITxPoolConfig.cs b/src/Nethermind/Nethermind.TxPool/ITxPoolConfig.cs index d3adcc58273a..495e6d9e4855 100644 --- a/src/Nethermind/Nethermind.TxPool/ITxPoolConfig.cs +++ b/src/Nethermind/Nethermind.TxPool/ITxPoolConfig.cs @@ -42,7 +42,7 @@ public interface ITxPoolConfig : IConfig [ConfigItem(DefaultValue = "null", Description = "The max transaction gas allowed.")] - long? GasLimit { get; set; } + ulong? GasLimit { get; set; } [ConfigItem(DefaultValue = "131072", Description = "The max transaction size allowed, in bytes.")] diff --git a/src/Nethermind/Nethermind.TxPool/ITxPoolPeer.cs b/src/Nethermind/Nethermind.TxPool/ITxPoolPeer.cs index 50f48f78f0f3..8b661f1ffc64 100644 --- a/src/Nethermind/Nethermind.TxPool/ITxPoolPeer.cs +++ b/src/Nethermind/Nethermind.TxPool/ITxPoolPeer.cs @@ -11,7 +11,7 @@ public interface ITxPoolPeer { public PublicKey Id { get; } public string Enode => string.Empty; - long HeadNumber { get; set; } + ulong HeadNumber { get; set; } void SendNewTransaction(Transaction tx) => SendNewTransactions(new[] { tx }, true); void SendNewTransactions(IEnumerable txs, bool sendFullTx); } diff --git a/src/Nethermind/Nethermind.TxPool/ITxValidator.cs b/src/Nethermind/Nethermind.TxPool/ITxValidator.cs index 545f8973b671..b43db4eb51fa 100644 --- a/src/Nethermind/Nethermind.TxPool/ITxValidator.cs +++ b/src/Nethermind/Nethermind.TxPool/ITxValidator.cs @@ -9,7 +9,7 @@ namespace Nethermind.TxPool public interface ITxValidator { public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec); - public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, long blockGasLimit) => + public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec, ulong blockGasLimit) => IsWellFormed(transaction, releaseSpec); public const string HeadTxValidatorKey = "HeadTxValidator"; diff --git a/src/Nethermind/Nethermind.TxPool/LightTransaction.cs b/src/Nethermind/Nethermind.TxPool/LightTransaction.cs index 3cf8a3fdd619..ee41e4e905ff 100644 --- a/src/Nethermind/Nethermind.TxPool/LightTransaction.cs +++ b/src/Nethermind/Nethermind.TxPool/LightTransaction.cs @@ -35,12 +35,12 @@ public LightTransaction(Transaction fullTx) public LightTransaction( UInt256 timestamp, Address sender, - UInt256 nonce, + ulong nonce, Hash256 hash, - UInt256 value, - long gasLimit, - UInt256 gasPrice, - UInt256 maxFeePerGas, + ulong value, + ulong gasLimit, + ulong gasPrice, + ulong maxFeePerGas, UInt256 maxFeePerBlobGas, byte[][] blobVersionHashes, ulong poolIndex, diff --git a/src/Nethermind/Nethermind.TxPool/LightTxDecoder.cs b/src/Nethermind/Nethermind.TxPool/LightTxDecoder.cs index c4b471d73c47..51b6bdb3caea 100644 --- a/src/Nethermind/Nethermind.TxPool/LightTxDecoder.cs +++ b/src/Nethermind/Nethermind.TxPool/LightTxDecoder.cs @@ -14,7 +14,7 @@ private static int GetLength(Transaction tx) => Rlp.LengthOf(tx.Timestamp) + Rlp.LengthOf(tx.SenderAddress) + Rlp.LengthOf(tx.Nonce) + Rlp.LengthOf(tx.Hash) - + Rlp.LengthOf(in tx.ValueRef) + + Rlp.LengthOf(tx.Value) + Rlp.LengthOf(tx.GasLimit) + Rlp.LengthOf(tx.GasPrice) + Rlp.LengthOf(tx.DecodedMaxFeePerGas) @@ -32,7 +32,7 @@ public static byte[] Encode(Transaction tx) rlpStream.Encode(tx.SenderAddress); rlpStream.Encode(tx.Nonce); rlpStream.Encode(tx.Hash); - rlpStream.Encode(in tx.ValueRef); + rlpStream.Encode(tx.Value); rlpStream.Encode(tx.GasLimit); rlpStream.Encode(tx.GasPrice); rlpStream.Encode(tx.DecodedMaxFeePerGas); @@ -51,12 +51,12 @@ public static LightTransaction Decode(byte[] data) return new LightTransaction( timestamp: ctx.DecodeUInt256(), sender: ctx.DecodeAddress()!, - nonce: ctx.DecodeUInt256(), + nonce: ctx.DecodeULong(), hash: ctx.DecodeKeccak()!, - value: ctx.DecodeUInt256(), - gasLimit: ctx.DecodeLong(), - gasPrice: ctx.DecodeUInt256(), - maxFeePerGas: ctx.DecodeUInt256(), + value: ctx.DecodeULong(), + gasLimit: ctx.DecodeULong(), + gasPrice: ctx.DecodeULong(), + maxFeePerGas: ctx.DecodeULong(), maxFeePerBlobGas: ctx.DecodeUInt256(), blobVersionHashes: ctx.DecodeByteArrays(BlobTxDecoder.BlobVersionedHashesCountLimit, innerSize: Hash256.Size), poolIndex: ctx.DecodeULong(), diff --git a/src/Nethermind/Nethermind.TxPool/NonceManager.cs b/src/Nethermind/Nethermind.TxPool/NonceManager.cs index b426d321efee..7ae9a7b6160f 100644 --- a/src/Nethermind/Nethermind.TxPool/NonceManager.cs +++ b/src/Nethermind/Nethermind.TxPool/NonceManager.cs @@ -14,14 +14,14 @@ public class NonceManager(IAccountStateProvider accounts) : INonceManager private readonly ConcurrentDictionary _addressNonceManagers = new(); private readonly IAccountStateProvider _accounts = accounts; - public NonceLocker ReserveNonce(Address address, out UInt256 reservedNonce) + public NonceLocker ReserveNonce(Address address, out ulong reservedNonce) { AddressNonceManager addressNonceManager = _addressNonceManagers.GetOrAdd(address, static _ => new AddressNonceManager()); return addressNonceManager.ReserveNonce(_accounts.GetNonce(address), out reservedNonce); } - public NonceLocker TxWithNonceReceived(Address address, UInt256 nonce) + public NonceLocker TxWithNonceReceived(Address address, ulong nonce) { AddressNonceManager addressNonceManager = _addressNonceManagers.GetOrAdd(address, static _ => new AddressNonceManager()); @@ -30,18 +30,18 @@ public NonceLocker TxWithNonceReceived(Address address, UInt256 nonce) private class AddressNonceManager { - private readonly HashSet _usedNonces = []; - private UInt256 _currentNonce; - private UInt256 _reservedNonce; - private UInt256 _previousAccountNonce; + private readonly HashSet _usedNonces = []; + private ulong _currentNonce; + private ulong _reservedNonce; + private ulong _previousAccountNonce; private readonly SemaphoreSlim _accountLock = new(1); - public NonceLocker ReserveNonce(UInt256 accountNonce, out UInt256 reservedNonce) + public NonceLocker ReserveNonce(ulong accountNonce, out ulong reservedNonce) { NonceLocker locker = new(_accountLock, TxAccepted); ReleaseNonces(accountNonce); - _currentNonce = UInt256.Max(_currentNonce, accountNonce); + _currentNonce = ulong.Max(_currentNonce, accountNonce); _reservedNonce = _currentNonce; reservedNonce = _currentNonce; return locker; @@ -56,16 +56,16 @@ private void TxAccepted() } } - public NonceLocker TxWithNonceReceived(UInt256 nonce) + public NonceLocker TxWithNonceReceived(ulong nonce) { NonceLocker locker = new(_accountLock, TxAccepted); _reservedNonce = nonce; return locker; } - private void ReleaseNonces(UInt256 accountNonce) + private void ReleaseNonces(ulong accountNonce) { - for (UInt256 i = _previousAccountNonce; i < accountNonce; i++) + for (ulong i = _previousAccountNonce; i < accountNonce; i++) { _usedNonces.Remove(i); } diff --git a/src/Nethermind/Nethermind.TxPool/NullBlobTxStorage.cs b/src/Nethermind/Nethermind.TxPool/NullBlobTxStorage.cs index e7bf5bd0f406..c2468cddd34e 100644 --- a/src/Nethermind/Nethermind.TxPool/NullBlobTxStorage.cs +++ b/src/Nethermind/Nethermind.TxPool/NullBlobTxStorage.cs @@ -29,13 +29,13 @@ public void Add(Transaction transaction) { } public void Delete(in ValueHash256 hash, in UInt256 timestamp) { } - public bool TryGetBlobTransactionsFromBlock(long blockNumber, out Transaction[]? blockBlobTransactions) + public bool TryGetBlobTransactionsFromBlock(ulong blockNumber, out Transaction[]? blockBlobTransactions) { blockBlobTransactions = default; return false; } - public void AddBlobTransactionsFromBlock(long blockNumber, in ArrayPoolListRef blockBlobTransactions) { } + public void AddBlobTransactionsFromBlock(ulong blockNumber, in ArrayPoolListRef blockBlobTransactions) { } - public void DeleteBlobTransactionsFromBlock(long blockNumber) { } + public void DeleteBlobTransactionsFromBlock(ulong blockNumber) { } } diff --git a/src/Nethermind/Nethermind.TxPool/NullTxPool.cs b/src/Nethermind/Nethermind.TxPool/NullTxPool.cs index 0c5828873544..08cb3e7ee942 100644 --- a/src/Nethermind/Nethermind.TxPool/NullTxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/NullTxPool.cs @@ -88,7 +88,7 @@ public bool TryGetBlobAndProofV1(byte[] blobVersionedHash, public int TryGetBlobsAndProofsV1(byte[][] requestedBlobVersionedHashes, byte[]?[] blobs, ReadOnlyMemory[] proofs) => 0; - public UInt256 GetLatestPendingNonce(Address address) => 0; + public ulong GetLatestPendingNonce(Address address) => 0; public AnnounceResult NotifyAboutTx(Hash256 txhash, IMessageHandler retryHandler) => AnnounceResult.RequestRequired; diff --git a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs index a2a2030ceb0d..399f5e79de53 100644 --- a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs @@ -18,7 +18,7 @@ public static class TransactionExtensions public static int GetLength(this Transaction tx, bool shouldCountBlobs = true) => tx.GetLength(_transactionSizeCalculator, shouldCountBlobs); - public static bool CanPayBaseFee(this Transaction tx, UInt256 currentBaseFee) => tx.MaxFeePerGas >= currentBaseFee; + public static bool CanPayBaseFee(this Transaction tx, UInt256 currentBaseFee) => (UInt256)tx.MaxFeePerGas >= currentBaseFee; public static bool CanPayForBlobGas(this Transaction tx, UInt256 currentPricePerBlobGas) => !tx.SupportsBlobs || tx.MaxFeePerBlobGas >= currentPricePerBlobGas; @@ -43,17 +43,17 @@ internal static UInt256 CalculateAffordableGasPrice(this Transaction tx, bool ei { if (eip1559Enabled && tx.Supports1559) { - if (balance > tx.ValueRef && tx.GasLimit > 0) + if (balance > tx.Value && tx.GasLimit > 0) { UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(eip1559Enabled, baseFee); effectiveGasPrice.Multiply((UInt256)tx.GasLimit, out UInt256 gasCost); - if (balance >= tx.ValueRef + gasCost) + if (balance >= tx.Value + gasCost) { return effectiveGasPrice; } - UInt256 balanceAvailableForFeePayment = balance - tx.ValueRef; + UInt256 balanceAvailableForFeePayment = balance - tx.Value; balanceAvailableForFeePayment.Divide((UInt256)tx.GasLimit, out UInt256 payablePricePerGasUnit); return payablePricePerGasUnit; } @@ -61,7 +61,7 @@ internal static UInt256 CalculateAffordableGasPrice(this Transaction tx, bool ei return 0; } - return balance <= tx.ValueRef ? default : tx.GasPrice; + return balance <= tx.Value ? default : tx.GasPrice; } internal static bool CheckForNotEnoughBalance(this Transaction tx, UInt256 currentCost, UInt256 balance, out UInt256 cumulativeCost) @@ -71,9 +71,9 @@ internal static bool IsOverflowWhenAddingTxCostToCumulative(this Transaction tx, { bool overflow = false; - overflow |= UInt256.MultiplyOverflow(tx.MaxFeePerGas, (UInt256)tx.GasLimit, out UInt256 maxTxCost); + overflow |= UInt256.MultiplyOverflow((UInt256)tx.MaxFeePerGas, tx.GasLimit, out UInt256 maxTxCost); overflow |= UInt256.AddOverflow(currentCost, maxTxCost, out cumulativeCost); - overflow |= UInt256.AddOverflow(in cumulativeCost, in tx.ValueRef, out cumulativeCost); + overflow |= UInt256.AddOverflow(cumulativeCost, (UInt256)tx.Value, out cumulativeCost); if (tx.SupportsBlobs) { diff --git a/src/Nethermind/Nethermind.TxPool/TxBroadcaster.cs b/src/Nethermind/Nethermind.TxPool/TxBroadcaster.cs index 0f2feaf2cdab..d7fa96c131cb 100644 --- a/src/Nethermind/Nethermind.TxPool/TxBroadcaster.cs +++ b/src/Nethermind/Nethermind.TxPool/TxBroadcaster.cs @@ -280,7 +280,7 @@ public void StopBroadcast(Hash256 txHash) } } - public void EnsureStopBroadcastUpToNonce(Address address, UInt256 nonce) + public void EnsureStopBroadcastUpToNonce(Address address, ulong nonce) { if (_persistentTxs.Count != 0) { diff --git a/src/Nethermind/Nethermind.TxPool/TxPool.cs b/src/Nethermind/Nethermind.TxPool/TxPool.cs index 84453d4d8f48..27aba788358e 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPool.cs @@ -79,7 +79,7 @@ public class TxPool : ITxPool, IAsyncDisposable private readonly ITimer? _timer; private volatile Transaction[]? _transactionSnapshot; private volatile Transaction[]? _blobTransactionSnapshot; - private long _lastBlockNumber = -1; + private ulong _lastBlockNumber = ulong.MaxValue; private Hash256? _lastBlockHash; private bool _isDisposed; @@ -743,7 +743,7 @@ private void UpdateBucketWithAddedTransaction(in AccountStruct account, Enhanced if (transactions.Count != 0) { UInt256 balance = account.Balance; - long currentNonce = (long)(account.Nonce); + ulong currentNonce = account.Nonce; UpdateGasBottleneckAndMarkForEviction(transactions, currentNonce, balance, lastElement, updateTx); } @@ -751,7 +751,7 @@ private void UpdateBucketWithAddedTransaction(in AccountStruct account, Enhanced private void UpdateGasBottleneckAndMarkForEviction( EnhancedSortedSet transactions, - long currentNonce, + ulong currentNonce, UInt256 balance, Transaction? lastElement, UpdateTransactionDelegate updateTx) @@ -791,7 +791,7 @@ private void UpdateGasBottleneckAndMarkForEviction( { gasBottleneck = UInt256.Zero; } - else if (tx.Nonce == currentNonce + i) + else if (tx.Nonce == currentNonce + (ulong)i) { UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(_specProvider.GetCurrentHeadSpec().IsEip1559Enabled, @@ -845,7 +845,7 @@ private void UpdateBucket(in AccountStruct account, EnhancedSortedSet 0; if (!hasPendingTxs && !(_blobTransactions.GetBucketCount(address) > 0)) @@ -955,7 +955,7 @@ public UInt256 GetLatestPendingNonce(Address address) { // if we don't have any gaps we can easily calculate the nonce Transaction lastTransaction = transactions.Max!; - if (maxPendingNonce + (UInt256)transactions.Count - 1 == lastTransaction.Nonce) + if (maxPendingNonce + (ulong)transactions.Count - 1 == lastTransaction.Nonce) { maxPendingNonce = lastTransaction.Nonce + 1; } diff --git a/src/Nethermind/Nethermind.TxPool/TxPoolConfig.cs b/src/Nethermind/Nethermind.TxPool/TxPoolConfig.cs index f1ada728b43b..c31fc01072bf 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPoolConfig.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPoolConfig.cs @@ -20,7 +20,7 @@ public class TxPoolConfig : ITxPoolConfig public int MaxPendingTxsPerSender { get; set; } = 0; public int MaxPendingBlobTxsPerSender { get; set; } = 16; public int HashCacheSize { get; set; } = 512 * 1024; - public long? GasLimit { get; set; } = null; + public ulong? GasLimit { get; set; } = null; public long? MaxTxSize { get; set; } = 128.KiB; public long? MaxBlobTxSize { get; set; } = 1.MiB; public bool ProofsTranslationEnabled { get; set; } = false; diff --git a/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs b/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs index 212c58538b1e..5e7465b0cee1 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs @@ -100,11 +100,11 @@ private void AddSenderToCounts( // Note: TxTypeTxFilter prevents a sender from holding both types simultaneously, so // the merge case is rare in practice but the API handles it correctly anyway. private static (IDictionary pending, IDictionary queued) - SplitByNonce(Transaction[]? standard, Transaction[]? blobs, UInt256 accountNonce) + SplitByNonce(Transaction[]? standard, Transaction[]? blobs, ulong accountNonce) { Dictionary pending = []; Dictionary queued = []; - UInt256 expectedNonce = accountNonce; + ulong expectedNonce = accountNonce; int i = 0; int j = 0; @@ -116,7 +116,7 @@ private static (IDictionary pending, IDictionary pending, IDictionary(), LimboLogs.Instance); - private static QuorumCertificate BuildQc(string seed, ulong round, long number) + private static QuorumCertificate BuildQc(string seed, ulong round, ulong number) { Hash256 hash = Keccak.Compute(seed); return new QuorumCertificate(new BlockRoundInfo(hash, round, number), [], 450); diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/TestXdcBlockProducer.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/TestXdcBlockProducer.cs index c9ead7a91bf0..03ab66e2d6d6 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/TestXdcBlockProducer.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/TestXdcBlockProducer.cs @@ -66,7 +66,7 @@ private Address GetLeaderAddress(XdcBlockHeader currentHead, ulong round, IXdcRe masternodes = epochSwitchInfo!.Masternodes; } - int currentLeaderIndex = ((int)round % spec.EpochLength % masternodes.Length); + int currentLeaderIndex = (int)(round % spec.EpochLength % (ulong)masternodes.Length); return masternodes[currentLeaderIndex]; } } diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/TransactionBuilderXdcExtensions.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/TransactionBuilderXdcExtensions.cs index ee80662cd98b..c2b89772ceec 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/TransactionBuilderXdcExtensions.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/TransactionBuilderXdcExtensions.cs @@ -25,10 +25,10 @@ public static TransactionBuilder ToBlockSignerContract( /// Calldata = 4-byte selector + 32-byte big-endian uint + 32-byte bytes32 (68 bytes total). /// public static TransactionBuilder WithXdcSigningData( - this TransactionBuilder b, long blockNumber, Hash256 blockHash) + this TransactionBuilder b, ulong blockNumber, Hash256 blockHash) => b.WithData(CreateSigningCalldata(blockNumber, blockHash)); - private static byte[] CreateSigningCalldata(long blockNumber, Hash256 blockHash) + private static byte[] CreateSigningCalldata(ulong blockNumber, Hash256 blockHash) { Span data = stackalloc byte[68]; // 4 + 32 + 32 @@ -36,7 +36,7 @@ private static byte[] CreateSigningCalldata(long blockNumber, Hash256 blockHash) SignSelector.CopyTo(data); // 4..35: uint256 blockNumber (big-endian, right-aligned in 32 bytes) - byte[] be = BitConverter.GetBytes((ulong)blockNumber); + byte[] be = BitConverter.GetBytes(blockNumber); if (BitConverter.IsLittleEndian) Array.Reverse(be); // last 8 bytes of that 32 are the ulong for (int i = 0; i < 8; i++) data[4 + 24 + i] = be[i]; diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcBlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcBlockHeaderBuilder.cs index 79b96eff3bde..43dcc2f620ff 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcBlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcBlockHeaderBuilder.cs @@ -93,7 +93,7 @@ public XdcBlockHeaderBuilder WithExtraConsensusData(ExtraFieldsV2 extraFieldsV2) return this; } - public new XdcBlockHeaderBuilder WithNumber(long blockNumber) + public new XdcBlockHeaderBuilder WithNumber(ulong blockNumber) { TestObjectInternal.Number = blockNumber; return this; diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcModuleTestOverrides.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcModuleTestOverrides.cs index 02821ffc47e8..93027e2ad2a4 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcModuleTestOverrides.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcModuleTestOverrides.cs @@ -83,7 +83,7 @@ protected override void Load(ContainerBuilder builder) internal class RandomPenaltyHandler(ISpecProvider specProvider) : IPenaltyHandler { readonly Dictionary _penaltiesCache = []; - public Address[] Penalize(long number, Hash256 currentHash, Address[] candidates, int count = 2) + public Address[] Penalize(ulong number, Hash256 currentHash, Address[] candidates, int count = 2) { IXdcReleaseSpec spec = specProvider.GetFinalSpec() as IXdcReleaseSpec ?? throw new ArgumentException("Must have XDC spec configured."); if (number == spec.SwitchBlock) @@ -107,7 +107,7 @@ public Address[] Penalize(long number, Hash256 currentHash, Address[] candidates _penaltiesCache[currentHash] = penalized.ToArray(); return _penaltiesCache[currentHash]; } - public Address[] HandlePenalties(long number, Hash256 currentHash, Address[] candidates) + public Address[] HandlePenalties(ulong number, Hash256 currentHash, Address[] candidates) => Penalize(number, currentHash, candidates, 7); } diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcSubnetBlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcSubnetBlockHeaderBuilder.cs index b0fe8716c8f2..12770a0dc772 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcSubnetBlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcSubnetBlockHeaderBuilder.cs @@ -20,7 +20,7 @@ public class XdcSubnetBlockHeaderBuilder : XdcBlockHeaderBuilder return this; } - public new XdcSubnetBlockHeaderBuilder WithNumber(long blockNumber) + public new XdcSubnetBlockHeaderBuilder WithNumber(ulong blockNumber) { base.WithNumber(blockNumber); return this; diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs index 10443ecadfa5..25461c9c57fc 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs @@ -224,7 +224,7 @@ private IXdcReleaseSpec WrapReleaseSpec(IReleaseSpec spec) xdcSpec.ObserverReward = Unit.Ether / 2; // 0.5 Ether in Wei per observer xdcSpec.MinimumMinerBlockPerEpoch = 1; xdcSpec.MinimumSigningTx = 1; - xdcSpec.GasLimitBoundDivisor = 1024; + xdcSpec.GasLimitBoundDivisor = 1024UL; xdcSpec.LimitPenaltyEpoch = 4; xdcSpec.LimitPenaltyEpochV2 = 0; @@ -389,7 +389,7 @@ private sealed class PresetPenaltyHistoryHandler( IBlockTree blockTree, IEpochSwitchManager epochSwitchManager) : IPenaltyHandler { - public Address[] HandlePenalties(long number, Hash256 currentHash, Address[] candidates) + public Address[] HandlePenalties(ulong number, Hash256 currentHash, Address[] candidates) { if (candidates.Length == 0) { @@ -438,7 +438,7 @@ public Task StopHotStuffModule() public async Task AddBlocks(int count, bool withTransaction = false) { - UInt256 nonce = 0; + ulong nonce = 0; for (int i = 0; i < count; i++) { @@ -485,8 +485,9 @@ public async Task SimulateVoting() Address leader = ConsensusModule.GetLeaderAddress(head, XdcContext.CurrentRound, spec); EpochSwitchInfo epochSwitchInfo = EpochSwitchManager.GetEpochSwitchInfo(head)!; - long epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - long gapNumber = epochSwitchNumber == 0 ? 0 : Math.Max(0, epochSwitchNumber - epochSwitchNumber % spec.EpochLength - spec.Gap); + ulong epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong temp = epochSwitchNumber - epochSwitchNumber % spec.EpochLength; + ulong gapNumber = epochSwitchNumber == 0 ? 0UL : (temp > spec.Gap ? temp - spec.Gap : 0UL); VoteDecoder voteDecoder = new(); @@ -506,7 +507,7 @@ public async Task SimulateVoting() break; } //Will cast a random master candidate vote for the head block and when vote threshold is reached the block should be proposed - Vote vote = new(new BlockRoundInfo(head.Hash!, head.ExtraConsensusData?.BlockRound ?? XdcContext.CurrentRound, head.Number), (ulong)gapNumber); + Vote vote = new(new BlockRoundInfo(head.Hash!, head.ExtraConsensusData?.BlockRound ?? XdcContext.CurrentRound, head.Number), gapNumber); SignRandom(vote); Task voteTask = this.VotesManager.OnReceiveVote(vote); } @@ -568,7 +569,8 @@ public void CreateAndCommitQC(XdcBlockHeader header) IXdcReleaseSpec headSpec = SpecProvider.GetXdcSpec(header, XdcContext.CurrentRound); EpochSwitchInfo switchInfo = EpochSwitchManager.GetEpochSwitchInfo(header.Hash!)!; - ulong gap = (ulong)Math.Max(0, switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % headSpec.EpochLength - headSpec.Gap); + ulong baseBlockNum = switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % headSpec.EpochLength; + ulong gap = baseBlockNum >= headSpec.Gap ? baseBlockNum - headSpec.Gap : 0UL; PrivateKey[] masterNodes = TakeRandomMasterNodes(headSpec, switchInfo); QuorumCertificate headQc = XdcTestHelper.CreateQc(new BlockRoundInfo(header.Hash!, header.ExtraConsensusData?.BlockRound ?? XdcContext.CurrentRound, header.Number), gap, masterNodes); diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestHelper.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestHelper.cs index aaf48ed92271..e7dedcd66e02 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestHelper.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestHelper.cs @@ -56,7 +56,7 @@ public static Timeout BuildSignedTimeout(PrivateKey key, ulong round, ulong gap) public static SyncInfo BuildSyncInfo(PrivateKey key, ulong round, ulong gap) { - BlockRoundInfo roundInfo = new(Hash256.Zero, round, (long)round); + BlockRoundInfo roundInfo = new(Hash256.Zero, round, round); QuorumCertificate qc = CreateQc(roundInfo, gap, [key]); Timeout timeout = BuildSignedTimeout(key, round, gap); TimeoutCertificate tc = new(round, [timeout.Signature!], gap); diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/PenaltyTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/PenaltyTests.cs index 819b1b83e623..8b725d387746 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/PenaltyTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/PenaltyTests.cs @@ -11,7 +11,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; -using Nethermind.Int256; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Test.Helpers; using Nethermind.Xdc.Types; @@ -35,13 +34,13 @@ public async Task TestHookPenaltyV2Comeback() PenaltyHandler penaltyHandler = CreatePenaltyHandler(chain); ISigningTxCache signingTxCache = chain.Container.Resolve(); IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - await chain.AddBlocks(spec.EpochLength * 3); + await chain.AddBlocks((int)(spec.EpochLength * 3)); spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - long epoch = spec.EpochLength; - long targetHeight = spec.SwitchBlock + epoch * 3; + ulong epoch = spec.EpochLength; + ulong targetHeight = spec.SwitchBlock + epoch * 3; - XdcBlockHeader firstEpochHeader = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch + 1)!; + XdcBlockHeader firstEpochHeader = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch + 1UL)!; EpochSwitchInfo? epochInfo = chain.EpochSwitchManager.GetEpochSwitchInfo(firstEpochHeader); Assert.That(epochInfo, Is.Not.Null); Address[] masternodes = epochInfo.Masternodes; @@ -67,13 +66,13 @@ public async Task TestHookPenaltyV2Jump() PenaltyHandler penaltyHandler = CreatePenaltyHandler(chain); IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - await chain.AddBlocks(spec.EpochLength * 3); + await chain.AddBlocks((int)(spec.EpochLength * 3)); spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - long epoch = spec.EpochLength; - long targetHeight = spec.SwitchBlock + epoch * 3 - spec.MergeSignRange; + ulong epoch = spec.EpochLength; + ulong targetHeight = spec.SwitchBlock + epoch * 3 - spec.MergeSignRange; - XdcBlockHeader firstEpochHeader = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch + 1)!; + XdcBlockHeader firstEpochHeader = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch + 1UL)!; Address[] masternodes = chain.EpochSwitchManager.GetEpochSwitchInfo(firstEpochHeader)!.Masternodes; XdcBlockHeader targetHeader = (XdcBlockHeader)chain.BlockTree.FindHeader(targetHeight)!; @@ -89,13 +88,13 @@ public async Task TestGetPenalties() ConfigureFastPenaltySpec(chain); PenaltyHandler penaltyHandler = CreatePenaltyHandler(chain); IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - await chain.AddBlocks(spec.EpochLength * 3); + await chain.AddBlocks((int)(spec.EpochLength * 3)); spec = chain.SpecProvider.GetXdcSpec((XdcBlockHeader)chain.BlockTree.Head!.Header); - long epoch = spec.EpochLength; + ulong epoch = spec.EpochLength; - XdcBlockHeader headerBeforeThirdEpochSwitch = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch * 3 - 1)!; - XdcBlockHeader headerAfterSecondEpochSwitch = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch * 2 + 1)!; + XdcBlockHeader headerBeforeThirdEpochSwitch = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch * 3 - 1UL)!; + XdcBlockHeader headerAfterSecondEpochSwitch = (XdcBlockHeader)chain.BlockTree.FindHeader(spec.SwitchBlock + epoch * 2 + 1UL)!; Assert.That(penaltyHandler.GetPenalties(headerBeforeThirdEpochSwitch), Has.Length.EqualTo(1)); Assert.That(penaltyHandler.GetPenalties(headerAfterSecondEpochSwitch), Has.Length.EqualTo(1)); @@ -105,11 +104,11 @@ public async Task TestGetPenalties() public void TestHookPenaltyParolee() { MockedPenaltyContext context = CreateMockedPenaltyContext( - targetEpoch: EpochLength * 3L, + targetEpoch: EpochLength * 3UL, limitPenaltyEpoch: 2, shouldPenalizeAtSwitch: _ => true); - long secondEpoch = EpochLength * 2L; - long thirdEpoch = EpochLength * 3L; + ulong secondEpoch = EpochLength * 2UL; + ulong thirdEpoch = EpochLength * 3UL; // Parole logic is not yet active, only the "not mining enough" penalty applies Address[] penaltiesAtSecondEpoch = context.PenaltyHandler.HandlePenalties(secondEpoch, context.BlockHeaders[(int)(secondEpoch - 1)].Hash!, context.MasternodesAddress); @@ -139,10 +138,10 @@ public void TestHookPenaltyParolee() public void TestHookPenaltyParoleeCustomized() { MockedPenaltyContext context = CreateMockedPenaltyContext( - targetEpoch: EpochLength * 7L, + targetEpoch: EpochLength * 7UL, limitPenaltyEpoch: 4, - shouldPenalizeAtSwitch: switchBlock => switchBlock != EpochLength * 4L); - long targetEpoch = EpochLength * 7L; + shouldPenalizeAtSwitch: switchBlock => switchBlock != EpochLength * 4UL); + ulong targetEpoch = EpochLength * 7UL; CacheSigningTxAt(context, targetEpoch - MergeSignRange); CacheSigningTxAt(context, targetEpoch - MergeSignRange * 2, nonce: 1); @@ -170,10 +169,10 @@ private static void ConfigureFastPenaltySpec(XdcTestBlockchain chain, bool activ private static PrivateKey GetPenaltyHistorySigner(XdcTestBlockchain chain, Address penaltyAddress) => chain.MasterNodeCandidates.First(k => k.Address == penaltyAddress); - private static Transaction BuildSigningTx(IXdcReleaseSpec spec, long blockNumber, Hash256 blockHash, PrivateKey signer, long nonce = 0) => + private static Transaction BuildSigningTx(IXdcReleaseSpec spec, ulong blockNumber, Hash256 blockHash, PrivateKey signer, ulong nonce = 0) => Build.A.Transaction .WithChainId(0) - .WithNonce((UInt256)nonce) + .WithNonce(nonce) .WithGasLimit(200000) .WithXdcSigningData(blockNumber, blockHash) .ToBlockSignerContract(spec) @@ -181,9 +180,9 @@ private static Transaction BuildSigningTx(IXdcReleaseSpec spec, long blockNumber .TestObject; private static MockedPenaltyContext CreateMockedPenaltyContext( - long targetEpoch, + ulong targetEpoch, int limitPenaltyEpoch, - System.Func shouldPenalizeAtSwitch) + System.Func shouldPenalizeAtSwitch) { PrivateKey[] masternodes = XdcTestHelper.GeneratePrivateKeys(TestMasternodeCount); Address[] masternodesAddress = masternodes.Select(privateKey => privateKey.Address).ToArray(); @@ -201,7 +200,7 @@ private static MockedPenaltyContext CreateMockedPenaltyContext( { Hash256 parentHash = i == 0 ? Hash256.Zero : blockHeaders[i - 1].Hash!; blockHeaders[i] = Build.A.XdcBlockHeader() - .WithNumber(i) + .WithNumber((ulong)i) .WithParentHash(parentHash) .WithValidators(masternodesAddress) .WithExtraConsensusData(new ExtraFieldsV2((ulong)i, Build.A.QuorumCertificate().TestObject)) @@ -209,25 +208,25 @@ private static MockedPenaltyContext CreateMockedPenaltyContext( .TestObject; blockHeaders[i].Beneficiary = masternodes[i % (masternodes.Length - 1)].Address; - if (!shouldPenalizeAtSwitch(i)) blockHeaders[i].Penalties = []; + if (!shouldPenalizeAtSwitch((ulong)i)) blockHeaders[i].Penalties = []; Hash256 hash = blockHeaders[i].Hash ?? blockHeaders[i].CalculateHash().ToHash256(); hashToHeader[hash] = blockHeaders[i]; blocks[i] = new Block(blockHeaders[i]); hashToBlock[hash] = blocks[i]; } - blockTree.FindHeader(Arg.Any(), Arg.Any()) + blockTree.FindHeader(Arg.Any(), Arg.Any()) .Returns(ci => hashToHeader[ci.ArgAt(0)]); - blockTree.FindBlock(Arg.Any(), Arg.Any()) + blockTree.FindBlock(Arg.Any(), Arg.Any()) .Returns(ci => hashToBlock.TryGetValue(ci.ArgAt(0), out Block? block) ? block : null); blockTree.Head.Returns(blocks.Last()); IXdcReleaseSpec xdcSpec = Substitute.For(); - xdcSpec.EpochLength.Returns(EpochLength); - xdcSpec.SwitchBlock.Returns(0); - xdcSpec.MergeSignRange.Returns(MergeSignRange); + xdcSpec.EpochLength.Returns((ulong)EpochLength); + xdcSpec.SwitchBlock.Returns(0UL); + xdcSpec.MergeSignRange.Returns((ulong)MergeSignRange); xdcSpec.IsTipUpgradePenaltyEnabled.Returns(true); - xdcSpec.LimitPenaltyEpoch.Returns(limitPenaltyEpoch); + xdcSpec.LimitPenaltyEpoch.Returns((ulong)limitPenaltyEpoch); xdcSpec.MinimumSigningTx.Returns(2); xdcSpec.MinimumMinerBlockPerEpoch.Returns(1); @@ -240,18 +239,18 @@ private static MockedPenaltyContext CreateMockedPenaltyContext( epochSwitchManager.GetEpochSwitchInfo(Arg.Any()).Returns(ci => { XdcBlockHeader header = hashToHeader[(Hash256)ci.Args()[0]]; - long switchEpoch = header.Number / EpochLength * EpochLength; + ulong switchEpoch = header.Number / EpochLength * EpochLength; return new EpochSwitchInfo( masternodesAddress, [], blockHeaders[(int)switchEpoch].PenaltiesAddress?.ToArray() ?? [], - new BlockRoundInfo(blockHeaders[(int)switchEpoch].Hash!, (ulong)switchEpoch, switchEpoch)); + new BlockRoundInfo(blockHeaders[(int)switchEpoch].Hash!, switchEpoch, switchEpoch)); }); epochSwitchManager.GetBlockByEpochNumber(Arg.Any()).Returns(ci => { - long blockNumber = EpochLength * (long)(ulong)ci.Args()[0]; + ulong blockNumber = EpochLength * (ulong)ci.Args()[0]; XdcBlockHeader header = blockHeaders[(int)blockNumber]; - return new BlockRoundInfo(header.Hash!, (ulong)blockNumber, blockNumber); + return new BlockRoundInfo(header.Hash!, blockNumber, blockNumber); }); ISigningTxCache signingTxCache = new SigningTxCache(blockTree, specProvider); @@ -259,7 +258,7 @@ private static MockedPenaltyContext CreateMockedPenaltyContext( return new MockedPenaltyContext(blockHeaders, masternodesAddress, penaltySigner, xdcSpec, signingTxCache, penaltyHandler); } - private static void CacheSigningTxAt(MockedPenaltyContext context, long signedBlockNumber, long nonce = 0) + private static void CacheSigningTxAt(MockedPenaltyContext context, ulong signedBlockNumber, ulong nonce = 0) { XdcBlockHeader signedHeader = context.BlockHeaders[(int)signedBlockNumber]; context.SigningTxCache.SetSigningTransactions( diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs index 7b4be3fd9e22..9f2bda699147 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs @@ -8,7 +8,6 @@ using Nethermind.Xdc.Test.Helpers; using Nethermind.Xdc.Types; using NUnit.Framework; -using System; using System.Linq; using System.Threading.Tasks; @@ -30,11 +29,11 @@ public async Task TestShouldSendVoteMsgAndCommitGreatGrandparentBlockAsync() PrivateKey[] masternodes = blockChain.TakeRandomMasterNodes(spec, switchInfo); BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - long gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0 ? 0 : Math.Max(0, switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); //We skip 1 vote so we are 1 under the vote threshold, proving that if the round advances the module cast a vote itself foreach (PrivateKey? key in masternodes.Skip(1)) { - Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, (ulong)gapNumber, key); + Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, gapNumber, key); await blockChain.VotesManager.HandleVote(vote); } @@ -101,11 +100,11 @@ public async Task TestProposedBlockMessageHandlerSuccessfullyGenerateVote() PrivateKey[] masternodes = blockChain.TakeRandomMasterNodes(spec, switchInfo); BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - long gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0 ? 0 : Math.Max(0, switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); //We skip 1 vote so we are 1 under the vote threshold foreach (PrivateKey? key in masternodes.Skip(1)) { - Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, (ulong)gapNumber, key); + Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, gapNumber, key); await blockChain.VotesManager.HandleVote(vote); } @@ -140,8 +139,8 @@ public async Task CanBuildAFinalizedChain(int count) using XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(0, true); blockChain.ChangeReleaseSpec((s) => { - s.EpochLength = 90; - s.Gap = 45; + s.EpochLength = 90UL; + s.Gap = 45UL; }); await blockChain.AddBlocks(3); @@ -153,9 +152,9 @@ public async Task CanBuildAFinalizedChain(int count) for (int i = 1; i <= count; i++) { await blockChain.TriggerAndSimulateBlockProposalAndVoting(); - Assert.That(blockChain.BlockTree.Head.Number, Is.EqualTo(startBlock.Number + i)); - Assert.That(blockChain.XdcContext.HighestQC!.ProposedBlockInfo.BlockNumber, Is.EqualTo(startBlock.Number + i)); - Assert.That(blockChain.XdcContext.HighestCommitBlock.BlockNumber, Is.EqualTo(blockChain.XdcContext.HighestQC!.ProposedBlockInfo.BlockNumber - 2)); + Assert.That(blockChain.BlockTree.Head.Number, Is.EqualTo(startBlock.Number + (ulong)i)); + Assert.That(blockChain.XdcContext.HighestQC!.ProposedBlockInfo.BlockNumber, Is.EqualTo(startBlock.Number + (ulong)i)); + Assert.That(blockChain.XdcContext.HighestCommitBlock.BlockNumber, Is.EqualTo(blockChain.XdcContext.HighestQC!.ProposedBlockInfo.BlockNumber - 2UL)); } } @@ -180,11 +179,11 @@ public async Task TestProposedBlockMessageHandlerNotGenerateVoteIfSignerNotInMNl } BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - long gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0 ? 0 : Math.Max(0, switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); //We skip 1 vote so we are 1 under the vote threshold foreach (PrivateKey? key in masternodes.Skip(1)) { - Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, (ulong)gapNumber, key); + Vote vote = XdcTestHelper.BuildSignedVote(votingBlock, gapNumber, key); await blockChain.VotesManager.HandleVote(vote); } diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RewardTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RewardTests.cs index 495a5c051459..14e896d48b0a 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RewardTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RewardTests.cs @@ -64,14 +64,14 @@ public async Task TestHookRewardV2() XdcBlockHeader head = (XdcBlockHeader)chain.BlockTree.Head!.Header; IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec(head, chain.XdcContext.CurrentRound); - long epochLength = spec.EpochLength; - long mergeSignRange = spec.MergeSignRange; + ulong epochLength = spec.EpochLength; + ulong mergeSignRange = spec.MergeSignRange; - long initialHeadNumber = chain.BlockTree.Head!.Number; + ulong initialHeadNumber = chain.BlockTree.Head!.Number; // --- Part 1: create signing tx for header (E + mergeSignRange) included in next block --- - long targetSignedHeaderNumberEPlusMerge = epochLength + mergeSignRange; + ulong targetSignedHeaderNumberEPlusMerge = epochLength + mergeSignRange; await chain.AddBlocks((int)(targetSignedHeaderNumberEPlusMerge - initialHeadNumber)); XdcBlockHeader? signedHeaderEPlusMerge = chain.BlockTree.Head!.Header as XdcBlockHeader; @@ -83,12 +83,12 @@ await chain.AddBlock(BuildSigningTx( signedHeaderEPlusMerge.Number, signedHeaderEPlusMerge.Hash ?? signedHeaderEPlusMerge.CalculateHash().ToHash256(), chain.Signer.Key!, - (long)chain.ReadOnlyState.GetNonce(chain.Signer.Address))); + chain.ReadOnlyState.GetNonce(chain.Signer.Address))); // --- Move to header (3E - mergeSignRange) to sign it later in Part 2 --- - long blockNumberAfterIncludingSignTx = chain.BlockTree.Head!.Number; - long targetSignedHeader3EMinusMerge = 3 * epochLength - mergeSignRange; + ulong blockNumberAfterIncludingSignTx = chain.BlockTree.Head!.Number; + ulong targetSignedHeader3EMinusMerge = 3 * epochLength - mergeSignRange; await chain.AddBlocks((int)(targetSignedHeader3EMinusMerge - blockNumberAfterIncludingSignTx)); XdcBlockHeader? signedHeader3EMinusMerge = chain.BlockTree.Head!.Header as XdcBlockHeader; @@ -96,8 +96,8 @@ await chain.AddBlock(BuildSigningTx( // --- Evaluate rewards at checkpoint (3E) --- - long headBeforeCheckpoint = chain.BlockTree.Head!.Number; - long checkpoint3E = 3 * epochLength; + ulong headBeforeCheckpoint = chain.BlockTree.Head!.Number; + ulong checkpoint3E = 3 * epochLength; await chain.AddBlocks((int)(checkpoint3E - headBeforeCheckpoint)); Block block3E = chain.BlockTree.Head!; @@ -122,8 +122,8 @@ await chain.AddBlock(BuildSigningTx( // === Part 2: signing hash in a different epoch still counts === // Place signing tx for the previously captured (3E - mergeSignRange) header in block (3E + mergeSignRange + 1) - long targetIncludingBlockForSecondSign = 3 * epochLength + mergeSignRange + 1; - long current = chain.BlockTree.Head!.Number; + ulong targetIncludingBlockForSecondSign = 3 * epochLength + mergeSignRange + 1; + ulong current = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(targetIncludingBlockForSecondSign - current - 1)); // move so AddBlockMayHaveExtraTx produces the target // For 4E reward calculation, the masternodes come from the second epoch switch found @@ -143,10 +143,10 @@ await chain.AddBlock(BuildSigningTx( signedHeader3EMinusMerge.Number, signedHeader3EMinusMerge.Hash ?? signedHeader3EMinusMerge.CalculateHash().ToHash256(), signerForPart2, - (long)chain.ReadOnlyState.GetNonce(signerForPart2.Address))); + chain.ReadOnlyState.GetNonce(signerForPart2.Address))); // --- Evaluate rewards at checkpoint (4E) --- - long checkpoint4E = 4 * epochLength; + ulong checkpoint4E = 4 * epochLength; current = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(checkpoint4E - current)); @@ -166,7 +166,7 @@ await chain.AddBlock(BuildSigningTx( // === Part 3: if no signing tx, reward should be empty === - long checkpoint5E = 5 * epochLength; + ulong checkpoint5E = 5 * epochLength; current = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(checkpoint5E - current)); @@ -200,15 +200,15 @@ public async Task TestHookRewardV2SplitReward() XdcBlockHeader head = (XdcBlockHeader)chain.BlockTree.Head!.Header; IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec(head, chain.XdcContext.CurrentRound); - long epochLength = spec.EpochLength; - long mergeSignRange = spec.MergeSignRange; + ulong epochLength = spec.EpochLength; + ulong mergeSignRange = spec.MergeSignRange; // - Insert 1 signing tx for header (E + mergeSignRange) signed by signerA into block (E + mergeSignRange + 1) // - Insert 2 signing txs (one for header (E + mergeSignRange), one for header (2E - mergeSignRange)) signed by signerB into block (2E - 1) // - Verify: rewards at (3E) split 1:2 between A:B with 90/10 owner/foundation - long initialHeadNumber = chain.BlockTree.Head!.Number; - long targetHeaderEPlusMerge = epochLength + mergeSignRange; + ulong initialHeadNumber = chain.BlockTree.Head!.Number; + ulong targetHeaderEPlusMerge = epochLength + mergeSignRange; await chain.AddBlocks((int)(targetHeaderEPlusMerge - initialHeadNumber)); XdcBlockHeader headerEPlusMerge = (XdcBlockHeader)chain.BlockTree.Head!.Header; @@ -229,16 +229,16 @@ public async Task TestHookRewardV2SplitReward() await chain.AddBlock(txA); // advances by 1 - long targetHeader2EMinusMerge = 2 * epochLength - mergeSignRange; - long currentHeadNumber = chain.BlockTree.Head!.Number; + ulong targetHeader2EMinusMerge = 2 * epochLength - mergeSignRange; + ulong currentHeadNumber = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(targetHeader2EMinusMerge - currentHeadNumber)); XdcBlockHeader header2EMinusMerge = (XdcBlockHeader)chain.BlockTree.Head!.Header; // Create a block (2E - 1) containing 2 signing txs from signerB. // Move to (2E - 2) so that AddBlock puts us at (2E - 1). - long targetBlock2EMinus1 = 2 * epochLength - 1; - long targetBlock2EMinus2 = targetBlock2EMinus1 - 1; + ulong targetBlock2EMinus1 = 2 * epochLength - 1; + ulong targetBlock2EMinus2 = targetBlock2EMinus1 - 1; currentHeadNumber = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(targetBlock2EMinus2 - currentHeadNumber)); @@ -263,7 +263,7 @@ public async Task TestHookRewardV2SplitReward() await chain.AddBlock(txBForEPlusMerge, txBFor2EMinusMerge); // now at (2E - 1) - long checkpoint3E = 3 * epochLength; + ulong checkpoint3E = 3 * epochLength; currentHeadNumber = chain.BlockTree.Head!.Number; await chain.AddBlocks((int)(checkpoint3E - currentHeadNumber)); @@ -295,14 +295,14 @@ public async Task TestHookRewardV2SplitReward() [Test] public void RewardCalculator_SplitReward_MatchesRounding() { - const long epochLength = 45; - const long totalRewardInEther = 250; + const ulong epochLength = 45; + const ulong totalRewardInEther = 250; - const long mergeSignRange = 15; - const long firstSignedBlockNumber = mergeSignRange; - const long secondSignedBlockNumber = 2 * mergeSignRange; - const long firstIncludedTxBlockNumber = firstSignedBlockNumber + 1; - const long secondIncludedTxBlockNumber = secondSignedBlockNumber + 1; + const ulong mergeSignRange = 15; + const ulong firstSignedBlockNumber = mergeSignRange; + const ulong secondSignedBlockNumber = 2 * mergeSignRange; + const ulong firstIncludedTxBlockNumber = firstSignedBlockNumber + 1; + const ulong secondIncludedTxBlockNumber = secondSignedBlockNumber + 1; PrivateKey[] masternodes = XdcTestHelper.GeneratePrivateKeys(2); PrivateKey signerA = masternodes.First(); @@ -316,11 +316,11 @@ public void RewardCalculator_SplitReward_MatchesRounding() .Returns(ci => ((XdcBlockHeader)ci.Args()[0]!).Number % epochLength == 0); IXdcReleaseSpec xdcSpec = Substitute.For(); - xdcSpec.EpochLength.Returns((int)epochLength); + xdcSpec.EpochLength.Returns(epochLength); xdcSpec.FoundationWallet.Returns(foundationWalletAddr); xdcSpec.BlockSignerContract.Returns(blockSignerContract); xdcSpec.Reward.Returns(totalRewardInEther); - xdcSpec.SwitchBlock.Returns(0); + xdcSpec.SwitchBlock.Returns(0UL); xdcSpec.MergeSignRange.Returns(mergeSignRange); xdcSpec.IsTipUpgradeRewardEnabled.Returns(false); @@ -328,12 +328,12 @@ public void RewardCalculator_SplitReward_MatchesRounding() specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); IBlockTree tree = Substitute.For(); - long chainSize = 2 * epochLength + 1; + ulong chainSize = 2 * epochLength + 1; XdcBlockHeader[] blockHeaders = new XdcBlockHeader[chainSize]; Block[] blocks = new Block[chainSize]; Address[] masternodeAddresses = masternodes.Select(m => m.Address).ToArray(); - for (int i = 0; i <= epochLength * 2; i++) + for (ulong i = 0; i <= epochLength * 2; i++) { XdcBlockHeaderBuilder builder = Build.A.XdcBlockHeader() .WithNumber(i) @@ -363,10 +363,42 @@ public void RewardCalculator_SplitReward_MatchesRounding() blocks[firstIncludedTxBlockNumber] = new Block(blockHeaders[firstIncludedTxBlockNumber], new BlockBody(txsAtFirstIncludedBlock.ToArray(), null, null)); blocks[secondIncludedTxBlockNumber] = new Block(blockHeaders[secondIncludedTxBlockNumber], new BlockBody(txsAtSecondIncludedBlock.ToArray(), null, null)); - tree.FindHeader(Arg.Any(), Arg.Any()) - .Returns(ci => blockHeaders[(int)(long)ci.Args()[1]]); - tree.FindBlock(Arg.Any(), Arg.Any()) - .Returns(ci => blocks[(int)(long)ci.Args()[1]]); + tree.FindHeader(Arg.Any(), Arg.Any()) + .Returns(ci => + { + ulong? num = ci.ArgAt(1); + if (num is not null) + { + return blockHeaders[(int)num.Value]; + } + Hash256 hash = ci.ArgAt(0); + for (int idx = 0; idx < blockHeaders.Length; idx++) + { + if (blockHeaders[idx].Hash == hash) + { + return blockHeaders[idx]; + } + } + return null; + }); + tree.FindBlock(Arg.Any(), Arg.Any()) + .Returns(ci => + { + ulong? num = ci.ArgAt(1); + if (num is not null) + { + return blocks[(int)num.Value]; + } + Hash256 hash = ci.ArgAt(0); + for (int idx = 0; idx < blocks.Length; idx++) + { + if (blocks[idx].Hash == hash) + { + return blocks[idx]; + } + } + return null; + }); IMasternodeVotingContract votingContract = Substitute.For(); votingContract.GetCandidateOwner(Arg.Any(), Arg.Any(), Arg.Any
()) @@ -395,9 +427,9 @@ public void RewardCalculator_SplitReward_MatchesRounding() [Test] public void TestHookRewardAfterUpgrade() { - const long epochLength = 900; - const long mergeSignRange = 15; - const long checkpointNumber = 2700; + const ulong epochLength = 900; + const ulong mergeSignRange = 15; + const ulong checkpointNumber = 2700; PrivateKey[] keys = XdcTestHelper.GeneratePrivateKeys(9); PrivateKey[] masternodeKeys = [keys[0], keys[1], keys[2], keys[3], keys[4]]; @@ -418,10 +450,10 @@ public void TestHookRewardAfterUpgrade() .Returns(ci => ((XdcBlockHeader)ci.Args()[0]!).Number % epochLength == 0); IXdcReleaseSpec xdcSpec = Substitute.For(); - xdcSpec.EpochLength.Returns((int)epochLength); + xdcSpec.EpochLength.Returns(epochLength); xdcSpec.FoundationWallet.Returns(foundationWalletAddr); xdcSpec.BlockSignerContract.Returns(blockSignerContract); - xdcSpec.SwitchBlock.Returns(0); + xdcSpec.SwitchBlock.Returns(0UL); xdcSpec.MergeSignRange.Returns(mergeSignRange); xdcSpec.IsTipUpgradeRewardEnabled.Returns(true); xdcSpec.MaxProtectorNodes.Returns(2); @@ -434,11 +466,11 @@ public void TestHookRewardAfterUpgrade() specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); IBlockTree tree = Substitute.For(); - int chainSize = (int)(checkpointNumber + 1); + ulong chainSize = checkpointNumber + 1; XdcBlockHeader[] blockHeaders = new XdcBlockHeader[chainSize]; Block[] blocks = new Block[chainSize]; - for (int i = 0; i < chainSize; i++) + for (ulong i = 0; i < chainSize; i++) { XdcBlockHeaderBuilder builder = Build.A.XdcBlockHeader() .WithNumber(i) @@ -480,10 +512,10 @@ public void TestHookRewardAfterUpgrade() blocks[916] = new Block(blockHeaders[916], new BlockBody(txsAt916, null, null)); blocks[1799] = new Block(blockHeaders[1799], new BlockBody(txsAt1799, null, null)); - tree.FindHeader(Arg.Any(), Arg.Any()) - .Returns(ci => blockHeaders[(int)(long)ci.Args()[1]]); - tree.FindBlock(Arg.Any(), Arg.Any()) - .Returns(ci => blocks[(int)(long)ci.Args()[1]]); + tree.FindHeader(Arg.Any(), Arg.Any()) + .Returns(ci => blockHeaders[(int)ci.ArgAt(1)!]); + tree.FindBlock(Arg.Any(), Arg.Any()) + .Returns(ci => blocks[(int)ci.ArgAt(1)!]); IMasternodeVotingContract votingContract = Substitute.For(); votingContract.GetCandidateOwner(Arg.Any(), Arg.Any(), Arg.Any
()) @@ -567,7 +599,7 @@ public void RewardCalculator_CalculateRewardsForSignersAndHolders_MatchesExpecte ); UInt256 totalReward = UInt256.Parse("171000000000000000000"); - long totalSigner = 177, sign = 59; + ulong totalSigner = 177, sign = 59; UInt256 expectedReward = UInt256.Parse("56999999999999999983"); Assert.That(rewardCalculator.CalculateProportionalReward(sign, totalSigner, totalReward), Is.EqualTo(expectedReward)); @@ -584,7 +616,7 @@ public void RewardCalculator_CalculateRewardsForSignersAndHolders_MatchesExpecte Assert.That(foundationWalletReward, Is.EqualTo(expectedAmountFoundationWallet)); } - private static Transaction BuildSigningTx(IXdcReleaseSpec spec, long blockNumber, Hash256 blockHash, PrivateKey signer, long nonce = 0) + private static Transaction BuildSigningTx(IXdcReleaseSpec spec, ulong blockNumber, Hash256 blockHash, PrivateKey signer, ulong nonce = 0) { // These are protocol constants (not "test magic numbers"): const int signingTxGasLimit = 200_000; @@ -592,7 +624,7 @@ private static Transaction BuildSigningTx(IXdcReleaseSpec spec, long blockNumber return Build.A.Transaction .WithChainId(chainId) - .WithNonce((UInt256)nonce) + .WithNonce(nonce) .WithGasLimit(signingTxGasLimit) .WithXdcSigningData(blockNumber, blockHash) .ToBlockSignerContract(spec) diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/SubnetPenaltyTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/SubnetPenaltyTests.cs index 3ee37c348fef..ff0e26876b07 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/SubnetPenaltyTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/SubnetPenaltyTests.cs @@ -10,7 +10,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; -using Nethermind.Int256; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Test.Helpers; using Nethermind.Xdc.Types; @@ -36,7 +35,7 @@ public void TestNoPenalty() validatorSelector: (validators, i) => validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; + ulong target = EpochLength * 3 - Gap; Address[] penalties = ctx.Handler.HandlePenalties( target, ctx.Headers[(int)(target - 1)].Hash!, @@ -56,7 +55,7 @@ public void TestNoMinedBlocksInEpochPenalty(int absentEpoch) validatorSelector: (validators, i) => i / EpochLength == absentEpoch ? validators[i % (ValidatorCount - 1)] : validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; + ulong target = EpochLength * 3 - Gap; Address[] penalties = ctx.Handler.HandlePenalties( target, ctx.Headers[(int)(target - 1)].Hash!, @@ -74,13 +73,13 @@ public void TestKeepPreviousPenalties() validatorSelector: (validators, i) => validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; + ulong target = EpochLength * 3 - Gap; Address[] injectedPenalties = [TestItem.AddressA, TestItem.AddressB]; byte[] penaltyBytes = new byte[injectedPenalties.Length * Address.Size]; for (int i = 0; i < injectedPenalties.Length; i++) injectedPenalties[i].Bytes.CopyTo(penaltyBytes.AsSpan(i * Address.Size)); - ctx.Headers[target - EpochLength + 1].Penalties = penaltyBytes; + ctx.Headers[(int)(target - EpochLength + 1)].Penalties = penaltyBytes; Address[] penalties = ctx.Handler.HandlePenalties( target, @@ -99,9 +98,9 @@ public void TestSigningTxRemovesPenalty() validatorSelector: (validators, i) => i / EpochLength == 2 ? validators[i % (ValidatorCount - 1)] : validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; - long signBlock = (target - 1) / MergeSignRange * MergeSignRange; - BlockHeader header = ctx.Headers[signBlock]; + ulong target = EpochLength * 3 - Gap; + ulong signBlock = (target - 1) / MergeSignRange * MergeSignRange; + BlockHeader header = ctx.Headers[(int)signBlock]; Transaction tx = BuildSigningTx(ctx.Spec, header.Number, header.Hash!, ctx.ValidatorKeys.Last()); ctx.HashToBlock[header.Hash!] = new Block(header, [tx], Array.Empty()); @@ -121,9 +120,9 @@ public void TestSigningTxBeforeRangeReturnSigner() validatorSelector: (validators, i) => i / EpochLength == 2 ? validators[i % (ValidatorCount - 1)] : validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; - long signBlock = (target - 1 - (long)RangeReturnSigner) / MergeSignRange * MergeSignRange; - BlockHeader header = ctx.Headers[signBlock]; + ulong target = EpochLength * 3 - Gap; + ulong signBlock = (target - 1 - RangeReturnSigner) / MergeSignRange * MergeSignRange; + BlockHeader header = ctx.Headers[(int)signBlock]; Transaction tx = BuildSigningTx(ctx.Spec, header.Number, header.Hash!, ctx.ValidatorKeys.Last()); ctx.HashToBlock[header.Hash!] = new Block(header, [tx], Array.Empty()); @@ -145,9 +144,9 @@ public void TestSigningTxForNonMergeSignRangeBlock() validatorSelector: (validators, i) => i / EpochLength == 2 ? validators[i % (ValidatorCount - 1)] : validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; - long signBlock = (target - 1) / MergeSignRange * MergeSignRange - 1; - BlockHeader header = ctx.Headers[signBlock]; + ulong target = EpochLength * 3 - Gap; + ulong signBlock = (target - 1) / MergeSignRange * MergeSignRange - 1; + BlockHeader header = ctx.Headers[(int)signBlock]; Transaction tx = BuildSigningTx(ctx.Spec, header.Number, header.Hash!, ctx.ValidatorKeys.Last()); ctx.HashToBlock[header.Hash!] = new Block(header, [tx], Array.Empty()); @@ -167,7 +166,7 @@ public void TestSortOrder() validatorSelector: (validators, i) => validators[i % ValidatorCount] ); - long target = EpochLength * 3 - Gap; + ulong target = EpochLength * 3 - Gap; Address eip55First = new("0xECf1aC276D2D3333483cF394d2F73BaB6915feCb"); Address eip55Second = new("0xe3eE640071486df6A007021c34D52b5DE7be94e3"); @@ -179,7 +178,7 @@ public void TestSortOrder() byte[] penaltyBytes = new byte[injectedPenalties.Length * Address.Size]; for (int i = 0; i < injectedPenalties.Length; i++) injectedPenalties[i].Bytes.CopyTo(penaltyBytes.AsSpan(i * Address.Size)); - ctx.Headers[target - EpochLength + 1].Penalties = penaltyBytes; + ctx.Headers[(int)(target - EpochLength + 1)].Penalties = penaltyBytes; Address[] penalties = ctx.Handler.HandlePenalties( target, @@ -192,10 +191,10 @@ public void TestSortOrder() // ─── Helpers ────────────────────────────────────────────────────── private static Transaction BuildSigningTx( - IXdcReleaseSpec spec, long blockNumber, Hash256 blockHash, PrivateKey signer, long nonce = 0) => + IXdcReleaseSpec spec, ulong blockNumber, Hash256 blockHash, PrivateKey signer, ulong nonce = 0) => Build.A.Transaction .WithChainId(0) - .WithNonce((UInt256)nonce) + .WithNonce(nonce) .WithGasLimit(200000) .WithXdcSigningData(blockNumber, blockHash) .ToBlockSignerContract(spec) @@ -224,7 +223,7 @@ private static MockedSubnetPenaltyContext CreateMockedContext( { Hash256 parentHash = i == 0 ? Hash256.Zero : headers[i - 1].Hash!; XdcSubnetBlockHeaderBuilder builder = Build.A.XdcSubnetBlockHeader(); - builder.WithNumber(i); + builder.WithNumber((ulong)i); builder.WithParentHash(parentHash); builder.WithValidators(validatorAddresses); builder.WithExtraConsensusData(new ExtraFieldsV2((ulong)i, Build.A.QuorumCertificate().TestObject)); @@ -238,9 +237,9 @@ private static MockedSubnetPenaltyContext CreateMockedContext( hashToBlock[hash] = blocks[i]; } - blockTree.FindHeader(Arg.Any(), Arg.Any()) + blockTree.FindHeader(Arg.Any(), Arg.Any()) .Returns(ci => hashToHeader.TryGetValue(ci.ArgAt(0), out XdcSubnetBlockHeader? h) ? h : null); - blockTree.FindBlock(Arg.Any(), Arg.Any()) + blockTree.FindBlock(Arg.Any(), Arg.Any()) .Returns(ci => hashToBlock.TryGetValue(ci.ArgAt(0), out Block? block) ? block : null); blockTree.Head.Returns(blocks.Last()); @@ -265,13 +264,13 @@ private static MockedSubnetPenaltyContext CreateMockedContext( .Returns(ci => { XdcBlockHeader header = (XdcBlockHeader)ci.Args()[0]; - long switchEpoch = header.Number / EpochLength * EpochLength; + ulong switchEpoch = header.Number / EpochLength * EpochLength; int idx = Math.Min((int)switchEpoch, chainLength - 1); return new EpochSwitchInfo( validatorAddresses, [], headers[idx].PenaltiesAddress?.ToArray() ?? [], - new BlockRoundInfo(headers[idx].Hash!, (ulong)switchEpoch, switchEpoch)); + new BlockRoundInfo(headers[idx].Hash!, switchEpoch, switchEpoch)); }); ISigningTxCache signingTxCache = new SigningTxCache(blockTree, specProvider); diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/VotesManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/VotesManagerTests.cs index 82021b5c3dbe..4280b4d11068 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/VotesManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/VotesManagerTests.cs @@ -71,7 +71,7 @@ public async Task HandleVote_VariousScenarios_CommitsQcExpectedTimes(Address[] m XdcConsensusContext context = new(); context.SetNewRound(currentRound); IBlockTree blockTree = Substitute.For(); - blockTree.FindHeader(Arg.Any(), Arg.Any()).Returns(header); + blockTree.FindHeader(Arg.Any(), Arg.Any()).Returns(header); IEpochSwitchManager epochSwitchManager = Substitute.For(); EpochSwitchInfo epochSwitchInfo = new(masternodes, [], [], info); @@ -137,7 +137,7 @@ public async Task HandleVote_HeaderMissing_ReturnsEarly() quorumCertificateManager.DidNotReceive().CommitCertificate(Arg.Any()); // Now insert header and send one more - blockTree.FindHeader(header.Hash!, Arg.Any()).Returns(header); + blockTree.FindHeader(header.Hash!, Arg.Any()).Returns(header); await voteManager.HandleVote(XdcTestHelper.BuildSignedVote(info, 450, keys.Last())); quorumCertificateManager.Received(1).CommitCertificate(Arg.Any()); @@ -325,11 +325,11 @@ private static VotesManager BuildVoteManager(IXdcConsensusContext ctx, IBlockTre specProvider, signer, forensicsProcessor, NullLogManager.Instance); } - private static XdcBlockHeader[] GenerateBlockHeaders(int n, long blockNumber) + private static XdcBlockHeader[] GenerateBlockHeaders(int n, ulong blockNumber) { XdcBlockHeader[] headers = new XdcBlockHeader[n]; Hash256 parentHash = Hash256.Zero; - long number = blockNumber; + ulong number = blockNumber; for (int i = 0; i < n; i++, number++) { headers[i] = Build.A.XdcBlockHeader() diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcReorgModuleTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcReorgModuleTests.cs index c4dbf6c59ed4..7f255d35172c 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcReorgModuleTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcReorgModuleTests.cs @@ -96,7 +96,7 @@ public async Task AfterReorgSnapshotManagerReturnsSnapshotForNewChainGapBlock() blockChain.ChangeReleaseSpec(spec => { spec.EpochLength = 10; spec.Gap = 5; }); await blockChain.AddBlocks(3); - const long gapBlockNumber = 5; + const ulong gapBlockNumber = 5; XdcBlockHeader originalChainGapBlock = (XdcBlockHeader)blockChain.BlockTree.FindHeader(gapBlockNumber)!; diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcTestBlockchainTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcTestBlockchainTests.cs index d750c0958da2..df6bb8e0c098 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcTestBlockchainTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/XdcTestBlockchainTests.cs @@ -29,16 +29,16 @@ public async Task SetupXdcChainAndValidateAllHeaders(int count) //Shorten the epoch length so we can run the test faster _blockchain.ChangeReleaseSpec((c) => { - c.EpochLength = 90; - c.Gap = 45; + c.EpochLength = 90UL; + c.Gap = 45UL; }); await _blockchain.AddBlocks(count); IHeaderValidator headerValidator = _blockchain.Container.Resolve(); BlockHeader parent = _blockchain.BlockTree.Genesis!; - for (int i = 1; i < _blockchain.BlockTree.Head!.Number; i++) + for (ulong i = 1; i < _blockchain.BlockTree.Head!.Number; i++) { - Block? block = _blockchain.BlockTree.FindBlock(i); + Block? block = _blockchain.BlockTree.FindBlock(i, Nethermind.Blockchain.BlockTreeLookupOptions.None); Assert.That(block, Is.Not.Null); Assert.That(headerValidator.Validate(block!.Header, parent, false, out string? error), Is.True, "Header validation failed: " + error); parent = block.Header; diff --git a/src/Nethermind/Nethermind.Xdc.Test/QuorumCertificateManagerTest.cs b/src/Nethermind/Nethermind.Xdc.Test/QuorumCertificateManagerTest.cs index bc9f9f71af0c..dadc5db8efbb 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/QuorumCertificateManagerTest.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/QuorumCertificateManagerTest.cs @@ -108,8 +108,8 @@ public void VerifyCertificate_QcWithDifferentParameters_ReturnsExpected(QuorumCe .Returns(new EpochSwitchInfo(masternodes.ToArray(), [], [], new BlockRoundInfo(Hash256.Zero, 1, 10))); ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.EpochLength.Returns(900); - xdcReleaseSpec.Gap.Returns(450); + xdcReleaseSpec.EpochLength.Returns(900UL); + xdcReleaseSpec.Gap.Returns(450UL); xdcReleaseSpec.CertificateThreshold.Returns(0.667); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); QuorumCertificateManager quorumCertificateManager = new( @@ -128,8 +128,8 @@ public void Initialize_GenesisBlockWithNoConsensusData_SetsHighestQCAndRound() { ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.SwitchBlock.Returns(900L); - xdcReleaseSpec.Gap.Returns(450); + xdcReleaseSpec.SwitchBlock.Returns(900UL); + xdcReleaseSpec.Gap.Returns(450UL); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); XdcConsensusContext context = new(); QuorumCertificateManager quorumCertificateManager = new( @@ -323,7 +323,7 @@ public void OnUpdateMainChain_GenesisBlock_CallsInitialize() IBlockTree blockTree = Substitute.For(); ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.SwitchBlock.Returns(900L); + xdcReleaseSpec.SwitchBlock.Returns(900UL); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); _ = new QuorumCertificateManager( context, @@ -348,7 +348,7 @@ public void OnUpdateMainChain_NonGenesisBlockWithValidQc_UpdatesHighestQc() IBlockTree blockTree = Substitute.For(); ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.SwitchBlock.Returns(100L); + xdcReleaseSpec.SwitchBlock.Returns(100UL); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); blockTree.FindHeader(Arg.Any()).Returns(Build.A.XdcBlockHeader().WithNumber(1).TestObject); context.HighestQC = Build.A.QuorumCertificate().WithBlockInfo(new BlockRoundInfo(Hash256.Zero, 0, 0)).TestObject; diff --git a/src/Nethermind/Nethermind.Xdc.Test/SignTransactionFilterTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SignTransactionFilterTests.cs index 1e144b881647..ad0a9358f172 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SignTransactionFilterTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SignTransactionFilterTests.cs @@ -32,18 +32,18 @@ private static SignTransactionFilter CreateFilter(Block? head, Snapshot? snapsho IXdcReleaseSpec xdcSpec = Substitute.For(); xdcSpec.BlockSignerContract.Returns(BlockSignerContract); xdcSpec.RandomizeSMCBinary.Returns(RandomizeSMC); - xdcSpec.EpochLength.Returns(900); + xdcSpec.EpochLength.Returns(900UL); ISpecProvider specProvider = Substitute.For(); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetSnapshotByBlockNumber(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetSnapshotByBlockNumber(Arg.Any(), Arg.Any()).Returns(snapshot); return new SignTransactionFilter(snapshotManager, blockTree, specProvider); } - private static Block HeadBlock(long number = 100) => + private static Block HeadBlock(ulong number = 100) => Build.A.Block.WithHeader(Build.A.XdcBlockHeader().WithNumber(number).TestObject).TestObject; [Test] diff --git a/src/Nethermind/Nethermind.Xdc.Test/SnapshotManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SnapshotManagerTests.cs index 976f647a30e7..c5b1ecb386a6 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SnapshotManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SnapshotManagerTests.cs @@ -32,8 +32,8 @@ internal class SnapshotManagerTests public void Setup() { _xdcReleaseSpec = Substitute.For(); - _xdcReleaseSpec.EpochLength.Returns(900); - _xdcReleaseSpec.Gap.Returns(450); + _xdcReleaseSpec.EpochLength.Returns(900UL); + _xdcReleaseSpec.Gap.Returns(450UL); _snapshotDb = new MemDb(); _blockTree = Substitute.For(); @@ -59,7 +59,7 @@ public void GetSnapshot_ShouldReturnNullForNonExistentSnapshot() public void GetSnapshot_ShouldRetrieveFromIfFound() { // Arrange - const int gapBlock = 0; + const ulong gapBlock = 0; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; Snapshot snapshot = new(gapBlock, header.Hash!, [Address.FromNumber(1)]); _snapshotManager.StoreSnapshot(snapshot); @@ -85,7 +85,7 @@ public void GetSnapshot_ShouldReturnNullForEmptyDb() public void GetSnapshot_ShouldRetrieveFromDbIfNotInCache() { // Arrange - const int gapBlock = 0; + const ulong gapBlock = 0; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; Snapshot snapshot = new(gapBlock, header.Hash!, [Address.FromNumber(1)]); _snapshotManager.StoreSnapshot(snapshot); @@ -102,7 +102,7 @@ public void GetSnapshot_ShouldRetrieveFromDbIfNotInCache() public void StoreSnapshot_ShouldStoreSnapshotInDb() { // Arrange - const int gapBlock = 0; + const ulong gapBlock = 0; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; Snapshot snapshot = new(gapBlock, header.Hash!, [Address.FromNumber(1)]); _blockTree.FindHeader(gapBlock).Returns(header); @@ -119,7 +119,7 @@ public void StoreSnapshot_ShouldStoreSnapshotInDb() public void GetSnapshot_ShouldReturnSnapshotIfExists() { // setup a snapshot and store it - const int gapBlock1 = 0; + const ulong gapBlock1 = 0; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; Snapshot snapshot1 = new(gapBlock1, header.Hash!, [Address.FromNumber(1)]); _snapshotManager.StoreSnapshot(snapshot1); @@ -131,7 +131,7 @@ public void GetSnapshot_ShouldReturnSnapshotIfExists() // store another snapshot with the same hash but different data - const int gapBlock2 = 450; + const ulong gapBlock2 = 450; XdcBlockHeader header2 = Build.A.XdcBlockHeader().WithGeneratedExtraConsensusData(1).TestObject; Snapshot snapshot2 = new(gapBlock2, header2.Hash!, [Address.FromNumber(2)]); _snapshotManager.StoreSnapshot(snapshot2); @@ -143,14 +143,14 @@ public void GetSnapshot_ShouldReturnSnapshotIfExists() Assert.That(result, Is.EqualTo(snapshot2).UsingXdcProperties()); } - [TestCase(1, 0)] - [TestCase(451, 0)] - [TestCase(899, 0)] - [TestCase(900, 450)] - [TestCase(1349, 450)] - [TestCase(1350, 450)] - [TestCase(1800, 1350)] - public void GetSnapshot_DifferentBlockNumbers_ReturnsSnapshotFromCorrectGapNumber(int blockNumber, int expectedGapNumber) + [TestCase(1UL, 0UL)] + [TestCase(451UL, 0UL)] + [TestCase(899UL, 0UL)] + [TestCase(900UL, 450UL)] + [TestCase(1349UL, 450UL)] + [TestCase(1350UL, 450UL)] + [TestCase(1800UL, 1350UL)] + public void GetSnapshot_DifferentBlockNumbers_ReturnsSnapshotFromCorrectGapNumber(ulong blockNumber, ulong expectedGapNumber) { // setup a snapshot and store it XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; @@ -163,9 +163,9 @@ public void GetSnapshot_DifferentBlockNumbers_ReturnsSnapshotFromCorrectGapNumbe Assert.That(result, Is.EqualTo(snapshot).UsingXdcProperties()); } - [TestCase(450)] - [TestCase(1350)] - public void OnUpdateMainChain_ShouldStoreSnapshot(int gapNumber) + [TestCase(450UL)] + [TestCase(1350UL)] + public void OnUpdateMainChain_ShouldStoreSnapshot(ulong gapNumber) { IBlockTree blockTree = Substitute.For(); ISpecProvider specProvider = Substitute.For(); @@ -175,7 +175,7 @@ public void OnUpdateMainChain_ShouldStoreSnapshot(int gapNumber) XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) .WithNumber(gapNumber).TestObject; - blockTree.FindHeader(Arg.Any()).Returns(header); + blockTree.FindHeader(Arg.Any()).Returns(header); blockTree.OnUpdateMainChain += Raise.EventWith(new OnUpdateMainChainArgs([new Block(header)], true)); Snapshot? result = snapshotManager.GetSnapshotByGapNumber(header.Number); @@ -188,12 +188,12 @@ public void TryRecoverSnapshot_ReturnsSnapshot_WhenStateAndProcessingAvailable() { XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) - .WithNumber(450).TestObject; - _blockTree.FindHeader(450).Returns(header); + .WithNumber(450UL).TestObject; + _blockTree.FindHeader(450UL).Returns(header); _stateReader.HasStateForBlock(header).Returns(true); - _blockTree.WasProcessed(450, header.Hash!).Returns(true); + _blockTree.WasProcessed(450UL, header.Hash!).Returns(true); - Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450); + Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450UL); Assert.That(result, Is.Not.Null); Assert.That(result!.HeaderHash, Is.EqualTo(header.Hash!)); @@ -204,12 +204,12 @@ public void TryRecoverSnapshot_ReturnsNull_WhenStateUnavailable() { XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) - .WithNumber(450).TestObject; - _blockTree.FindHeader(450).Returns(header); - _blockTree.WasProcessed(450, header.Hash!).Returns(true); + .WithNumber(450UL).TestObject; + _blockTree.FindHeader(450UL).Returns(header); + _blockTree.WasProcessed(450UL, header.Hash!).Returns(true); _stateReader.HasStateForBlock(header).Returns(false); - Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450); + Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450UL); Assert.That(result, Is.Null); } @@ -219,12 +219,12 @@ public void TryRecoverSnapshot_ReturnsNull_WhenBlockNotProcessed() { XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) - .WithNumber(450).TestObject; - _blockTree.FindHeader(450).Returns(header); + .WithNumber(450UL).TestObject; + _blockTree.FindHeader(450UL).Returns(header); _stateReader.HasStateForBlock(header).Returns(true); - _blockTree.WasProcessed(450, header.Hash!).Returns(false); + _blockTree.WasProcessed(450UL, header.Hash!).Returns(false); - Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450); + Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(450UL); Assert.That(result, Is.Null); } @@ -234,13 +234,13 @@ public void TryRecoverSnapshot_Throws_WhenCreateSnapshotThrows() { XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) - .WithNumber(450).TestObject; - _blockTree.FindHeader(450).Returns(header); + .WithNumber(450UL).TestObject; + _blockTree.FindHeader(450UL).Returns(header); _stateReader.HasStateForBlock(header).Returns(true); - _blockTree.WasProcessed(450, header.Hash!).Returns(true); + _blockTree.WasProcessed(450UL, header.Hash!).Returns(true); _votingContract.GetCandidatesByStake(header).Throws(new Exception("contract failure")); - Assert.Throws(() => _snapshotManager.GetSnapshotByGapNumber(450)); + Assert.Throws(() => _snapshotManager.GetSnapshotByGapNumber(450UL)); } [Test] @@ -249,10 +249,10 @@ public void TryRecoverSnapshot_ReturnsNull_WhenNotSnapshotBlock() // Block 100 is not a snapshot block (100 % 900 != 450) XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) - .WithNumber(100).TestObject; - _blockTree.FindHeader(100).Returns(header); + .WithNumber(100UL).TestObject; + _blockTree.FindHeader(100UL).Returns(header); - Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(100); + Snapshot? result = _snapshotManager.GetSnapshotByGapNumber(100UL); Assert.That(result, Is.Null); _stateReader.DidNotReceiveWithAnyArgs().HasStateForBlock(default); diff --git a/src/Nethermind/Nethermind.Xdc.Test/SpecialTransactionsTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SpecialTransactionsTests.cs index fcb23cce804d..d44cdbeb8d6d 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SpecialTransactionsTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SpecialTransactionsTests.cs @@ -33,7 +33,7 @@ namespace Nethermind.Xdc.Test; internal class SpecialTransactionsTests { - private bool IsTimeForOnchainSignature(IXdcReleaseSpec spec, long blockNumber) => + private bool IsTimeForOnchainSignature(IXdcReleaseSpec spec, ulong blockNumber) => blockNumber % spec.MergeSignRange == 0; private Task ProposeBatchTransferTxFrom(PrivateKey source, PrivateKey destination, UInt256 amount, int count, XdcTestBlockchain chain) => @@ -50,7 +50,7 @@ private Task ProposeBatchTransferTxFrom(PrivateKey source, PrivateKey destinatio private Transaction CreateTransferTxFrom(PrivateKey source, PrivateKey destination, UInt256 amount, XdcTestBlockchain chain) { - UInt256 nonce = chain.TxPool.GetLatestPendingNonce(source.Address); + ulong nonce = chain.TxPool.GetLatestPendingNonce(source.Address); Transaction tx = Build.A.Transaction .WithSenderAddress(source.Address) @@ -85,7 +85,7 @@ public async Task SignTx_Is_Dispatched_On_MergeSignRange_Block(bool enableEip155 { XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(1, true); - int mergeSignBlockRange = 5; + ulong mergeSignBlockRange = 5; blockChain.ChangeReleaseSpec((spec) => { @@ -117,7 +117,7 @@ public async Task SignTx_Is_Dispatched_On_MergeSignRange_Block(bool enableEip155 Transaction specialTx = signTxs.First(); - long blockTarget = (long)(new UInt256(specialTx.Data.Span.Slice(4, 32), true)); + ulong blockTarget = (ulong)(new UInt256(specialTx.Data.Span.Slice(4, 32), true)); Assert.That(blockTarget, Is.EqualTo(mergeSignBlockRange)); } @@ -128,7 +128,7 @@ public async Task SignTx_Is_Not_Dispatched_Outside_MergeSignRange_Block(bool ena { XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(1, true); - int mergeSignBlockRange = 5; + ulong mergeSignBlockRange = 5; blockChain.ChangeReleaseSpec((spec) => { @@ -159,7 +159,7 @@ public async Task Special_Tx_Is_Executed_Before_Normal_Txs(bool enableEip1559) { XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(1, true); - int mergeSignBlockRange = 5; + ulong mergeSignBlockRange = 5; blockChain.ChangeReleaseSpec((spec) => { @@ -176,7 +176,7 @@ public async Task Special_Tx_Is_Executed_Before_Normal_Txs(bool enableEip1559) PrivateKey[] accounts = FilledAccounts(blockChain); - for (int i = 1; i < spec.MergeSignRange + 2; i++) + for (ulong i = 1; i < spec.MergeSignRange + 2; i++) { if (head!.Number == mergeSignBlockRange + 1) { @@ -304,7 +304,7 @@ public async Task Tx_With_With_BlackListed_Receiver_Fails_Validation(bool blackL moqVm.SetBlockExecutionContext(new BlockExecutionContext(head, spec)); - UInt256 nonce = blockChain.ReadOnlyState.GetNonce(blockChain.Signer.Address); + ulong nonce = blockChain.ReadOnlyState.GetNonce(blockChain.Signer.Address); Transaction tx = Build.A.Transaction .WithNonce(nonce) @@ -398,7 +398,7 @@ public async Task Malformed_SenderNonceLesserThanTxNonce_SignTx_Fails_Validation blockChain.MainWorldState.IncrementNonce(blockChain.Signer.Address); - UInt256 nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); + ulong nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); Transaction txWithSmallerNonce = SignTransactionManager.CreateTxSign((UInt256)head.Number, head.Hash!, nonce - 1, spec.BlockSignerContract, blockChain.Signer.Address); @@ -455,7 +455,7 @@ public async Task Malformed_SenderNonceBiggerLesserThanTxNonce_SignTx_Fails_Vali blockChain.MainWorldState.IncrementNonce(blockChain.Signer.Address); - UInt256 nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); + ulong nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); Transaction txWithBiggerNonce = SignTransactionManager.CreateTxSign((UInt256)head.Number, head.Hash!, nonce + 1, spec.BlockSignerContract, blockChain.Signer.Address); @@ -513,7 +513,7 @@ public async Task Malformed_SenderNonceEqualLesserThanTxNonce_SignTx_Fails_Valid blockChain.MainWorldState.IncrementNonce(blockChain.Signer.Address); - UInt256 nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); + ulong nonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); Transaction validNonceTx = SignTransactionManager.CreateTxSign((UInt256)head.Number, head.Hash!, nonce, spec.BlockSignerContract, blockChain.Signer.Address); @@ -542,8 +542,8 @@ public async Task Malformed_SenderNonceEqualLesserThanTxNonce_SignTx_Fails_Valid [TestCase(false)] public async Task Malformed_WrongBlockNumber_BlockTooHigh_SignTx_Fails_Validation(bool enableEip1559) { - int epochLength = 10; - XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(epochLength * 3, false); + ulong epochLength = 10; + XdcTestBlockchain blockChain = await XdcTestBlockchain.Create((int)epochLength * 3, false); blockChain.ChangeReleaseSpec((spec) => { spec.IsEip1559Enabled = enableEip1559; @@ -575,8 +575,8 @@ public async Task Malformed_WrongBlockNumber_BlockTooHigh_SignTx_Fails_Validatio [TestCase(false)] public async Task Malformed_WrongBlockNumber_BlockTooLow_SignTx_Fails_Validation(bool enableEip1559) { - int epochLength = 10; - XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(epochLength * 3, false); + ulong epochLength = 10; + XdcTestBlockchain blockChain = await XdcTestBlockchain.Create((int)epochLength * 3, false); blockChain.ChangeReleaseSpec((spec) => { spec.IsEip1559Enabled = enableEip1559; @@ -588,8 +588,8 @@ public async Task Malformed_WrongBlockNumber_BlockTooLow_SignTx_Fails_Validation blockChain.MainWorldState.BeginScope(head); - long lowerBound = head.Number - (spec.EpochLength * 2); - UInt256 tooLowBlockNumber = (UInt256)lowerBound; + ulong lowerBound = head.Number > spec.EpochLength * 2 ? head.Number - (spec.EpochLength * 2) : 0UL; + UInt256 tooLowBlockNumber = lowerBound; Transaction txTooLow = SignTransactionManager.CreateTxSign( tooLowBlockNumber, head.Hash!, @@ -609,8 +609,8 @@ public async Task Malformed_WrongBlockNumber_BlockTooLow_SignTx_Fails_Validation [TestCase(true)] public async Task Malformed_WrongBlockNumber_BlockWithinRange_SignTx_Fails_Validation(bool enableEip1559) { - int epochLength = 10; - XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(epochLength * 3, false); + ulong epochLength = 10; + XdcTestBlockchain blockChain = await XdcTestBlockchain.Create((int)epochLength * 3, false); blockChain.ChangeReleaseSpec((spec) => { spec.IsEip1559Enabled = enableEip1559; @@ -625,9 +625,9 @@ public async Task Malformed_WrongBlockNumber_BlockWithinRange_SignTx_Fails_Valid // blkNumber > header.Number - (EpochLength * 2) // // Pick something comfortably in the middle of that interval. - long upper = head.Number - 1; - long lower = head.Number - (spec.EpochLength * 2) + 1; - long validBlockNumber = lower + (upper - lower) / 2; + ulong upper = head.Number - 1; + ulong lower = head.Number > spec.EpochLength * 2 ? head.Number - (spec.EpochLength * 2) + 1 : 1UL; + ulong validBlockNumber = lower + (upper - lower) / 2; Transaction tx = SignTransactionManager.CreateTxSign( @@ -649,8 +649,8 @@ public async Task Malformed_WrongBlockNumber_BlockWithinRange_SignTx_Fails_Valid [TestCase(true)] public async Task SignTx_From_NonEpochCandidate_Fails_Validation(bool enableEip1559) { - int epochLength = 10; - XdcTestBlockchain blockChain = await XdcTestBlockchain.Create(epochLength * 3, false); + ulong epochLength = 10; + XdcTestBlockchain blockChain = await XdcTestBlockchain.Create((int)epochLength * 3, false); blockChain.ChangeReleaseSpec((spec) => { spec.IsEip1559Enabled = enableEip1559; @@ -716,7 +716,7 @@ public async Task SignTx_Increments_Nonce_And_Emits_Log_And_Consume_NoGas(bool e moqVm.SetBlockExecutionContext(new BlockExecutionContext(head.Header, spec)); - UInt256 initialNonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); + ulong initialNonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); UInt256 initialBalance = blockChain.MainWorldState.GetBalance(blockChain.Signer.Address); Transaction? tx = SignTransactionManager.CreateTxSign((UInt256)head.Number - 1, head.ParentHash!, initialNonce, spec.BlockSignerContract, blockChain.Signer.Address); @@ -739,7 +739,7 @@ public async Task SignTx_Increments_Nonce_And_Emits_Log_And_Consume_NoGas(bool e receiptsTracer.EndTxTrace(); receiptsTracer.EndBlockTrace(); - UInt256 finalNonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); + ulong finalNonce = blockChain.MainWorldState.GetNonce(blockChain.Signer.Address); UInt256 finalBalance = blockChain.MainWorldState.GetBalance(blockChain.Signer.Address); Assert.That(finalNonce, Is.EqualTo(initialNonce + 1)); @@ -860,7 +860,7 @@ public async Task SignTx_With_ZeroBalance_CanBeIncludedInBlock_And_ReceiptIsEmit XdcBlockHeader head = (XdcBlockHeader)chain.BlockTree.Head!.Header; IXdcReleaseSpec spec = chain.SpecProvider.GetXdcSpec(head, chain.XdcContext.CurrentRound); - int epochLength = spec.EpochLength; + int epochLength = (int)spec.EpochLength; // Add blocks up to epochLength (E) + 15 and create a signing tx that will be inserted in the next block await chain.AddBlocks(epochLength + 15 - 3); diff --git a/src/Nethermind/Nethermind.Xdc.Test/SubnetEpochSwitchManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SubnetEpochSwitchManagerTests.cs index cc63fcde720f..138141dd2edd 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SubnetEpochSwitchManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SubnetEpochSwitchManagerTests.cs @@ -29,9 +29,9 @@ public void Setup() _epochSwitchManager = new SubnetEpochSwitchManager(_config, _tree, _snapshotManager); } - [TestCase(20L, 10, true)] - [TestCase(5L, 10, false)] - public void IsEpochSwitchAtBlock_BlockNumberBased(long blockNumber, int epochLength, bool expected) + [TestCase(20UL, 10UL, true)] + [TestCase(5UL, 10UL, false)] + public void IsEpochSwitchAtBlock_BlockNumberBased(ulong blockNumber, ulong epochLength, bool expected) { XdcReleaseSpec releaseSpec = new() { @@ -47,9 +47,9 @@ public void IsEpochSwitchAtBlock_BlockNumberBased(long blockNumber, int epochLen Assert.That(_epochSwitchManager.IsEpochSwitchAtBlock(header), Is.EqualTo(expected)); } - [TestCase(9L, 10, true)] // parent.Number + 1 = 10, 10 % 10 == 0 - [TestCase(5L, 10, false)] // parent.Number + 1 = 6 - public void IsEpochSwitchAtRound_DerivedFromParentBlockNumber(long parentNumber, int epochLength, bool expected) + [TestCase(9UL, 10UL, true)] // parent.Number + 1 = 10, 10 % 10 == 0 + [TestCase(5UL, 10UL, false)] // parent.Number + 1 = 6 + public void IsEpochSwitchAtRound_DerivedFromParentBlockNumber(ulong parentNumber, ulong epochLength, bool expected) { XdcReleaseSpec releaseSpec = new() { diff --git a/src/Nethermind/Nethermind.Xdc.Test/SubnetMasternodesCalculatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SubnetMasternodesCalculatorTests.cs index bc7878e3ba65..9e59b72ae5b1 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SubnetMasternodesCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SubnetMasternodesCalculatorTests.cs @@ -28,7 +28,7 @@ public void CalculateNextEpochMasternodes_FiltersPenaltiesAndRespectsMaxMasterno SubnetSnapshot snapshot = new(0, Hash256.Zero, [a1, a2, a3, a4, a5, a6], [a1, a2]); ISubnetSnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetSnapshotByBlockNumber(Arg.Any(), Arg.Any()).Returns(snapshot); + snapshotManager.GetSnapshotByBlockNumber(Arg.Any(), Arg.Any()).Returns(snapshot); SubnetMasternodesCalculator calculator = new(snapshotManager); diff --git a/src/Nethermind/Nethermind.Xdc.Test/SubnetSnapshotManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/SubnetSnapshotManagerTests.cs index ba236de3af54..da0d9037da43 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/SubnetSnapshotManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/SubnetSnapshotManagerTests.cs @@ -31,8 +31,8 @@ internal class SubnetSnapshotManagerTests public void Setup() { _xdcReleaseSpec = Substitute.For(); - _xdcReleaseSpec.EpochLength.Returns(900); - _xdcReleaseSpec.Gap.Returns(450); + _xdcReleaseSpec.EpochLength.Returns(900UL); + _xdcReleaseSpec.Gap.Returns(450UL); _snapshotDb = new MemDb(); @@ -57,7 +57,7 @@ public void GetSnapshot_ShouldReturnNullForNonExistentSnapshot() public void GetSnapshot_ShouldRetrieveFromIfFound() { // Arrange - const int gapBlock = 0; + const ulong gapBlock = 0UL; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; SubnetSnapshot snapshot = new(gapBlock, header.Hash!, [Address.FromNumber(1)], [Address.FromNumber(2)]); _snapshotManager.StoreSnapshot(snapshot); @@ -73,7 +73,7 @@ public void GetSnapshot_ShouldRetrieveFromIfFound() public void StoreSnapshot_ShouldRaiseExceptionIfTypeIsWrong() { // Act - const int gapBlock = 0; + const ulong gapBlock = 0UL; XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; Snapshot snapshot = new(gapBlock, header.Hash!, [Address.FromNumber(1)]); @@ -81,27 +81,27 @@ public void StoreSnapshot_ShouldRaiseExceptionIfTypeIsWrong() Assert.Throws(() => _snapshotManager.StoreSnapshot(snapshot)); } - [TestCase(450)] - [TestCase(1350)] - public void OnUpdateMainChain_StoresSnapshot(int gapNumber) + [TestCase(450UL)] + [TestCase(1350UL)] + public void OnUpdateMainChain_StoresSnapshot(ulong gapNumber) { IXdcReleaseSpec releaseSpec = Substitute.For(); - releaseSpec.EpochLength.Returns(900); - releaseSpec.Gap.Returns(450); + releaseSpec.EpochLength.Returns(900UL); + releaseSpec.Gap.Returns(450UL); IBlockTree blockTree = Substitute.For(); ISpecProvider specProvider = Substitute.For(); specProvider.GetSpec(Arg.Any()).Returns(releaseSpec); Address[] penalties = [Address.FromNumber(1), Address.FromNumber(2)]; IPenaltyHandler penaltyHandler = Substitute.For(); - penaltyHandler.HandlePenalties(Arg.Any(), Arg.Any(), Arg.Any()).Returns(penalties); + penaltyHandler.HandlePenalties(Arg.Any(), Arg.Any(), Arg.Any()).Returns(penalties); SubnetSnapshotManager snapshotManager = new(new MemDb(), blockTree, Substitute.For(), specProvider, Substitute.For(), LimboLogs.Instance, penaltyHandler); XdcBlockHeader header = Build.A.XdcBlockHeader() .WithGeneratedExtraConsensusData(1) .WithNumber(gapNumber).TestObject; - blockTree.FindHeader(Arg.Any()).Returns(header); + blockTree.FindHeader(Arg.Any()).Returns(header); blockTree.OnUpdateMainChain += Raise.EventWith(new OnUpdateMainChainArgs([new Block(header)], true)); Snapshot? result = snapshotManager.GetSnapshotByGapNumber(gapNumber); diff --git a/src/Nethermind/Nethermind.Xdc.Test/TimeoutCertificateManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/TimeoutCertificateManagerTests.cs index 4a90bbd96f34..f48942900455 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/TimeoutCertificateManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/TimeoutCertificateManagerTests.cs @@ -45,7 +45,7 @@ public void VerifyTC_SnapshotMissing_ReturnsFalse() { TimeoutCertificate tc = new(1, Array.Empty(), 0); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetSnapshotByGapNumber(Arg.Any()) + snapshotManager.GetSnapshotByGapNumber(Arg.Any()) .Returns((Snapshot?)null); IBlockTree blockTree = Substitute.For(); XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; @@ -74,7 +74,7 @@ public void VerifyTC_EmptyCandidates_ReturnsFalse() { TimeoutCertificate tc = new(1, Array.Empty(), 0); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetSnapshotByGapNumber(Arg.Any()) + snapshotManager.GetSnapshotByGapNumber(Arg.Any()) .Returns(new Snapshot(0, Hash256.Zero, Array.Empty
())); IBlockTree blockTree = Substitute.For(); XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; @@ -142,7 +142,7 @@ public void VerifyTCWithDifferentParameters_ReturnsExpected(TimeoutCertificate t { Address[] masternodes = masternodesList.ToArray(); ISnapshotManager snapshotManager = Substitute.For(); - snapshotManager.GetSnapshotByGapNumber(Arg.Any()) + snapshotManager.GetSnapshotByGapNumber(Arg.Any()) .Returns(new Snapshot(0, Hash256.Zero, masternodes)); IEpochSwitchManager epochSwitchManager = Substitute.For(); @@ -157,15 +157,15 @@ public void VerifyTCWithDifferentParameters_ReturnsExpected(TimeoutCertificate t ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.EpochLength.Returns(900); - xdcReleaseSpec.SwitchEpoch.Returns(89300); + xdcReleaseSpec.EpochLength.Returns(900UL); + xdcReleaseSpec.SwitchEpoch.Returns(89300UL); xdcReleaseSpec.CertificateThreshold.Returns(0.667); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); IBlockTree blockTree = Substitute.For(); XdcBlockHeader header = Build.A.XdcBlockHeader().TestObject; blockTree.Head.Returns(new Block(header, new BlockBody())); - blockTree.FindHeader(Arg.Any()).Returns(header); + blockTree.FindHeader(Arg.Any()).Returns(header); XdcConsensusContext context = new(); ISigner signer = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProcessorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProcessorTests.cs index c91814891998..204699c204d0 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProcessorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProcessorTests.cs @@ -32,15 +32,15 @@ public void SetUp() => _processor = new TestableXdcBlockProcessor(); [ - TestCase(0L, "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), - TestCase(1L, "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2"), - TestCase(2L, "0xf2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2"), - TestCase(100L, "0xf1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3"), - TestCase(10_000_000L, "0xcb2bea23225e166d181633a5500bb13f45947baf4699fe7d7be7709662ed2cd4"), - TestCase(50_000_000L, "0xcfa4f717b73afc03b1397871f456c85553ea93c536860d57572d2f2b6947e962"), - TestCase(999_999_999L, "0xecfe0cf238d62038a8de7039c5c1700a26581c9c3c61e6352085728207948d1f"), + TestCase(0UL, "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), + TestCase(1UL, "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2"), + TestCase(2UL, "0xf2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2"), + TestCase(100UL, "0xf1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3"), + TestCase(10_000_000UL, "0xcb2bea23225e166d181633a5500bb13f45947baf4699fe7d7be7709662ed2cd4"), + TestCase(50_000_000UL, "0xcfa4f717b73afc03b1397871f456c85553ea93c536860d57572d2f2b6947e962"), + TestCase(999_999_999UL, "0xecfe0cf238d62038a8de7039c5c1700a26581c9c3c61e6352085728207948d1f"), ] - public void CreateBlockExecutionContext_PrevRandao_MatchesGoXdcRandomValue(long blockNumber, string expectedPrevRandaoHex) + public void CreateBlockExecutionContext_PrevRandao_MatchesGoXdcRandomValue(ulong blockNumber, string expectedPrevRandaoHex) { BlockHeader header = Build.A.BlockHeader.WithNumber(blockNumber).TestObject; IReleaseSpec spec = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs index e7d82839119b..1b6cf8d6328a 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs @@ -32,8 +32,8 @@ public async Task BuildBlock_HasCorrectQC_ProducesValidHeader() ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); xdcReleaseSpec.MinePeriod.Returns(2); - xdcReleaseSpec.EpochLength.Returns(900); - xdcReleaseSpec.GasLimitBoundDivisor.Returns(1); + xdcReleaseSpec.EpochLength.Returns(900UL); + xdcReleaseSpec.GasLimitBoundDivisor.Returns(1UL); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); IEpochSwitchManager epochManager = Substitute.For(); IWorldState stateProvider = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockTreeTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockTreeTests.cs index a10ea4c82e85..d5c2910118ae 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockTreeTests.cs @@ -22,9 +22,9 @@ public void Suggest_BlockBelowFinalizedHeight_WhenKnown_ReturnsAlreadyKnown() { (XdcBlockTree blockTree, IXdcConsensusContext consensus) = BuildBlockTree(); - Block genesis = XdcBlock(0, Keccak.Zero); - Block block1 = XdcBlock(1, genesis.Hash!); - Block block2 = XdcBlock(2, block1.Hash!); + Block genesis = XdcBlock(0UL, Keccak.Zero); + Block block1 = XdcBlock(1UL, genesis.Hash!); + Block block2 = XdcBlock(2UL, block1.Hash!); blockTree.SuggestBlock(genesis); blockTree.SuggestBlock(block1); @@ -41,9 +41,9 @@ public void Suggest_BlockBelowFinalizedHeight_WhenUnknown_ReturnsInvalidBlock() { (XdcBlockTree blockTree, IXdcConsensusContext consensus) = BuildBlockTree(); - Block genesis = XdcBlock(0, Keccak.Zero); - Block block1 = XdcBlock(1, genesis.Hash!); - Block block2 = XdcBlock(2, block1.Hash!); + Block genesis = XdcBlock(0UL, Keccak.Zero); + Block block1 = XdcBlock(1UL, genesis.Hash!); + Block block2 = XdcBlock(2UL, block1.Hash!); blockTree.SuggestBlock(genesis); blockTree.SuggestBlock(block1); @@ -52,7 +52,7 @@ public void Suggest_BlockBelowFinalizedHeight_WhenUnknown_ReturnsInvalidBlock() consensus.HighestCommitBlock.Returns(new BlockRoundInfo(block2.Hash!, 1, block2.Number)); - Block unknown = XdcBlock(1, genesis.Hash!, nonce: 1); + Block unknown = XdcBlock(1UL, genesis.Hash!, nonce: 1UL); Assert.That(blockTree.SuggestBlock(unknown), Is.EqualTo(AddBlockResult.InvalidBlock)); } @@ -61,10 +61,10 @@ public void Suggest_BlockAboveFinalizedHeight_ConnectedToFinalizedChain_ReturnsA { (XdcBlockTree blockTree, IXdcConsensusContext consensus) = BuildBlockTree(); - Block genesis = XdcBlock(0, Keccak.Zero); - Block block1 = XdcBlock(1, genesis.Hash!); - Block block2 = XdcBlock(2, block1.Hash!); - Block block3 = XdcBlock(3, block2.Hash!); + Block genesis = XdcBlock(0UL, Keccak.Zero); + Block block1 = XdcBlock(1UL, genesis.Hash!); + Block block2 = XdcBlock(2UL, block1.Hash!); + Block block3 = XdcBlock(3UL, block2.Hash!); blockTree.SuggestBlock(genesis); blockTree.SuggestBlock(block1); @@ -74,7 +74,7 @@ public void Suggest_BlockAboveFinalizedHeight_ConnectedToFinalizedChain_ReturnsA consensus.HighestCommitBlock.Returns(new BlockRoundInfo(block2.Hash!, 1, block2.Number)); - Block block3Alt = XdcBlock(3, block2.Hash!, nonce: 1); + Block block3Alt = XdcBlock(3UL, block2.Hash!, nonce: 1UL); Assert.That(blockTree.SuggestBlock(block3Alt), Is.EqualTo(AddBlockResult.Added)); } @@ -83,14 +83,14 @@ public void Suggest_BlockAboveFinalizedHeight_ForkBeforeFinalized_ReturnsInvalid { (XdcBlockTree blockTree, IXdcConsensusContext consensus) = BuildBlockTree(); - Block genesis = XdcBlock(0, Keccak.Zero); - Block block1 = XdcBlock(1, genesis.Hash!); - Block block2 = XdcBlock(2, block1.Hash!); - Block block3 = XdcBlock(3, block2.Hash!); + Block genesis = XdcBlock(0UL, Keccak.Zero); + Block block1 = XdcBlock(1UL, genesis.Hash!); + Block block2 = XdcBlock(2UL, block1.Hash!); + Block block3 = XdcBlock(3UL, block2.Hash!); // block2Fork forks at height 2 — same height as the finalized block - Block block2Fork = XdcBlock(2, block1.Hash!, nonce: 1); - Block block3Fork = XdcBlock(3, block2Fork.Hash!); + Block block2Fork = XdcBlock(2UL, block1.Hash!, nonce: 1UL); + Block block3Fork = XdcBlock(3UL, block2Fork.Hash!); blockTree.SuggestBlock(genesis); blockTree.SuggestBlock(block1); @@ -109,19 +109,19 @@ public void Suggest_BlockAboveFinalizedHeight_UnknownParent_ReturnsUnknownParent { (XdcBlockTree blockTree, IXdcConsensusContext consensus) = BuildBlockTree(); - Block genesis = XdcBlock(0, Keccak.Zero); - Block block1 = XdcBlock(1, genesis.Hash!); + Block genesis = XdcBlock(0UL, Keccak.Zero); + Block block1 = XdcBlock(1UL, genesis.Hash!); blockTree.SuggestBlock(genesis); blockTree.SuggestBlock(block1); blockTree.UpdateHeadBlock(block1.Hash!); consensus.HighestCommitBlock.Returns(new BlockRoundInfo(block1.Hash!, 1, block1.Number)); - Block disconnected = XdcBlock(2, Keccak.Compute("other")); + Block disconnected = XdcBlock(2UL, Keccak.Compute("other")); Assert.That(blockTree.SuggestBlock(disconnected), Is.EqualTo(AddBlockResult.UnknownParent)); } - private static Block XdcBlock(long number, Hash256 parentHash, ulong nonce = 0) + private static Block XdcBlock(ulong number, Hash256 parentHash, ulong nonce = 0) { XdcBlockHeader header = Build.A.XdcBlockHeader() .WithNumber(number) diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs index 6006220d750a..1e8ab52ea475 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs @@ -18,20 +18,20 @@ public class XdcGasLimitCalculatorTests public void GetGasLimit_WhenDynamicGasLimitNotEnabled_ReturnsTargetBlockGasLimit() { // Arrange - const long targetGasLimit = 10_000_000L; + const ulong targetGasLimit = 10_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1000); + BlockHeader parentHeader = CreateParentHeader(1000UL); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: false); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); // Assert Assert.That(result, Is.EqualTo(targetGasLimit)); @@ -46,13 +46,13 @@ public void GetGasLimit_WhenDynamicGasLimitNotEnabledAndTargetBlockGasLimitIsNul blocksConfig.TargetBlockGasLimit.Returns((long?)null); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1000); + BlockHeader parentHeader = CreateParentHeader(1000UL); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: false); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); // Assert Assert.That(result, Is.EqualTo(XdcConstants.DefaultTargetGasLimit)); @@ -62,21 +62,21 @@ public void GetGasLimit_WhenDynamicGasLimitNotEnabledAndTargetBlockGasLimitIsNul public void GetGasLimit_WhenDynamicGasLimitEnabled_UsesTargetAdjustedCalculator() { // Arrange - const long parentGasLimit = 84_000_000L; - const long targetGasLimit = 100_000_000L; + const ulong parentGasLimit = 84_000_000UL; + const ulong targetGasLimit = 100_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1000, parentGasLimit); + BlockHeader parentHeader = CreateParentHeader(1000UL, parentGasLimit); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: true); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); // Assert // The TargetAdjustedGasLimitCalculator will adjust the gas limit toward the target @@ -90,21 +90,21 @@ public void GetGasLimit_WhenDynamicGasLimitEnabled_UsesTargetAdjustedCalculator( public void GetGasLimit_WhenDynamicGasLimitEnabled_GasLimitAdjustsTowardTarget() { // Arrange - const long parentGasLimit = 50_000_000L; - const long targetGasLimit = 84_000_000L; + const ulong parentGasLimit = 50_000_000UL; + const ulong targetGasLimit = 84_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1000, parentGasLimit); + BlockHeader parentHeader = CreateParentHeader(1000UL, parentGasLimit); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: true); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); // Assert // Should increase toward target @@ -117,21 +117,21 @@ public void GetGasLimit_WhenDynamicGasLimitEnabled_GasLimitAdjustsTowardTarget() public void GetGasLimit_AtDynamicGasLimitBlockBoundary_TransitionsToTargetAdjusted(bool dynamicBlockActive) { // Arrange - const long targetGasLimit = 100_000_000L; + const ulong targetGasLimit = 100_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1); + BlockHeader parentHeader = CreateParentHeader(1UL); IXdcReleaseSpec spec = CreateXdcSpec(isDynamicGasLimitBlock: dynamicBlockActive); specProvider.GetSpec(Arg.Any()).Returns(spec); - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); if (dynamicBlockActive) { - Assert.That(result, Is.InRange(parentHeader.GasLimit - 100000, parentHeader.GasLimit + 100000)); + Assert.That(result, Is.InRange(parentHeader.GasLimit - 100000UL, parentHeader.GasLimit + 100000UL)); } else { @@ -143,51 +143,51 @@ public void GetGasLimit_AtDynamicGasLimitBlockBoundary_TransitionsToTargetAdjust public void GetGasLimit_WhenParentGasLimitEqualsTarget_DynamicModeReturnsNearTarget() { // Arrange - const long targetGasLimit = 84_000_000L; + const ulong targetGasLimit = 84_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader parentHeader = CreateParentHeader(1000, targetGasLimit); + BlockHeader parentHeader = CreateParentHeader(1000UL, targetGasLimit); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: true); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(parentHeader); + ulong result = calculator.GetGasLimit(parentHeader); // Assert // When at target, should return close to target - Assert.That(result, Is.GreaterThanOrEqualTo(targetGasLimit - 100_000)); - Assert.That(result, Is.LessThanOrEqualTo(targetGasLimit + 100_000)); + Assert.That(result, Is.GreaterThanOrEqualTo(targetGasLimit - 100_000UL)); + Assert.That(result, Is.LessThanOrEqualTo(targetGasLimit + 100_000UL)); } [Test] public void GetGasLimit_WithGenesisBlock_HandlesCorrectly() { // Arrange - const long targetGasLimit = 84_000_000L; + const ulong targetGasLimit = 84_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); - BlockHeader genesisHeader = CreateParentHeader(0, 5_000_000L); + BlockHeader genesisHeader = CreateParentHeader(0UL, 5_000_000UL); IXdcReleaseSpec xdcSpec = CreateXdcSpec(isDynamicGasLimitBlock: false); specProvider.GetSpec(Arg.Any()).Returns(xdcSpec); // Act - long result = calculator.GetGasLimit(genesisHeader); + ulong result = calculator.GetGasLimit(genesisHeader); // Assert Assert.That(result, Is.EqualTo(targetGasLimit)); } - private static BlockHeader CreateParentHeader(long number, long gasLimit = 84_000_000L) => + private static BlockHeader CreateParentHeader(ulong number, ulong gasLimit = 84_000_000UL) => Build.A.BlockHeader .WithNumber(number) .WithGasLimit(gasLimit) @@ -198,9 +198,9 @@ private static IXdcReleaseSpec CreateXdcSpec(bool isDynamicGasLimitBlock) { IXdcReleaseSpec spec = Substitute.For(); spec.IsDynamicGasLimitBlock.Returns(isDynamicGasLimitBlock); - spec.Eip1559TransitionBlock.Returns(long.MaxValue); // Not relevant for these tests + spec.Eip1559TransitionBlock.Returns(ulong.MaxValue); // Not relevant for these tests spec.IsEip1559Enabled.Returns(false); - spec.GasLimitBoundDivisor.Returns(1024); + spec.GasLimitBoundDivisor.Returns(1024UL); return spec; } } diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcHeaderValidatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcHeaderValidatorTests.cs index 37979e4c7662..5dffb8537053 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcHeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcHeaderValidatorTests.cs @@ -92,7 +92,7 @@ public void Validate_HeaderWithDifferentValues_ReturnsExpected(XdcBlockHeaderBui sealValidator.ValidateParams(Arg.Any(), Arg.Any(), Arg.Any()).Returns(true); ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec releaseSpec = Substitute.For(); - releaseSpec.GasLimitBoundDivisor.Returns(1); + releaseSpec.GasLimitBoundDivisor.Returns(1UL); specProvider.GetSpec(Arg.Any()).Returns(releaseSpec); IQuorumCertificateManager quorumCertificateManager = Substitute.For(); quorumCertificateManager.VerifyCertificate(Arg.Any(), Arg.Any(), out _).Returns(true); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcOpcodesTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcOpcodesTests.cs index 4bd68c39a229..80378724c71c 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcOpcodesTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcOpcodesTests.cs @@ -72,11 +72,11 @@ public void BlobBaseFee_opcode_returns_zero_when_enabled_and_bad_instruction_whe // In XDC, PREVRANDAO returns keccak(blockNumber) instead of the header Random field, // matching Go-XDC's big.Int.Bytes() behavior (block 0 produces empty bytes → keccak of empty). [ - TestCase(0L, "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), - TestCase(1L, "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2"), - TestCase(100L, "0xf1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3"), + TestCase(0UL, "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), + TestCase(1UL, "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2"), + TestCase(100UL, "0xf1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3"), ] - public void PrevRandao_opcode_returns_keccak_of_block_number(long blockNumber, string expectedPrevRandaoHex) + public void PrevRandao_opcode_returns_keccak_of_block_number(ulong blockNumber, string expectedPrevRandaoHex) { byte[] code = Prepare.EvmCode .Op(Instruction.PREVRANDAO) diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcPoolTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcPoolTests.cs index c92204151f77..3e9a1817a29e 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcPoolTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcPoolTests.cs @@ -15,7 +15,7 @@ namespace Nethermind.Xdc.Test; public class XdcPoolTests { private static BlockRoundInfo MakeBlockInfo(ulong round = 1) => - new(Hash256.Zero, round, (long)round); + new(Hash256.Zero, round, round); private static Vote BuildVote(BlockRoundInfo info, PrivateKey key, ulong gap = 0) => XdcTestHelper.BuildSignedVote(info, gap, key); @@ -89,7 +89,7 @@ public void EndRound_RemovesItemsUpToRound() pool.Add(voteRound1); pool.Add(voteRound2); - pool.EndRound(1); + pool.EndRound(1UL); Assert.That(pool.GetCount(voteRound1), Is.EqualTo(0)); Assert.That(pool.GetCount(voteRound2), Is.EqualTo(1)); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcSealValidatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcSealValidatorTests.cs index 08956f2ef7d7..f85d52b965b8 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcSealValidatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcSealValidatorTests.cs @@ -32,7 +32,7 @@ private static bool IsEpochSwitch(XdcBlockHeader header, IXdcReleaseSpec spec) return false; } ulong parentRound = extraFields.QuorumCert.ProposedBlockInfo.Round; - ulong epochStart = extraFields.BlockRound - extraFields.BlockRound % (ulong)spec.EpochLength; + ulong epochStart = extraFields.BlockRound - extraFields.BlockRound % spec.EpochLength; return parentRound < epochStart; } @@ -222,11 +222,11 @@ public void ValidateParams_HeaderHasDifferentSealParameters_ReturnsExpected(XdcB ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec releaseSpec = Substitute.For(); - releaseSpec.EpochLength.Returns(900); + releaseSpec.EpochLength.Returns(900UL); specProvider.GetSpec(Arg.Any()).Returns(releaseSpec); IMasternodesCalculator masternodesCalculator = Substitute.For(); - masternodesCalculator.CalculateNextEpochMasternodes(Arg.Any(), Arg.Any(), Arg.Any()) + masternodesCalculator.CalculateNextEpochMasternodes(Arg.Any(), Arg.Any(), Arg.Any()) .Returns((epochCandidates.ToArray(), penalties.ToArray())); IEpochSwitchManager epochSwitchManager = Substitute.For(); epochSwitchManager.GetEpochSwitchInfo(Arg.Any()).Returns(new EpochSwitchInfo(epochCandidates.ToArray(), [], [], new BlockRoundInfo(Hash256.Zero, 0, 0))); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs index 348d967e8889..7d39da1c2b8a 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs @@ -16,22 +16,22 @@ namespace Nethermind.Xdc.Test; internal class XdcStateSyncSnapshotManagerTests { [ - TestCase(24, 10, 5, new int[] { 0, 9, 18, 23 }, new int[] { 15 }), - TestCase(25, 10, 5, new int[] { 0, 9, 18, 23 }, new int[] { 15, 25 }), - TestCase(26, 10, 5, new int[] { 0, 9, 18, 23 }, new int[] { 15, 25 }), - TestCase(26, 10, 5, new int[] { 0, 9, 18, 28 }, new int[] { 5, 15, 25 }), - TestCase(11, 10, 5, new int[] { 0, 9 }, new int[] { 5 }), - TestCase(4, 10, 5, new int[] { 0 }, new int[] { }), + TestCase(24UL, 10UL, 5UL, new int[] { 0, 9, 18, 23 }, new int[] { 15 }), + TestCase(25UL, 10UL, 5UL, new int[] { 0, 9, 18, 23 }, new int[] { 15, 25 }), + TestCase(26UL, 10UL, 5UL, new int[] { 0, 9, 18, 23 }, new int[] { 15, 25 }), + TestCase(26UL, 10UL, 5UL, new int[] { 0, 9, 18, 28 }, new int[] { 5, 15, 25 }), + TestCase(11UL, 10UL, 5UL, new int[] { 0, 9 }, new int[] { 5 }), + TestCase(4UL, 10UL, 5UL, new int[] { 0 }, new int[] { }), ] public async Task GetGapBlocks_ReturnsExpectedGapBlockNumbers( - int pivotNumber, - int epochLength, - int gap, + ulong pivotNumber, + ulong epochLength, + ulong gap, int[] epochSwitchNumbers, int[] expectedGapBlockNumbers ) { - XdcTestBlockchain xdcTestBlockchain = await XdcTestBlockchain.Create(pivotNumber); + XdcTestBlockchain xdcTestBlockchain = await XdcTestBlockchain.Create((int)pivotNumber); xdcTestBlockchain.ChangeReleaseSpec(spec => { spec.EpochLength = epochLength; @@ -64,18 +64,18 @@ int[] expectedGapBlockNumbers // gapBlockNum = Max(switchBlock - switchBlock%epochLength, epochLength) - gap // V1 branch triggers when gapBlockNum + gap == switchBlock - [TestCase(27, 10, 10, 5, new int[] { 10, 19 }, new int[] { 15, 25 })] - [TestCase(14, 10, 10, 5, new int[] { 10 }, new int[] { })] + [TestCase(27UL, 10UL, 10UL, 5UL, new int[] { 10, 19 }, new int[] { 15, 25 })] + [TestCase(14UL, 10UL, 10UL, 5UL, new int[] { 10 }, new int[] { })] public async Task GetGapBlocks_WhenGapLandsOnSwitchBlock_StoresV1Snapshot( - int pivotNumber, - int switchBlock, - int epochLength, - int gap, + ulong pivotNumber, + ulong switchBlock, + ulong epochLength, + ulong gap, int[] epochSwitchNumbers, int[] expectedGapBlockNumbers ) { - XdcTestBlockchain xdcTestBlockchain = await XdcTestBlockchain.Create(pivotNumber); + XdcTestBlockchain xdcTestBlockchain = await XdcTestBlockchain.Create((int)pivotNumber); xdcTestBlockchain.ChangeReleaseSpec(spec => { spec.EpochLength = epochLength; @@ -107,7 +107,7 @@ int[] expectedGapBlockNumbers int[] resultNumbers = result.Select(r => (int)r.Number).ToArray(); Assert.That(resultNumbers, Is.EqualTo(expectedGapBlockNumbers)); - snapshotManager.Received(1).StoreSnapshot(Arg.Is(s => + snapshotManager.Received(1).StoreSnapshot(Arg.Is(s => s.BlockNumber == switchBlock - gap && s.NextEpochCandidates.SequenceEqual(masternodeAddresses))); } diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncTest.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncTest.cs index 226c7686a83c..0ec5a748d902 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncTest.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncTest.cs @@ -35,7 +35,7 @@ public async Task RunStateSyncRounds_WithMultiTargetPivot_SyncsAllTargetsBeforeF remote.StateTree.Commit(); gapBlocks[i] = new XdcBlockHeaderBuilder() - .WithNumber((i + 1) * 25) + .WithNumber((ulong)(i + 1) * 25) .WithStateRoot(remote.StateTree.RootHash) .TestObject; } @@ -46,7 +46,7 @@ public async Task RunStateSyncRounds_WithMultiTargetPivot_SyncsAllTargetsBeforeF remote.StateTree.Commit(); XdcBlockHeader xdcFinalPivot = new XdcBlockHeaderBuilder() - .WithNumber((gapBlockCount + 1) * 25) + .WithNumber((ulong)(gapBlockCount + 1) * 25) .WithStateRoot(remote.StateTree.RootHash) .TestObject; diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs index 2be91694a7ae..0d85be06e501 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs @@ -16,8 +16,8 @@ namespace Nethermind.Xdc.Test; [Parallelizable(ParallelScope.All)] public class XdcSubnetSealValidatorTests { - private const int Epoch = 900; - private const int Gap = 450; + private const ulong Epoch = 900; + private const ulong Gap = 450; [Test] public void EpochSwitch_PenaltiesInSnapshotButNotInHeader_HeaderIsStillValid() @@ -26,7 +26,7 @@ public void EpochSwitch_PenaltiesInSnapshotButNotInHeader_HeaderIsStillValid() Address[] candidates = [Address.FromNumber(1)]; Address[] penalties = [Address.FromNumber(2)]; ISubnetMasternodesCalculator calculator = Substitute.For(); - calculator.CalculateNextEpochMasternodes(Arg.Any(), Arg.Any(), Arg.Any()).Returns((candidates, penalties)); + calculator.CalculateNextEpochMasternodes(Arg.Any(), Arg.Any(), Arg.Any()).Returns((candidates, penalties)); XdcSubnetSealValidator validator = CreateValidator(specProvider, calculator, CreateEpochSwitchManager(true)); XdcSubnetBlockHeader parent = BuildParentHeader(899); XdcSubnetBlockHeader header = BuildSubnetHeader(parent, 900, 110, @@ -187,7 +187,7 @@ private static (IXdcReleaseSpec Spec, ISpecProvider SpecProvider) CreateSubnetSp releaseSpec.EpochLength.Returns(Epoch); releaseSpec.Gap.Returns(Gap); releaseSpec.MinePeriod.Returns(10); - releaseSpec.GasLimitBoundDivisor.Returns(1024); + releaseSpec.GasLimitBoundDivisor.Returns(1024UL); releaseSpec.When(x => x.ApplyV2Config(Arg.Any())).Do(_ => { }); ISpecProvider specProvider = Substitute.For(); @@ -215,7 +215,7 @@ private static XdcSubnetSealValidator CreateValidator( epochSwitchManager ?? CreateEpochSwitchManager(), specProvider); - private static XdcSubnetBlockHeader BuildParentHeader(long number) + private static XdcSubnetBlockHeader BuildParentHeader(ulong number) { XdcSubnetBlockHeaderBuilder b = Build.A.XdcSubnetBlockHeader(); b.WithNumber(number); @@ -229,7 +229,7 @@ private static XdcSubnetBlockHeader BuildParentHeader(long number) private static XdcSubnetBlockHeader BuildSubnetHeader( BlockHeader parent, - long number, + ulong number, ulong timestamp, Action? configure = null) { diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcTransactionProcessorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcTransactionProcessorTests.cs index 4ef3501de30d..08bc5801ee80 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcTransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcTransactionProcessorTests.cs @@ -74,7 +74,7 @@ public void PayFees_IsTipTrc21FeeEnabled_ShouldPayFeesToTheCorrectAddress( _spec.IsTipTrc21FeeEnabled.Returns(tipTrc21FeeEnabled); _spec.IsEip1559Enabled.Returns(isEip1559Enabled); - long spentGas = 21000; + ulong spentGas = 21000; UInt256 premiumPerGas = 9; UInt256 blobBaseFee = 0; Address beneficiaryAddress = TestItem.AddressB; @@ -117,13 +117,13 @@ public void PayFees_IsTipTrc21FeeEnabled_ShouldPayFeesToTheCorrectAddress( if (tipTrc21FeeEnabled) { UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(_spec.IsEip1559Enabled, header.BaseFeePerGas); - UInt256 expectedFees = effectiveGasPrice * (ulong)spentGas; + UInt256 expectedFees = effectiveGasPrice * spentGas; Assert.That(ownerReceivedFees, Is.EqualTo(expectedFees)); Assert.That(beneficiaryReceivedFees, Is.EqualTo(UInt256.Zero)); } else { - UInt256 expectedFees = premiumPerGas * (ulong)spentGas; + UInt256 expectedFees = premiumPerGas * spentGas; Assert.That(beneficiaryReceivedFees, Is.EqualTo(expectedFees)); Assert.That(ownerReceivedFees, Is.EqualTo(UInt256.Zero)); } @@ -144,7 +144,7 @@ public void TestPayFees( IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, - long spentGas, + ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) => diff --git a/src/Nethermind/Nethermind.Xdc/BaseSnapshotManager.cs b/src/Nethermind/Nethermind.Xdc/BaseSnapshotManager.cs index 53a5c82f0bfc..c4522f864b32 100644 --- a/src/Nethermind/Nethermind.Xdc/BaseSnapshotManager.cs +++ b/src/Nethermind/Nethermind.Xdc/BaseSnapshotManager.cs @@ -55,9 +55,9 @@ string cacheName protected IMasternodeVotingContract VotingContract => _votingContract; // Explicit interface implementation to return base Snapshot type - Snapshot? ISnapshotManager.GetSnapshotByGapNumber(long gapNumber) => GetSnapshotByGapNumber(gapNumber); + Snapshot? ISnapshotManager.GetSnapshotByGapNumber(ulong gapNumber) => GetSnapshotByGapNumber(gapNumber); - Snapshot? ISnapshotManager.GetSnapshotByBlockNumber(long blockNumber, IXdcReleaseSpec spec) => GetSnapshotByBlockNumber(blockNumber, spec); + Snapshot? ISnapshotManager.GetSnapshotByBlockNumber(ulong blockNumber, IXdcReleaseSpec spec) => GetSnapshotByBlockNumber(blockNumber, spec); void ISnapshotManager.StoreSnapshot(Snapshot snapshot) { @@ -71,7 +71,7 @@ void ISnapshotManager.StoreSnapshot(Snapshot snapshot) } } - public TSnapshot? GetSnapshotByGapNumber(long gapNumber) + public TSnapshot? GetSnapshotByGapNumber(ulong gapNumber) { if (_blockTree.FindHeader(gapNumber) is not XdcBlockHeader gapBlockHeader) return null; @@ -103,9 +103,10 @@ void ISnapshotManager.StoreSnapshot(Snapshot snapshot) return snapshot; } - public TSnapshot? GetSnapshotByBlockNumber(long blockNumber, IXdcReleaseSpec spec) + public TSnapshot? GetSnapshotByBlockNumber(ulong blockNumber, IXdcReleaseSpec spec) { - long gapBlockNum = Math.Max(0, blockNumber - blockNumber % spec.EpochLength - spec.Gap); + ulong epochBase = blockNumber - blockNumber % spec.EpochLength; + ulong gapBlockNum = epochBase >= spec.Gap ? epochBase - spec.Gap : 0UL; return GetSnapshotByGapNumber(gapBlockNum); } diff --git a/src/Nethermind/Nethermind.Xdc/Contracts/MintedRecordContract.cs b/src/Nethermind/Nethermind.Xdc/Contracts/MintedRecordContract.cs index 5df53cd2211d..e940471d2e20 100644 --- a/src/Nethermind/Nethermind.Xdc/Contracts/MintedRecordContract.cs +++ b/src/Nethermind/Nethermind.Xdc/Contracts/MintedRecordContract.cs @@ -28,7 +28,7 @@ public void UpdateAccounting( { XdcTransactionProcessor xdcTransactionProcessor = (XdcTransactionProcessor)transactionProcessor; IWorldState worldState = xdcTransactionProcessor.RewardWorldState; - UInt256 epochNumber = (ulong)spec.SwitchEpoch + (header.ExtraConsensusData?.BlockRound ?? 0) / (ulong)spec.EpochLength; + UInt256 epochNumber = spec.SwitchEpoch + (header.ExtraConsensusData?.BlockRound ?? 0) / spec.EpochLength; UInt256 blockNumber = (UInt256)header.Number; worldState.CreateAccountIfNotExists(MintedRecordAddress, UInt256.Zero); @@ -62,7 +62,7 @@ public void UpdateAccounting( WriteStorage(worldState, MintedRecordPostMintedBase + epochNumber, totalMinted); WriteStorage(worldState, MintedRecordPostBurnedBase + epochNumber, totalBurned); WriteStorage(worldState, MintedRecordPostRewardBlockBase + epochNumber, blockNumber); - worldState.IncrementNonce(MintedRecordAddress, UInt256.One, out _); + worldState.IncrementNonce(MintedRecordAddress, 1UL, out _); } private static UInt256 ReadStorage(IWorldState worldState, UInt256 slot) diff --git a/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs b/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs index 7ca7f142d526..4ba3dae609ea 100644 --- a/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs +++ b/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs @@ -23,6 +23,7 @@ internal class EpochSwitchManager( snapshotManager) { private LruCache Round2EpochBlockInfo { get; } = new(XdcConstants.InMemoryRound2Epochs, nameof(Round2EpochBlockInfo)); + /// /// Determine if the given block is an epoch switch block. /// @@ -48,7 +49,7 @@ public override bool IsEpochSwitchAtBlock(XdcBlockHeader header) ulong round = header.ExtraConsensusData.BlockRound; QuorumCertificate qc = header.ExtraConsensusData.QuorumCert; ulong parentRound = qc.ProposedBlockInfo.Round; - ulong epochStartRound = round - (round % (ulong)xdcSpec.EpochLength); + ulong epochStartRound = round - (round % xdcSpec.EpochLength); if (qc.ProposedBlockInfo.BlockNumber == xdcSpec.SwitchBlock) { @@ -87,12 +88,12 @@ public override bool IsEpochSwitchAtRound(ulong currentRound, XdcBlockHeader par return false; } - ulong epochStartRound = currentRound - (currentRound % (ulong)xdcSpec.EpochLength); + ulong epochStartRound = currentRound - (currentRound % xdcSpec.EpochLength); return parentRound < epochStartRound; } protected override ulong GetCurrentEpochNumber(EpochSwitchInfo epochSwitchInfo, IXdcReleaseSpec xdcSpec) => - (ulong)xdcSpec.SwitchEpoch + epochSwitchInfo.EpochSwitchBlockInfo.Round / (ulong)xdcSpec.EpochLength; + xdcSpec.SwitchEpoch + epochSwitchInfo.EpochSwitchBlockInfo.Round / xdcSpec.EpochLength; protected override Address[] ResolvePenalties(XdcBlockHeader header, Snapshot _) => header.PenaltiesAddress is null @@ -104,7 +105,7 @@ private EpochSwitchInfo[] GetEpochSwitchBetween(XdcBlockHeader start, XdcBlockHe List epochSwitchInfos = []; Hash256 iteratorHash = end.Hash; - long iteratorBlockNumber = end.Number; + ulong iteratorBlockNumber = end.Number; while (iteratorBlockNumber > start.Number) { @@ -137,7 +138,7 @@ private EpochSwitchInfo[] GetEpochSwitchBetween(XdcBlockHeader start, XdcBlockHe { List epochSwitchInCache = []; - for (ulong r = estRound; r < estRound + (ulong)epoch; r++) + for (ulong r = estRound; r < estRound + epoch; r++) { if (Round2EpochBlockInfo.TryGet(r, out BlockRoundInfo blockInfo)) { @@ -171,11 +172,14 @@ private EpochSwitchInfo[] GetEpochSwitchBetween(XdcBlockHeader start, XdcBlockHe return null; } - private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long start, long end, ulong switchBlock, ulong epoch, IXdcReleaseSpec xdcSpec, out BlockRoundInfo epochBlockInfo) + private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, ulong start, ulong end, ulong switchBlock, ulong epoch, IXdcReleaseSpec xdcSpec, out BlockRoundInfo epochBlockInfo) { while (start < end) { - XdcBlockHeader? header = (XdcBlockHeader?)Tree.FindHeader((start + end) / 2); + // Use start + (end - start) / 2 instead of (start + end) / 2 to avoid + // ulong overflow when both start and end are large block numbers. + ulong mid = start + (end - start) / 2; + XdcBlockHeader? header = (XdcBlockHeader?)Tree.FindHeader(mid); if (header is null) { epochBlockInfo = null; @@ -189,7 +193,7 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta } bool isEpochSwitch = IsEpochSwitchAtBlock(header); - ulong epochNum = (ulong)xdcSpec.SwitchEpoch + (header.ExtraConsensusData?.BlockRound ?? 0) / (ulong)xdcSpec.EpochLength; + ulong epochNum = xdcSpec.SwitchEpoch + (header.ExtraConsensusData?.BlockRound ?? 0) / xdcSpec.EpochLength; if (epochNum == targetEpochNumber) { @@ -203,8 +207,12 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta else { end = header.Number; - // trick to shorten the search - start = Math.Max(start, end - (int)(round % epoch)); + // Shorten the search range by stepping back at most (round % epoch) blocks. + // The subtraction is safe: round % epoch < epoch, and epoch is bounded by + // reasonable chain parameters, so underflow past start is guarded by the + // Math.Max clamp below. + ulong roundOffset = round % epoch; + start = end >= roundOffset ? Math.Max(start, end - roundOffset) : start; } } else if (epochNum > targetEpochNumber) @@ -213,7 +221,7 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta } else { - long nextStart = header.Number; + ulong nextStart = header.Number; if (nextStart == start) { break; @@ -241,7 +249,7 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta return null; } - ulong epochNumber = (ulong)xdcSpec.SwitchEpoch + epochSwitchInfo.EpochSwitchBlockInfo.Round / (ulong)xdcSpec.EpochLength; + ulong epochNumber = xdcSpec.SwitchEpoch + epochSwitchInfo.EpochSwitchBlockInfo.Round / xdcSpec.EpochLength; if (targetEpoch == epochNumber) { @@ -253,22 +261,22 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta return null; } - if (targetEpoch < (ulong)xdcSpec.SwitchEpoch) + if (targetEpoch < xdcSpec.SwitchEpoch) { return null; } - ulong estRound = (targetEpoch - (ulong)xdcSpec.SwitchEpoch) * (ulong)xdcSpec.EpochLength; + ulong estRound = (targetEpoch - xdcSpec.SwitchEpoch) * xdcSpec.EpochLength; - BlockRoundInfo epochBlockInfo = GetBlockInfoInCache(estRound, (ulong)xdcSpec.EpochLength); + BlockRoundInfo epochBlockInfo = GetBlockInfoInCache(estRound, xdcSpec.EpochLength); if (epochBlockInfo is not null) { return epochBlockInfo; } - ulong epoch = (ulong)xdcSpec.EpochLength; + ulong epoch = xdcSpec.EpochLength; ulong estBlockNumDiff = epoch * (epochNumber - targetEpoch); - long estBlockNum = Math.Max((long)xdcSpec.SwitchBlock, epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber - (long)estBlockNumDiff); + ulong estBlockNum = Math.Max(xdcSpec.SwitchBlock, epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber - estBlockNumDiff); ulong closeEpochNum = 2ul; @@ -286,7 +294,7 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta } foreach (EpochSwitchInfo info in epochSwitchInfos) { - ulong epochNum = (ulong)xdcSpec.SwitchEpoch + info.EpochSwitchBlockInfo.Round / (ulong)xdcSpec.EpochLength; + ulong epochNum = xdcSpec.SwitchEpoch + info.EpochSwitchBlockInfo.Round / xdcSpec.EpochLength; if (epochNum == targetEpoch) { return info.EpochSwitchBlockInfo; @@ -294,7 +302,7 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, long sta } } - if (!TryBinarySearchBlockByEpochNumber(targetEpoch, estBlockNum, epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber, (ulong)xdcSpec.SwitchBlock, (ulong)xdcSpec.EpochLength, xdcSpec, out epochBlockInfo)) + if (!TryBinarySearchBlockByEpochNumber(targetEpoch, estBlockNum, epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber, xdcSpec.SwitchBlock, xdcSpec.EpochLength, xdcSpec, out epochBlockInfo)) { return null; } diff --git a/src/Nethermind/Nethermind.Xdc/Errors/IncomingMessageBlockNotFoundException.cs b/src/Nethermind/Nethermind.Xdc/Errors/IncomingMessageBlockNotFoundException.cs index 9fdfd7166517..d731fe5aca78 100644 --- a/src/Nethermind/Nethermind.Xdc/Errors/IncomingMessageBlockNotFoundException.cs +++ b/src/Nethermind/Nethermind.Xdc/Errors/IncomingMessageBlockNotFoundException.cs @@ -7,9 +7,9 @@ namespace Nethermind.Xdc.Errors; -public class IncomingMessageBlockNotFoundException(Hash256 incomingBlockHash, long incomingBlockNumber, Exception? innerException = null) +public class IncomingMessageBlockNotFoundException(Hash256 incomingBlockHash, ulong incomingBlockNumber, Exception? innerException = null) : BlockchainException($"proposed block is not found hash: {incomingBlockHash}, block number: {incomingBlockNumber}", innerException) { public Hash256 IncomingBlockHash { get; } = incomingBlockHash; - public long IncomingBlockNumber { get; } = incomingBlockNumber; + public ulong IncomingBlockNumber { get; } = incomingBlockNumber; } diff --git a/src/Nethermind/Nethermind.Xdc/ForensicsProcessor.cs b/src/Nethermind/Nethermind.Xdc/ForensicsProcessor.cs index 466189b35d8e..5d659acc0b4f 100644 --- a/src/Nethermind/Nethermind.Xdc/ForensicsProcessor.cs +++ b/src/Nethermind/Nethermind.Xdc/ForensicsProcessor.cs @@ -161,15 +161,18 @@ internal QuorumCertificate[] GetHighestCommittedQcsSnapshot() List lowerBlockNumToAncestorHashPath = []; List higherBlockToAncestorNumHashPath = []; - bool orderSwapped = false; + bool orderSwapped = secondBlockInfo.BlockNumber < firstBlockInfo.BlockNumber; - long blockNumberDifference = secondBlockInfo.BlockNumber - firstBlockInfo.BlockNumber; - if (blockNumberDifference < 0) + ulong blockNumberDifference; + if (orderSwapped) { lowerBlockNumHash = secondBlockInfo.Hash; higherBlockNumberHash = firstBlockInfo.Hash; - blockNumberDifference = -blockNumberDifference; - orderSwapped = true; + blockNumberDifference = firstBlockInfo.BlockNumber - secondBlockInfo.BlockNumber; + } + else + { + blockNumberDifference = secondBlockInfo.BlockNumber - firstBlockInfo.BlockNumber; } if (blockNumberDifference > MaxForensicsTraversalDepth) @@ -184,7 +187,7 @@ internal QuorumCertificate[] GetHighestCommittedQcsSnapshot() lowerBlockNumToAncestorHashPath.Add(lowerBlockNumHash.ToString()); higherBlockToAncestorNumHashPath.Add(higherBlockNumberHash.ToString()); - for (int i = 0; i < blockNumberDifference; i++) + for (int i = 0; i < (int)blockNumberDifference; i++) { XdcBlockHeader? parentHeader = (XdcBlockHeader?)_blockTree.FindHeader(higherBlockNumberHash); if (parentHeader is null || parentHeader.ParentHash is null) @@ -243,13 +246,13 @@ private bool CheckQCsOnTheSameChain(QuorumCertificate[] highestCommittedQCs, Quo } BlockRoundInfo proposedBlockInfo = higherBlockNumQCs[0].ProposedBlockInfo; - long blockDifference = higherBlockNumQCs[0].ProposedBlockInfo.BlockNumber - lowerBlockNumQCs[0].ProposedBlockInfo.BlockNumber; + ulong blockDifference = higherBlockNumQCs[0].ProposedBlockInfo.BlockNumber - lowerBlockNumQCs[0].ProposedBlockInfo.BlockNumber; if (blockDifference < 0 || blockDifference > MaxForensicsTraversalDepth) { return false; } - for (int i = 0; i < blockDifference; i++) + for (int i = 0; i < (int)blockDifference; i++) { XdcBlockHeader? parentHeader = (XdcBlockHeader?)_blockTree.FindHeader(proposedBlockInfo.Hash); QuorumCertificate? parentQc = parentHeader?.ExtraConsensusData?.QuorumCert; @@ -430,14 +433,14 @@ private ValueHash256 VoteHash(Vote vote) private bool IsExtendingFromAncestor(BlockRoundInfo currentBlock, BlockRoundInfo ancestorBlock) { - long blockNumDiff = currentBlock.BlockNumber - ancestorBlock.BlockNumber; + ulong blockNumDiff = currentBlock.BlockNumber - ancestorBlock.BlockNumber; if (blockNumDiff < 0 || blockNumDiff > MaxForensicsTraversalDepth) { return false; } Hash256 nextBlockHash = currentBlock.Hash; - for (int i = 0; i < blockNumDiff; i++) + for (int i = 0; i < (int)blockNumDiff; i++) { XdcBlockHeader? parentBlock = (XdcBlockHeader?)_blockTree.FindHeader(nextBlockHash); if (parentBlock is null || parentBlock.ParentHash is null) diff --git a/src/Nethermind/Nethermind.Xdc/IMasternodesCalculator.cs b/src/Nethermind/Nethermind.Xdc/IMasternodesCalculator.cs index 11d8c7e1bad2..95a0decda4bb 100644 --- a/src/Nethermind/Nethermind.Xdc/IMasternodesCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/IMasternodesCalculator.cs @@ -9,5 +9,5 @@ namespace Nethermind.Xdc; public interface IMasternodesCalculator { - (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(long blockNumber, Hash256 parentHash, IXdcReleaseSpec spec); + (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(ulong blockNumber, Hash256 parentHash, IXdcReleaseSpec spec); } diff --git a/src/Nethermind/Nethermind.Xdc/IPenaltyHandler.cs b/src/Nethermind/Nethermind.Xdc/IPenaltyHandler.cs index f9906aec6281..5eae79c5dd66 100644 --- a/src/Nethermind/Nethermind.Xdc/IPenaltyHandler.cs +++ b/src/Nethermind/Nethermind.Xdc/IPenaltyHandler.cs @@ -8,5 +8,5 @@ namespace Nethermind.Xdc; public interface IPenaltyHandler { - Address[] HandlePenalties(long number, Hash256 currentHash, Address[] candidates); + Address[] HandlePenalties(ulong number, Hash256 currentHash, Address[] candidates); } diff --git a/src/Nethermind/Nethermind.Xdc/ISigningTxCache.cs b/src/Nethermind/Nethermind.Xdc/ISigningTxCache.cs index 84709224d8be..3756735750fe 100644 --- a/src/Nethermind/Nethermind.Xdc/ISigningTxCache.cs +++ b/src/Nethermind/Nethermind.Xdc/ISigningTxCache.cs @@ -9,6 +9,6 @@ namespace Nethermind.Xdc; public interface ISigningTxCache { - Transaction[] GetSigningTransactions(Hash256 blockHash, long blockNumber, IXdcReleaseSpec spec); + Transaction[] GetSigningTransactions(Hash256 blockHash, ulong blockNumber, IXdcReleaseSpec spec); void SetSigningTransactions(Hash256 blockHash, Transaction[] transactions); } diff --git a/src/Nethermind/Nethermind.Xdc/ISnapshotManager.cs b/src/Nethermind/Nethermind.Xdc/ISnapshotManager.cs index 2ed93d403652..12745aeffebe 100644 --- a/src/Nethermind/Nethermind.Xdc/ISnapshotManager.cs +++ b/src/Nethermind/Nethermind.Xdc/ISnapshotManager.cs @@ -9,13 +9,13 @@ namespace Nethermind.Xdc; public interface ISnapshotManager : IDisposable { - static bool IsTimeForSnapshot(long blockNumber, IXdcReleaseSpec spec) + static bool IsTimeForSnapshot(ulong blockNumber, IXdcReleaseSpec spec) { if (blockNumber == spec.SwitchBlock) return true; return blockNumber % spec.EpochLength == spec.EpochLength - spec.Gap; } - Snapshot? GetSnapshotByGapNumber(long gapNumber); - Snapshot? GetSnapshotByBlockNumber(long blockNumber, IXdcReleaseSpec spec); + Snapshot? GetSnapshotByGapNumber(ulong gapNumber); + Snapshot? GetSnapshotByBlockNumber(ulong blockNumber, IXdcReleaseSpec spec); void StoreSnapshot(Snapshot snapshot); } diff --git a/src/Nethermind/Nethermind.Xdc/IVotesManager.cs b/src/Nethermind/Nethermind.Xdc/IVotesManager.cs index 818d317ae62d..592ed006504d 100644 --- a/src/Nethermind/Nethermind.Xdc/IVotesManager.cs +++ b/src/Nethermind/Nethermind.Xdc/IVotesManager.cs @@ -15,5 +15,5 @@ public interface IVotesManager Task OnReceiveVote(Vote vote); bool VerifyVotingRules(BlockRoundInfo roundInfo, QuorumCertificate certificate, [NotNullWhen(false)] out string? error); bool VerifyVotingRules(XdcBlockHeader header, [NotNullWhen(false)] out string? error); - bool VerifyVotingRules(Hash256 blockHash, long blockNumber, ulong roundNumber, QuorumCertificate qc, [NotNullWhen(false)] out string? error); + bool VerifyVotingRules(Hash256 blockHash, ulong blockNumber, ulong roundNumber, QuorumCertificate qc, [NotNullWhen(false)] out string? error); } diff --git a/src/Nethermind/Nethermind.Xdc/IXdcHeaderStore.cs b/src/Nethermind/Nethermind.Xdc/IXdcHeaderStore.cs index f2f42c82cc3b..4324e3af5fe0 100644 --- a/src/Nethermind/Nethermind.Xdc/IXdcHeaderStore.cs +++ b/src/Nethermind/Nethermind.Xdc/IXdcHeaderStore.cs @@ -11,7 +11,7 @@ internal interface IXdcHeaderStore : IHeaderStore { void Insert(XdcBlockHeader header) => ((IHeaderStore)this).Insert(header); void BulkInsert(IReadOnlyList headers) => ((IHeaderStore)this).BulkInsert(headers); - new XdcBlockHeader? Get(Hash256 blockHash, bool shouldCache, long? blockNumber = null) => ((IHeaderStore)this).Get(blockHash, shouldCache, blockNumber) as XdcBlockHeader; + new XdcBlockHeader? Get(Hash256 blockHash, bool shouldCache, ulong? blockNumber = null) => ((IHeaderStore)this).Get(blockHash, shouldCache, blockNumber) as XdcBlockHeader; void Cache(XdcBlockHeader header) => ((IHeaderStore)this).Cache(header); } diff --git a/src/Nethermind/Nethermind.Xdc/InitializeBlockchainXdc.cs b/src/Nethermind/Nethermind.Xdc/InitializeBlockchainXdc.cs index fa2f00c09090..3ce55bcf14de 100644 --- a/src/Nethermind/Nethermind.Xdc/InitializeBlockchainXdc.cs +++ b/src/Nethermind/Nethermind.Xdc/InitializeBlockchainXdc.cs @@ -6,7 +6,9 @@ using Nethermind.Core; using Nethermind.Init.Steps; using Nethermind.TxPool; +using Nethermind.Xdc.Spec; using Nethermind.Xdc.TxPool; +using System; using System.Collections.Generic; namespace Nethermind.Xdc; @@ -15,6 +17,17 @@ internal class InitializeBlockchainXdc(INethermindApi api, IChainHeadInfoProvide : InitializeBlockchain(api, chainHeadInfoProvider, txGossipPolicy) { private readonly INethermindApi _api = api; + + // Non-trivial cast: ISpecProvider -> XdcChainSpecBasedSpecProvider. + // Safe in the XDC context because XDC nodes are always configured with + // XdcChainSpecBasedSpecProvider. Throws early at startup if the DI + // container is mis-configured rather than silently returning null. + private XdcChainSpecBasedSpecProvider XdcSpecProvider => + _api.SpecProvider as XdcChainSpecBasedSpecProvider + ?? throw new InvalidOperationException( + $"Expected {nameof(XdcChainSpecBasedSpecProvider)} but got {_api.SpecProvider?.GetType().Name}. " + + "Ensure the DI container registers XdcChainSpecBasedSpecProvider for ISpecProvider."); + protected override ITxPool CreateTxPool(IChainHeadInfoProvider chainHeadInfoProvider) { ISnapshotManager snapshotManager = _api.Context.Resolve(); @@ -27,7 +40,7 @@ protected override ITxPool CreateTxPool(IChainHeadInfoProvider chainHeadInfoProv _api.LogManager, CreateTxPoolTxComparer(), _txGossipPolicy, - new SignTransactionFilter(snapshotManager, _api.BlockTree, _api.SpecProvider), + new SignTransactionFilter(snapshotManager, _api.BlockTree, XdcSpecProvider), _api.HeadTxValidator, true ); @@ -36,5 +49,6 @@ protected override ITxPool CreateTxPool(IChainHeadInfoProvider chainHeadInfoProv return txPool; } - protected new IComparer CreateTxPoolTxComparer() => new XdcTransactionComparerProvider(_api.SpecProvider!, _api.BlockTree!).GetDefaultComparer(); + protected new IComparer CreateTxPoolTxComparer() => + new XdcTransactionComparerProvider(XdcSpecProvider, _api.BlockTree!).GetDefaultComparer(); } diff --git a/src/Nethermind/Nethermind.Xdc/MasternodesCalculator.cs b/src/Nethermind/Nethermind.Xdc/MasternodesCalculator.cs index 897bf2803c82..fcc8341ed72f 100644 --- a/src/Nethermind/Nethermind.Xdc/MasternodesCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/MasternodesCalculator.cs @@ -12,7 +12,7 @@ namespace Nethermind.Xdc; internal class MasternodesCalculator(ISnapshotManager snapshotManager, IPenaltyHandler penaltyHandler) : IMasternodesCalculator { - public (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(long blockNumber, Hash256 parentHash, IXdcReleaseSpec spec) + public (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(ulong blockNumber, Hash256 parentHash, IXdcReleaseSpec spec) { int maxMasternodes = spec.MaxMasternodes; Snapshot previousSnapshot = snapshotManager.GetSnapshotByBlockNumber(blockNumber, spec) ?? throw new InvalidOperationException($"No snapshot found for header #{blockNumber}"); diff --git a/src/Nethermind/Nethermind.Xdc/PenaltyHandler.cs b/src/Nethermind/Nethermind.Xdc/PenaltyHandler.cs index 269d3dab56a2..e07b94b57117 100644 --- a/src/Nethermind/Nethermind.Xdc/PenaltyHandler.cs +++ b/src/Nethermind/Nethermind.Xdc/PenaltyHandler.cs @@ -24,7 +24,7 @@ private Address[] GetPreviousPenalties(Hash256 currentHash, IXdcReleaseSpec spec if (limit == 0) return currentEpochSwitchInfo.Penalties; - ulong epochNumber = (ulong)spec.SwitchEpoch + currentEpochSwitchInfo.EpochSwitchBlockInfo.Round / (ulong)spec.EpochLength; + ulong epochNumber = spec.SwitchEpoch + currentEpochSwitchInfo.EpochSwitchBlockInfo.Round / spec.EpochLength; if (epochNumber < limit) return []; BlockRoundInfo results = epochSwitchManager.GetBlockByEpochNumber(epochNumber - limit); @@ -36,14 +36,16 @@ private Address[] GetPreviousPenalties(Hash256 currentHash, IXdcReleaseSpec spec return [.. header.PenaltiesAddress]; } - public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] candidates) + public Address[] HandlePenalties(ulong number, Hash256 parentHash, Address[] candidates) { List listBlockHash = [parentHash]; Dictionary minerStatistics = []; - long parentNumber = number - 1; + // Loop down from (number - 1) to 1. Since parentNumber is ulong, we use > 0 + // to avoid wrapping past 0 — block 0 is genesis and never an epoch switch body block. + ulong parentNumber = number - 1; Hash256 currentHash = parentHash; - while (parentNumber >= 0) + while (parentNumber > 0) { XdcBlockHeader parentHeader = (XdcBlockHeader)tree.FindHeader(currentHash, parentNumber); if (parentHeader is null) return []; @@ -80,21 +82,23 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand if (!currentSpec.IsTipUpgradePenaltyEnabled) { - long comebackHeight = (currentSpec.LimitPenaltyEpochV2 + 1) * currentSpec.EpochLength + currentSpec.SwitchBlock; + ulong comebackHeight = (currentSpec.LimitPenaltyEpochV2 + 1) * currentSpec.EpochLength + currentSpec.SwitchBlock; if (number > comebackHeight) { - Address[] prevPenalties = GetPreviousPenalties(parentHash, currentSpec, (ulong)currentSpec.LimitPenaltyEpochV2); + Address[] prevPenalties = GetPreviousPenalties(parentHash, currentSpec, currentSpec.LimitPenaltyEpochV2); HashSet
penComebacks = prevPenalties.Intersect(candidates).ToHashSet(); HashSet blockHashes = []; - int startRange = Math.Min((int)currentSpec.RangeReturnSigner, listBlockHash.Count) - 1; + // RangeReturnSigner is ulong; clamp to listBlockHash.Count (int) before use as + // a loop bound. The cast to int is safe: listBlockHash.Count is always <= int.MaxValue. + int startRange = (int)Math.Min(currentSpec.RangeReturnSigner, (ulong)listBlockHash.Count) - 1; for (int i = startRange; i >= 0; i--) { if (penComebacks.Count == 0) break; - long blockNumber = number - i - 1; + ulong blockNumber = number - (ulong)i - 1; Hash256 blockHash = listBlockHash[i]; if (blockNumber % currentSpec.MergeSignRange == 0) @@ -116,16 +120,17 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand } else { - long limitPenaltyEpoch = currentSpec.LimitPenaltyEpoch > 0 ? currentSpec.LimitPenaltyEpoch : 1; - long comebackHeight = limitPenaltyEpoch * currentSpec.EpochLength + currentSpec.SwitchBlock; + // LimitPenaltyEpoch of 0 is treated as 1 to avoid division/multiplication by zero. + ulong limitPenaltyEpoch = currentSpec.LimitPenaltyEpoch > 0 ? currentSpec.LimitPenaltyEpoch : 1; + ulong comebackHeight = limitPenaltyEpoch * currentSpec.EpochLength + currentSpec.SwitchBlock; if (number > comebackHeight) { Dictionary penaltyParolees = []; Address[] lastPenalty = []; - for (long i = 0; i < limitPenaltyEpoch; i++) + for (ulong i = 0; i < limitPenaltyEpoch; i++) { - Address[] previousPenalties = GetPreviousPenalties(parentHash, currentSpec, (ulong)i); + Address[] previousPenalties = GetPreviousPenalties(parentHash, currentSpec, i); foreach (Address previousPenalty in previousPenalties) { penaltyParolees[previousPenalty] = penaltyParolees.TryGetValue(previousPenalty, out ulong count) @@ -138,11 +143,13 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand HashSet blockHashes = []; Dictionary txSignerMap = []; - int startRange = Math.Min(currentSpec.EpochLength, listBlockHash.Count) - 1; + // EpochLength is ulong; clamp to listBlockHash.Count (int) before use as a loop + // bound. The cast to int is safe: listBlockHash.Count is always <= int.MaxValue. + int startRange = (int)Math.Min(currentSpec.EpochLength, (ulong)listBlockHash.Count) - 1; for (int i = startRange; i >= 0; i--) { - long blockNumber = number - i - 1; + ulong blockNumber = number - (ulong)i - 1; Hash256 blockHash = listBlockHash[i]; if (blockNumber % currentSpec.MergeSignRange == 0) @@ -163,7 +170,7 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand foreach (Address penalty in lastPenalty) { penaltyParolees.TryGetValue(penalty, out ulong epochs); - if (epochs == (ulong)limitPenaltyEpoch) + if (epochs == limitPenaltyEpoch) { txSignerMap.TryGetValue(penalty, out int signedCount); if (signedCount >= currentSpec.MinimumSigningTx) diff --git a/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs b/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs index 70562a281b16..ce86b442ed84 100644 --- a/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs +++ b/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs @@ -221,13 +221,11 @@ public bool VerifyCertificate(QuorumCertificate qc, XdcBlockHeader certificateTa } } - long epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - long gapNumber = epochSwitchNumber - (epochSwitchNumber % (long)spec.EpochLength) - (long)spec.Gap; + ulong epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong epochBase = epochSwitchNumber - (epochSwitchNumber % (ulong)spec.EpochLength); + ulong gapNumber = epochBase >= spec.Gap ? epochBase - spec.Gap : 0UL; - if (epochSwitchNumber - (epochSwitchNumber % (long)spec.EpochLength) < (long)spec.Gap) - gapNumber = 0; - - if (gapNumber != (long)qc.GapNumber) + if (gapNumber != qc.GapNumber) { error = $"Gap number mismatch between QC Gap {qc.GapNumber} and {gapNumber}"; return false; @@ -268,7 +266,7 @@ public void Initialize(XdcBlockHeader current) if (current.ExtraConsensusData is null && _logger.IsInfo) _logger.Info($"Block {current.ToString(BlockHeader.Format.FullHashAndNumber)} has no V2 consensus data; initializing consensus on round 1."); latestQc = new QuorumCertificate(new BlockRoundInfo(current.Hash, 0, current.Number), Array.Empty(), - (ulong)Math.Max(0, current.Number - spec.Gap)); + current.Number >= spec.Gap ? current.Number - spec.Gap : 0UL); _context.HighestQC = latestQc; _context.SetNewRound(1); } diff --git a/src/Nethermind/Nethermind.Xdc/RLP/BaseSnapshotDecoder.cs b/src/Nethermind/Nethermind.Xdc/RLP/BaseSnapshotDecoder.cs index e024a071ea9d..dde6e6649899 100644 --- a/src/Nethermind/Nethermind.Xdc/RLP/BaseSnapshotDecoder.cs +++ b/src/Nethermind/Nethermind.Xdc/RLP/BaseSnapshotDecoder.cs @@ -11,7 +11,7 @@ namespace Nethermind.Xdc.RLP; internal abstract class BaseSnapshotDecoder : RlpDecoder where T : Snapshot { - protected TResult DecodeBase(ref Rlp.ValueDecoderContext decoderContext, Func createSnapshot, RlpBehaviors rlpBehaviors = RlpBehaviors.None) where TResult : Snapshot + protected TResult DecodeBase(ref Rlp.ValueDecoderContext decoderContext, Func createSnapshot, RlpBehaviors rlpBehaviors = RlpBehaviors.None) where TResult : Snapshot { if (decoderContext.IsNextItemEmptyList()) { @@ -20,7 +20,7 @@ protected TResult DecodeBase(ref Rlp.ValueDecoderContext decoderContext } decoderContext.ReadSequenceLength(); - long number = decoderContext.DecodeLong(); + ulong number = decoderContext.DecodeULong(); Hash256 hash256 = decoderContext.DecodeKeccak(); Address[] candidates = DecodeAddressArray(ref decoderContext); return createSnapshot(number, hash256, candidates); diff --git a/src/Nethermind/Nethermind.Xdc/RLP/BaseXdcHeaderDecoder.cs b/src/Nethermind/Nethermind.Xdc/RLP/BaseXdcHeaderDecoder.cs index 6e7f8eabc5ec..39f5862cf521 100644 --- a/src/Nethermind/Nethermind.Xdc/RLP/BaseXdcHeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Xdc/RLP/BaseXdcHeaderDecoder.cs @@ -21,8 +21,8 @@ protected abstract TH CreateHeader( Hash256? unclesHash, Address? beneficiary, UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[]? extraData); @@ -51,9 +51,9 @@ protected abstract TH CreateHeader( Hash256? receiptsRoot = decoderContext.DecodeKeccak(); Bloom? bloom = decoderContext.DecodeBloom(); UInt256 difficulty = decoderContext.DecodeUInt256(); - long number = decoderContext.DecodeLong(); - long gasLimit = decoderContext.DecodeLong(); - long gasUsed = decoderContext.DecodeLong(); + ulong number = decoderContext.DecodeULong(); + ulong gasLimit = decoderContext.DecodeULong(); + ulong gasUsed = decoderContext.DecodeULong(); ulong timestamp = decoderContext.DecodeULong(); byte[]? extraData = decoderContext.DecodeByteArray(); diff --git a/src/Nethermind/Nethermind.Xdc/RLP/XdcBlockInfoDecoder.cs b/src/Nethermind/Nethermind.Xdc/RLP/XdcBlockInfoDecoder.cs index 68467ea54712..7397cf04a206 100644 --- a/src/Nethermind/Nethermind.Xdc/RLP/XdcBlockInfoDecoder.cs +++ b/src/Nethermind/Nethermind.Xdc/RLP/XdcBlockInfoDecoder.cs @@ -23,7 +23,7 @@ protected override BlockRoundInfo DecodeInternal(ref Rlp.ValueDecoderContext dec if (hashBytes.Length > Hash256.Size) throw new RlpException($"Hash length {hashBytes.Length} is longer than max size of 32."); ulong round = decoderContext.DecodeULong(); - long number = decoderContext.DecodePositiveLong(); + ulong number = decoderContext.DecodeULong(); return new BlockRoundInfo(new Hash256(hashBytes), round, number); } diff --git a/src/Nethermind/Nethermind.Xdc/RLP/XdcHeaderDecoder.cs b/src/Nethermind/Nethermind.Xdc/RLP/XdcHeaderDecoder.cs index d737ea10b4c8..e15b8bb0716e 100644 --- a/src/Nethermind/Nethermind.Xdc/RLP/XdcHeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Xdc/RLP/XdcHeaderDecoder.cs @@ -15,8 +15,8 @@ protected override XdcBlockHeader CreateHeader( Hash256? unclesHash, Address? beneficiary, UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[]? extraData) => new(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData); diff --git a/src/Nethermind/Nethermind.Xdc/RLP/XdcSubnetHeaderDecoder.cs b/src/Nethermind/Nethermind.Xdc/RLP/XdcSubnetHeaderDecoder.cs index 3c49c7bda047..6a312655a0ad 100644 --- a/src/Nethermind/Nethermind.Xdc/RLP/XdcSubnetHeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Xdc/RLP/XdcSubnetHeaderDecoder.cs @@ -15,8 +15,8 @@ protected override XdcSubnetBlockHeader CreateHeader( Hash256? unclesHash, Address? beneficiary, UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[]? extraData) => new(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData); diff --git a/src/Nethermind/Nethermind.Xdc/SignTransactionManager.cs b/src/Nethermind/Nethermind.Xdc/SignTransactionManager.cs index d7184e290054..73a8b2ce4df7 100644 --- a/src/Nethermind/Nethermind.Xdc/SignTransactionManager.cs +++ b/src/Nethermind/Nethermind.Xdc/SignTransactionManager.cs @@ -41,7 +41,7 @@ internal class SignTransactionManager( public Task SubmitTransactionSign(XdcBlockHeader header, IXdcReleaseSpec spec) { - UInt256 nonce = _txPool.Value.GetLatestPendingNonce(_signer.Value.Address); + ulong nonce = _txPool.Value.GetLatestPendingNonce(_signer.Value.Address); Transaction transaction = CreateTxSign((UInt256)header.Number, header.Hash ?? header.CalculateHash().ToHash256(), nonce, spec.BlockSignerContract, _signer.Value.Address); if (!_signer.Value.TrySign(transaction)) @@ -95,7 +95,7 @@ private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e) private static bool IsMasternode(Snapshot snapshot, Address signerAddress) => snapshot.NextEpochCandidates.AsSpan().IndexOf(signerAddress) != -1; - internal static Transaction CreateTxSign(UInt256 number, Hash256 hash, UInt256 nonce, Address blockSignersAddress, Address sender) + internal static Transaction CreateTxSign(UInt256 number, Hash256 hash, ulong nonce, Address blockSignersAddress, Address sender) { byte[] inputData = [.. XdcConstants.SignMethod, .. number.PaddedBytes(32), .. hash.Bytes.PadLeft(32)]; diff --git a/src/Nethermind/Nethermind.Xdc/SigningTxCache.cs b/src/Nethermind/Nethermind.Xdc/SigningTxCache.cs index 06939a944d7e..000eecfeee3e 100644 --- a/src/Nethermind/Nethermind.Xdc/SigningTxCache.cs +++ b/src/Nethermind/Nethermind.Xdc/SigningTxCache.cs @@ -25,7 +25,7 @@ public SigningTxCache(IBlockTree blockTree, ISpecProvider specProvider) _blockTree.NewHeadBlock += OnNewHeadBlock; } - public Transaction[] GetSigningTransactions(Hash256 blockHash, long blockNumber, IXdcReleaseSpec spec) + public Transaction[] GetSigningTransactions(Hash256 blockHash, ulong blockNumber, IXdcReleaseSpec spec) { if (_signingTxsCache.TryGet(blockHash, out Transaction[] signingTxs)) return signingTxs; diff --git a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecBasedSpecProvider.cs index 46b224505693..f436f4c96776 100644 --- a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecBasedSpecProvider.cs @@ -26,7 +26,7 @@ public IXdcReleaseSpec GetXdcSpec(XdcBlockHeader header, ulong round = 0) return GetXdcSpec(header.Number, round); } - public IXdcReleaseSpec GetXdcSpec(long blockNumber, ulong round = 0) + public IXdcReleaseSpec GetXdcSpec(ulong blockNumber, ulong round = 0) { int blockIndex = GetBlockTransitionIndex(blockNumber); int roundIndex = GetRoundConfigIndex(round); @@ -41,7 +41,7 @@ public IXdcReleaseSpec GetXdcSpec(long blockNumber, ulong round = 0) return _specCache.GetOrAdd((blockIndex, roundIndex), copy); } - private int GetBlockTransitionIndex(long blockNumber) + private int GetBlockTransitionIndex(ulong blockNumber) { int result = _blockTransitions.BinarySearch(new ForkActivation(blockNumber), static (a, t) => a.CompareTo(t.Activation)); @@ -57,7 +57,8 @@ private int GetRoundConfigIndex(ulong round) } protected override ReleaseSpec CreateEmptyReleaseSpec() => new XdcReleaseSpec(); - protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releaseStartBlock, ulong? releaseStartTimestamp = null) + + protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, ulong releaseStartBlock, ulong? releaseStartTimestamp = null) { XdcReleaseSpec releaseSpec = (XdcReleaseSpec)base.CreateReleaseSpec(chainSpec, releaseStartBlock, releaseStartTimestamp); @@ -74,13 +75,14 @@ protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long relea releaseSpec.ProtectorReward = chainSpecEngineParameters.ProtectorReward; releaseSpec.ObserverReward = chainSpecEngineParameters.ObserverReward; - releaseSpec.IsTipTrc21FeeEnabled = (chainSpecEngineParameters.TipTrc21Fee ?? 0) <= releaseStartBlock; + releaseSpec.IsTipTrc21FeeEnabled = (chainSpecEngineParameters.TipTrc21Fee ?? 0UL) <= releaseStartBlock; releaseSpec.IsBlackListingEnabled = chainSpecEngineParameters.BlackListHFNumber <= releaseStartBlock; releaseSpec.IsTIP2019 = chainSpecEngineParameters.TIP2019Block <= releaseStartBlock; releaseSpec.IsTIPXDCXMiner = chainSpecEngineParameters.TipXDCX <= releaseStartBlock && releaseStartBlock < chainSpecEngineParameters.TIPXDCXMinerDisable; - releaseSpec.IsDynamicGasLimitBlock = chainSpecEngineParameters.DynamicGasLimitBlock <= releaseStartBlock; - releaseSpec.IsTipUpgradeRewardEnabled = (chainSpecEngineParameters.TipUpgradeReward ?? long.MaxValue) <= releaseStartBlock; - releaseSpec.IsTipUpgradePenaltyEnabled = (chainSpecEngineParameters.TipUpgradePenalty ?? long.MaxValue) <= releaseStartBlock; + releaseSpec.IsDynamicGasLimitBlock = (chainSpecEngineParameters.DynamicGasLimitBlock ?? 0UL) <= releaseStartBlock; + // Fall back to ulong.MaxValue so that a null TipUpgradeReward/Penalty means "never enabled". + releaseSpec.IsTipUpgradeRewardEnabled = (chainSpecEngineParameters.TipUpgradeReward ?? ulong.MaxValue) <= releaseStartBlock; + releaseSpec.IsTipUpgradePenaltyEnabled = (chainSpecEngineParameters.TipUpgradePenalty ?? ulong.MaxValue) <= releaseStartBlock; releaseSpec.MergeSignRange = chainSpecEngineParameters.MergeSignRange; releaseSpec.BlackListedAddresses = [.. chainSpecEngineParameters.BlackListedAddresses ?? []]; @@ -100,7 +102,7 @@ protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long relea if (releaseSpec.SwitchBlock == 0) { - //We can parse genesis masternodes from genesis if the chain starts as V2 + // We can parse genesis masternodes from genesis if the chain starts as V2 byte[] genesisExtraData = chainSpec.Genesis?.ExtraData ?? throw new ArgumentException("Genesis ExtraData is required when SwitchBlock is 0", nameof(chainSpec)); releaseSpec.GenesisMasterNodes = genesisExtraData.ParseV1Masternodes(); @@ -112,5 +114,4 @@ protected override ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long relea return releaseSpec; } - } diff --git a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs index 6e3a48a341d0..c27c2555d0f9 100644 --- a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs @@ -16,14 +16,14 @@ public class XdcChainSpecEngineParameters : IChainSpecEngineParameters { public string EngineName => SealEngineType; public string SealEngineType => XdcConstants.XDPoS; - public int Epoch { get; set; } - public int Gap { get; set; } - public int Period { get; set; } + public ulong Epoch { get; set; } + public ulong Gap { get; set; } + public ulong Period { get; set; } public bool SkipV1Validation { get; set; } public Address FoundationWalletAddr { get; set; } - public int Reward { get; set; } - public int SwitchEpoch { get; set; } - public long SwitchBlock { get; set; } + public ulong Reward { get; set; } + public ulong SwitchEpoch { get; set; } + public ulong SwitchBlock { get; set; } public ulong RangeReturnSigner { get; set; } public Address[] GenesisMasternodes { get; set; } = Array.Empty
(); @@ -36,8 +36,8 @@ public class XdcChainSpecEngineParameters : IChainSpecEngineParameters public Address MasternodeVotingContract { get; set; } - public long LimitPenaltyEpoch { get; set; } // Epochs in a row that a penalty node needs to be penalized - public long LimitPenaltyEpochV2 { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong LimitPenaltyEpoch { get; set; } + public ulong LimitPenaltyEpochV2 { get; set; } private List _v2Configs = []; public List V2Configs @@ -51,19 +51,20 @@ public List V2Configs _v2Configs = value; } } - public long? TipTrc21Fee { get; set; } - public long TIP2019Block { get; set; } - public long? TipUpgradePenalty { get; set; } - public long? TipUpgradeReward { get; set; } + + public ulong? TipTrc21Fee { get; set; } + public ulong TIP2019Block { get; set; } + public ulong? TipUpgradePenalty { get; set; } + public ulong? TipUpgradeReward { get; set; } public UInt256 MasternodeReward { get; set; } public UInt256 ProtectorReward { get; set; } public UInt256 ObserverReward { get; set; } - public long MergeSignRange { get; set; } + public ulong MergeSignRange { get; set; } public Address[] BlackListedAddresses { get; set; } - public long BlackListHFNumber { get; set; } - public long TipXDCX { get; set; } - public long TIPXDCXMinerDisable { get; set; } - public long? DynamicGasLimitBlock { get; set; } + public ulong BlackListHFNumber { get; set; } + public ulong TipXDCX { get; set; } + public ulong TIPXDCXMinerDisable { get; set; } + public ulong? DynamicGasLimitBlock { get; set; } private readonly struct V2ConfigBySwitchRoundComparer : IComparer { @@ -82,9 +83,9 @@ private static void CheckConfig(ReadOnlySpan list) } } - public void ApplyToReleaseSpec(ReleaseSpec spec, long startBlock, ulong? startTimestamp) => spec.BaseFeeCalculator = new XdcBaseFeeCalculator(); + public void ApplyToReleaseSpec(ReleaseSpec spec, ulong startBlock, ulong? startTimestamp) => spec.BaseFeeCalculator = new XdcBaseFeeCalculator(); - public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) + public void AddTransitions(SortedSet blockNumbers, SortedSet timestamps) { if (TipTrc21Fee is not null) blockNumbers.Add(TipTrc21Fee.Value); diff --git a/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs b/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs index a92dcebb98bc..f7047a0e6ff2 100644 --- a/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs @@ -13,11 +13,11 @@ namespace Nethermind.Xdc.Spec; public class XdcReleaseSpec : ReleaseSpec, IXdcReleaseSpec { - public int EpochLength { get; set; } - public int Gap { get; set; } - public long Reward { get; set; } - public int SwitchEpoch { get; set; } - public long SwitchBlock { get; set; } + public ulong EpochLength { get; set; } + public ulong Gap { get; set; } + public ulong Reward { get; set; } + public ulong SwitchEpoch { get; set; } + public ulong SwitchBlock { get; set; } public int MaxMasternodes { get; set; } // v2 max masternodes public int MaxProtectorNodes { get; set; } // v2 max ProtectorNodes public int MaxObserverNodes { get; set; } // v2 max ObserverNodes @@ -25,18 +25,18 @@ public class XdcReleaseSpec : ReleaseSpec, IXdcReleaseSpec public int MinePeriod { get; set; } // Miner mine period to mine a block public int TimeoutSyncThreshold { get; set; } // send syncInfo after number of timeout public int TimeoutPeriod { get; set; } // Duration in ms - public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate + public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate public UInt256 MasternodeReward { get; set; } // Block reward per masternode (core validator) in Wei public UInt256 ProtectorReward { get; set; } // Block reward per protector in Wei public UInt256 ObserverReward { get; set; } // Block reward per observer in Wei public int MinimumMinerBlockPerEpoch { get; set; } // Minimum block per epoch for a miner to not be penalized - public long LimitPenaltyEpoch { get; set; } // Epochs in a row that a penalty node needs to be penalized - public long LimitPenaltyEpochV2 { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong LimitPenaltyEpoch { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong LimitPenaltyEpochV2 { get; set; } // Epochs in a row that a penalty node needs to be penalized public int MinimumSigningTx { get; set; } // Signing txs that a node needs to produce to get out of penalty, after `LimitPenaltyEpoch` public List V2Configs { get; set; } = []; public Address[] GenesisMasterNodes { get; set; } - public long MergeSignRange { get; set; } + public ulong MergeSignRange { get; set; } public HashSet
BlackListedAddresses { get; set; } public Address BlockSignerContract { get; set; } public Address RandomizeSMCBinary { get; set; } @@ -44,7 +44,7 @@ public class XdcReleaseSpec : ReleaseSpec, IXdcReleaseSpec public Address XDCXLendingAddressBinary { get; set; } public Address XDCXAddressBinary { get; set; } public Address TradingStateAddressBinary { get; set; } - public long TIP2019Block { get; set; } + public ulong TIP2019Block { get; set; } public Address FoundationWallet { get; set; } public Address MasternodeVotingContract { get; set; } public bool IsTipUpgradeRewardEnabled { get; set; } @@ -101,31 +101,30 @@ public static XdcReleaseSpec FromReleaseSpec(IReleaseSpec spec) public interface IXdcReleaseSpec : IReleaseSpec { - public int EpochLength { get; } - public int Gap { get; } - public long Reward { get; } - public int SwitchEpoch { get; set; } - public long SwitchBlock { get; set; } - public int MaxMasternodes { get; set; } // v2 max masternodes - public int MaxProtectorNodes { get; set; } // v2 max ProtectorNodes - public int MaxObserverNodes { get; set; } // v2 max ObserverNodes - public ulong SwitchRound { get; set; } // v1 to v2 switch block number - public int MinePeriod { get; set; } // Miner mine period to mine a block - public int TimeoutSyncThreshold { get; set; } // send syncInfo after number of timeout - public int TimeoutPeriod { get; set; } // Duration in ms - public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate - public UInt256 MasternodeReward { get; set; } // Block reward per masternode (core validator) in Wei - public UInt256 ProtectorReward { get; set; } // Block reward per protector in Wei - public UInt256 ObserverReward { get; set; } // Block reward per observer in Wei + public ulong EpochLength { get; } + public ulong Gap { get; } + public ulong Reward { get; } + public ulong SwitchEpoch { get; set; } + public ulong SwitchBlock { get; set; } + public int MaxMasternodes { get; set; } // v2 max masternodes + public int MaxProtectorNodes { get; set; } // v2 max ProtectorNodes + public int MaxObserverNodes { get; set; } // v2 max ObserverNodes + public ulong SwitchRound { get; set; } // v1 to v2 switch block number + public int MinePeriod { get; set; } // Miner mine period to mine a block + public int TimeoutSyncThreshold { get; set; } // send syncInfo after number of timeout + public int TimeoutPeriod { get; set; } // Duration in ms + public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate + public UInt256 MasternodeReward { get; set; } // Block reward per masternode (core validator) in Wei + public UInt256 ProtectorReward { get; set; } // Block reward per protector in Wei + public UInt256 ObserverReward { get; set; } // Block reward per observer in Wei public int MinimumMinerBlockPerEpoch { get; set; } // Minimum block per epoch for a miner to not be penalized - public long LimitPenaltyEpoch { get; set; } // Epochs in a row that a penalty node needs to be penalized - public long LimitPenaltyEpochV2 { get; set; } // Epochs in a row that a penalty node needs to be penalized - public ulong RangeReturnSigner { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong LimitPenaltyEpoch { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong LimitPenaltyEpochV2 { get; set; } // Epochs in a row that a penalty node needs to be penalized + public ulong RangeReturnSigner { get; set; } public int MinimumSigningTx { get; set; } // Signing txs that a node needs to produce to get out of penalty, after `LimitPenaltyEpoch` public List V2Configs { get; set; } public Address[] GenesisMasterNodes { get; set; } - public long MergeSignRange { get; set; } - + public ulong MergeSignRange { get; set; } public Address BlockSignerContract { get; set; } public Address RandomizeSMCBinary { get; set; } public Address XDCXLendingFinalizedTradeAddressBinary { get; set; } @@ -142,5 +141,6 @@ public interface IXdcReleaseSpec : IReleaseSpec public bool IsTIPXDCXMiner { get; set; } public bool IsTipUpgradePenaltyEnabled { get; set; } public bool IsDynamicGasLimitBlock { get; set; } + public ulong TIP2019Block { get; set; } public void ApplyV2Config(ulong round); } diff --git a/src/Nethermind/Nethermind.Xdc/SubnetEpochSwitchManager.cs b/src/Nethermind/Nethermind.Xdc/SubnetEpochSwitchManager.cs index 18cedf4cc850..f364339cea34 100644 --- a/src/Nethermind/Nethermind.Xdc/SubnetEpochSwitchManager.cs +++ b/src/Nethermind/Nethermind.Xdc/SubnetEpochSwitchManager.cs @@ -30,7 +30,7 @@ public override bool IsEpochSwitchAtRound(ulong currentRound, XdcBlockHeader par } protected override ulong GetCurrentEpochNumber(EpochSwitchInfo epochSwitchInfo, IXdcReleaseSpec xdcSpec) => - (ulong)(epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber / xdcSpec.EpochLength); + epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber / xdcSpec.EpochLength; protected override Address[] ResolvePenalties(XdcBlockHeader _, Snapshot snapshot) { @@ -47,8 +47,8 @@ protected override Address[] ResolvePenalties(XdcBlockHeader _, Snapshot snapsho IXdcReleaseSpec xdcSpec = XdcSpecProvider.GetXdcSpec(headHeader); - if (targetEpoch > (ulong)(long.MaxValue / xdcSpec.EpochLength)) return null; - long targetNumber = (long)targetEpoch * xdcSpec.EpochLength; + if (targetEpoch > long.MaxValue / xdcSpec.EpochLength) return null; + ulong targetNumber = targetEpoch * xdcSpec.EpochLength; XdcBlockHeader? targetHeader = (XdcBlockHeader?)Tree.FindHeader(targetNumber); if (targetHeader is null) return null; diff --git a/src/Nethermind/Nethermind.Xdc/SubnetMasternodesCalculator.cs b/src/Nethermind/Nethermind.Xdc/SubnetMasternodesCalculator.cs index ab519ce2a36b..1815f0e8e80d 100644 --- a/src/Nethermind/Nethermind.Xdc/SubnetMasternodesCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/SubnetMasternodesCalculator.cs @@ -12,7 +12,7 @@ namespace Nethermind.Xdc; internal class SubnetMasternodesCalculator(ISubnetSnapshotManager snapshotManager) : ISubnetMasternodesCalculator { - public (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(long blockNumber, Hash256 parentHash, IXdcReleaseSpec spec) + public (Address[] Masternodes, Address[] PenalizedNodes) CalculateNextEpochMasternodes(ulong blockNumber, Hash256 parentHash, IXdcReleaseSpec spec) { if (snapshotManager.GetSnapshotByBlockNumber(blockNumber, spec) is not SubnetSnapshot previousSnapshot) throw new InvalidOperationException($"No snapshot found for header #{blockNumber}"); diff --git a/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs b/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs index 15194e9be2a3..c680bded2a49 100644 --- a/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs +++ b/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs @@ -13,7 +13,7 @@ namespace Nethermind.Xdc; internal class SubnetPenaltyHandler(IBlockTree tree, ISpecProvider specProvider, IEpochSwitchManager epochSwitchManager, ISigningTxCache signingTxCache) : IPenaltyHandler { - public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] candidates) + public Address[] HandlePenalties(ulong number, Hash256 parentHash, Address[] candidates) { // Triggered only at gap blocks XdcSubnetBlockHeader header = tree.FindHeader(parentHash, number - 1) as XdcSubnetBlockHeader @@ -24,13 +24,13 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand List listBlockHash = []; - List listBlockNumber = []; + List listBlockNumber = []; Dictionary minerStatistics = []; - long parentNumber = number - 1; - long minBlockNumber = Math.Max(1, number - currentSpec.EpochLength); + ulong parentNumber = number - 1; + ulong minBlockNumber = Math.Max(1UL, number - currentSpec.EpochLength); while (true) { @@ -73,10 +73,10 @@ public Address[] HandlePenalties(long number, Hash256 parentHash, Address[] cand HashSet blockHashes = []; - long startRange = Math.Max(number - (long)currentSpec.RangeReturnSigner + 1, 0); + ulong startRange = Math.Max(number - currentSpec.RangeReturnSigner + 1, 0); for (int i = listBlockNumber.Count - 1; i >= 0; i--) { - long blockNumber = listBlockNumber[i]; + ulong blockNumber = listBlockNumber[i]; Hash256 blockHash = listBlockHash[i]; if (blockNumber < startRange) diff --git a/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs b/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs index 4a99f8df8af2..abedd056668c 100644 --- a/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs +++ b/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs @@ -5,7 +5,6 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Logging; using Nethermind.Serialization.Rlp; @@ -13,6 +12,7 @@ using Nethermind.Xdc.Errors; using Nethermind.Xdc.P2P; using Nethermind.Xdc.RLP; +using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Types; using System; @@ -141,7 +141,7 @@ public bool VerifyTimeoutCertificate(TimeoutCertificate timeoutCertificate, [Not ArgumentNullException.ThrowIfNull(timeoutCertificate); if (timeoutCertificate.Signatures is null) throw new ArgumentNullException(nameof(timeoutCertificate.Signatures)); - Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber((long)timeoutCertificate.GapNumber); + Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber(timeoutCertificate.GapNumber); if (snapshot is null) { errorMessage = $"Failed to get snapshot using gap number {timeoutCertificate.GapNumber}"; @@ -225,9 +225,15 @@ public Task OnReceiveTimeout(Timeout timeout) { Block currentBlock = _blockTree.Head ?? throw new InvalidOperationException("Failed to get current block"); XdcBlockHeader currentHeader = currentBlock.Header as XdcBlockHeader; - long currentBlockNumber = currentBlock.Number; - int epochLength = _specProvider.GetXdcSpec(currentHeader, timeout.Round).EpochLength; - if (Math.Abs((long)timeout.GapNumber - currentBlockNumber) > 3 * epochLength) + ulong currentBlockNumber = currentBlock.Number; + ulong epochLength = _specProvider.GetXdcSpec(currentHeader, timeout.Round).EpochLength; + + // Math.Abs has no ulong overload; compute absolute difference without risk of underflow. + ulong gapDiff = timeout.GapNumber > currentBlockNumber + ? timeout.GapNumber - currentBlockNumber + : currentBlockNumber - timeout.GapNumber; + + if (gapDiff > 3 * epochLength) { // Discarded propagated timeout, too far away return Task.CompletedTask; @@ -244,7 +250,7 @@ public Task OnReceiveTimeout(Timeout timeout) internal bool FilterTimeout(Timeout timeout) { if (timeout.Round < _consensusContext.CurrentRound) return false; - Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber((long)timeout.GapNumber); + Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber(timeout.GapNumber); if (snapshot is null || snapshot.NextEpochCandidates.Length == 0) return false; // Verify msg signature @@ -259,31 +265,36 @@ internal bool FilterTimeout(Timeout timeout) private void SendTimeout() { - long gapNumber = 0; XdcBlockHeader currentHeader = (XdcBlockHeader)_blockTree.Head?.Header ?? throw new InvalidOperationException("Failed to retrieve current header"); ulong currentRound = _consensusContext.CurrentRound; IXdcReleaseSpec spec = _specProvider.GetXdcSpec(currentHeader, currentRound); + + ulong gapNumber; if (_epochSwitchManager.IsEpochSwitchAtRound(currentRound, currentHeader)) { - long currentNumber = currentHeader.Number + 1; - gapNumber = Math.Max(0, currentNumber - currentNumber % spec.EpochLength - spec.Gap); + ulong currentNumber = currentHeader.Number + 1; + ulong offset = currentNumber % spec.EpochLength + spec.Gap; + // Guard against underflow: if currentNumber is less than the offset, gap is 0. + gapNumber = currentNumber > offset ? currentNumber - offset : 0UL; } else { EpochSwitchInfo epochSwitchInfo = _epochSwitchManager.GetEpochSwitchInfo(currentHeader) ?? throw new DataExtractionException(nameof(EpochSwitchInfo)); - long currentNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - gapNumber = Math.Max(0, currentNumber - currentNumber % spec.EpochLength - spec.Gap); + ulong currentNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong offset = currentNumber % spec.EpochLength + spec.Gap; + // Guard against underflow: if currentNumber is less than the offset, gap is 0. + gapNumber = currentNumber > offset ? currentNumber - offset : 0UL; } - ValueHash256 msgHash = ComputeTimeoutMsgHash(currentRound, (ulong)gapNumber); + ValueHash256 msgHash = ComputeTimeoutMsgHash(currentRound, gapNumber); if (!_signer.TrySign(in msgHash, out Signature signedHash)) { if (_logger.IsWarn) _logger.Warn($"XDC signer {_signer.Address} could not sign timeout for round {currentRound} — skipping broadcast."); return; } - Timeout timeoutMsg = new(currentRound, signedHash, (ulong)gapNumber, isMyVote: true); + Timeout timeoutMsg = new(currentRound, signedHash, gapNumber, isMyVote: true); timeoutMsg.Signer = _signer.Address; HandleTimeoutVote(timeoutMsg); @@ -308,5 +319,4 @@ internal static ValueHash256 ComputeTimeoutMsgHash(ulong round, ulong gap) } public long GetTimeoutsCount(Timeout timeout) => _timeouts.GetCount(timeout); - } diff --git a/src/Nethermind/Nethermind.Xdc/TxPool/SignTransactionFilter.cs b/src/Nethermind/Nethermind.Xdc/TxPool/SignTransactionFilter.cs index cccea3c1688d..b071fc91f12c 100644 --- a/src/Nethermind/Nethermind.Xdc/TxPool/SignTransactionFilter.cs +++ b/src/Nethermind/Nethermind.Xdc/TxPool/SignTransactionFilter.cs @@ -3,10 +3,10 @@ using Nethermind.Blockchain; using Nethermind.Core; -using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.TxPool; using Nethermind.TxPool.Filters; +using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Types; using System; @@ -15,7 +15,7 @@ namespace Nethermind.Xdc.TxPool; internal sealed class SignTransactionFilter(ISnapshotManager snapshotManager, IBlockTree blockTree, ISpecProvider specProvider) : IIncomingTxFilter { - private AcceptTxResult ValidateSignTransaction(Transaction tx, long headerNumber, IXdcReleaseSpec xdcSpec) + private AcceptTxResult ValidateSignTransaction(Transaction tx, ulong headerNumber, IXdcReleaseSpec xdcSpec) { if (tx.Data.Length < XdcConstants.SignTransactionDataLength) { @@ -23,7 +23,13 @@ private AcceptTxResult ValidateSignTransaction(Transaction tx, long headerNumber } UInt256 blkNumber = new(tx.Data.Span.Slice(4, 32), true); - if (blkNumber > headerNumber || blkNumber <= (headerNumber - (xdcSpec.EpochLength * 2))) + + // Compute the lower bound defensively: if headerNumber < EpochLength * 2, the + // subtraction would underflow ulong, so treat the lower bound as 0 in that case. + ulong epochWindow = xdcSpec.EpochLength * 2; + UInt256 lowerBound = headerNumber > epochWindow ? headerNumber - epochWindow : UInt256.Zero; + + if (blkNumber > headerNumber || blkNumber <= lowerBound) { // Invalid block number in special transaction data return AcceptTxResult.Invalid.WithMessage("Sign transaction block number is out of range"); @@ -38,7 +44,7 @@ public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandl return AcceptTxResult.Syncing; XdcBlockHeader header = (XdcBlockHeader)blockTree.Head.Header; - long headerNumber = header.Number + 1; + ulong headerNumber = header.Number + 1; IXdcReleaseSpec spec = specProvider.GetXdcSpec(headerNumber); if (!tx.IsSpecialTransaction(spec)) diff --git a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTransactionComparerProvider.cs b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTransactionComparerProvider.cs index 364ee86cf75d..c64b57306860 100644 --- a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTransactionComparerProvider.cs +++ b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTransactionComparerProvider.cs @@ -5,8 +5,8 @@ using Nethermind.Consensus; using Nethermind.Consensus.Comparers; using Nethermind.Core; -using Nethermind.Core.Specs; using Nethermind.TxPool.Comparison; +using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; using System.Collections.Generic; @@ -14,11 +14,6 @@ namespace Nethermind.Xdc.TxPool; internal class CompareTxBySender(IXdcReleaseSpec spec) : IComparer { - public CompareTxBySender(ISpecProvider specProvider) - : this((IXdcReleaseSpec)specProvider.GetFinalSpec()) - { - } - public int Compare(Transaction? newTx, Transaction? oldTx) { if (ReferenceEquals(newTx, oldTx)) return TxComparisonResult.NotDecided; @@ -45,7 +40,8 @@ public IComparer GetDefaultComparer() { IComparer defaultComparer = defaultComparerProvider.GetDefaultComparer(); - CompareTxBySender signerFilter = new(specProvider); + IXdcReleaseSpec finalSpec = specProvider.GetXdcSpec(ulong.MaxValue - 1); + CompareTxBySender signerFilter = new(finalSpec); return signerFilter.ThenBy(defaultComparer); } @@ -54,8 +50,7 @@ public IComparer GetDefaultProducerComparer(BlockPreparationContext { IComparer defaultComparer = defaultComparerProvider.GetDefaultProducerComparer(blockPreparationContext); - IXdcReleaseSpec currentSpec = specProvider.GetXdcSpec(blockPreparationContext.BlockNumber); - + IXdcReleaseSpec currentSpec = specProvider.GetXdcSpec(blockPreparationContext.BlockNumber, round: 0); CompareTxBySender signerFilter = new(currentSpec); return signerFilter.ThenBy(defaultComparer); diff --git a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxGossipPolicy.cs b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxGossipPolicy.cs index 298c9967b637..8e112f221f5e 100644 --- a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxGossipPolicy.cs +++ b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxGossipPolicy.cs @@ -2,17 +2,17 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; -using Nethermind.Core.Specs; using Nethermind.TxPool; +using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; namespace Nethermind.Xdc.TxPool; -internal class XdcTxGossipPolicy(ISpecProvider provider, IChainHeadInfoProvider chainHeadInfoProvider) : ITxGossipPolicy +internal class XdcTxGossipPolicy(ISpecProvider specProvider, IChainHeadInfoProvider chainHeadInfoProvider) : ITxGossipPolicy { public bool ShouldGossipTransaction(Transaction tx) { - IXdcReleaseSpec spec = (IXdcReleaseSpec)provider.GetXdcSpec(chainHeadInfoProvider.HeadNumber); + IXdcReleaseSpec spec = specProvider.GetXdcSpec(chainHeadInfoProvider.HeadNumber); if (!tx.RequiresSpecialHandling(spec)) return true; diff --git a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs index 520f958424fd..219776050277 100644 --- a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs +++ b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs @@ -5,9 +5,10 @@ using Nethermind.Config; using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; -using Nethermind.Core.Specs; using Nethermind.Logging; using Nethermind.TxPool; +using Nethermind.Core.Specs; +using Nethermind.Xdc.Spec; namespace Nethermind.Xdc.TxPool; diff --git a/src/Nethermind/Nethermind.Xdc/Types/BlockRoundInfo.cs b/src/Nethermind/Nethermind.Xdc/Types/BlockRoundInfo.cs index 76f24fe24efa..0a03db1aa7e1 100644 --- a/src/Nethermind/Nethermind.Xdc/Types/BlockRoundInfo.cs +++ b/src/Nethermind/Nethermind.Xdc/Types/BlockRoundInfo.cs @@ -6,10 +6,10 @@ namespace Nethermind.Xdc.Types; -public class BlockRoundInfo(Hash256 hash256, ulong round, long number) +public class BlockRoundInfo(Hash256 hash256, ulong round, ulong number) { public Hash256 Hash { get; set; } = hash256; public ulong Round { get; set; } = round; - public long BlockNumber { get; set; } = number; + public ulong BlockNumber { get; set; } = number; public Hash256 SigHash() => Keccak.Compute(Rlp.Encode(this).Bytes); } diff --git a/src/Nethermind/Nethermind.Xdc/Types/Forensics.cs b/src/Nethermind/Nethermind.Xdc/Types/Forensics.cs index 97acdb80f899..919fc3dfc4a1 100644 --- a/src/Nethermind/Nethermind.Xdc/Types/Forensics.cs +++ b/src/Nethermind/Nethermind.Xdc/Types/Forensics.cs @@ -16,7 +16,7 @@ public class ForensicsInfo public class ForensicsContent { - public long DivergingBlockNumber { get; set; } + public ulong DivergingBlockNumber { get; set; } public string DivergingBlockHash { get; set; } = string.Empty; public bool AcrossEpoch { get; set; } public ForensicsInfo SmallerRoundInfo { get; set; } = null!; diff --git a/src/Nethermind/Nethermind.Xdc/Types/Snapshot.cs b/src/Nethermind/Nethermind.Xdc/Types/Snapshot.cs index 9b1f3cc1c42a..3fc7ab4095d9 100644 --- a/src/Nethermind/Nethermind.Xdc/Types/Snapshot.cs +++ b/src/Nethermind/Nethermind.Xdc/Types/Snapshot.cs @@ -6,9 +6,9 @@ namespace Nethermind.Xdc.Types; -public class Snapshot(long number, Hash256 hash, Address[] masterNodes) +public class Snapshot(ulong number, Hash256 hash, Address[] masterNodes) { - public long BlockNumber { get; set; } = number; + public ulong BlockNumber { get; set; } = number; public Hash256 HeaderHash { get; set; } = hash; public Address[] NextEpochCandidates { get; set; } = masterNodes; } diff --git a/src/Nethermind/Nethermind.Xdc/Types/SubnetSnapshot.cs b/src/Nethermind/Nethermind.Xdc/Types/SubnetSnapshot.cs index e6fef9cb1c45..694984e7f065 100644 --- a/src/Nethermind/Nethermind.Xdc/Types/SubnetSnapshot.cs +++ b/src/Nethermind/Nethermind.Xdc/Types/SubnetSnapshot.cs @@ -10,7 +10,7 @@ public class SubnetSnapshot : Snapshot { public Address[] NextEpochPenalties { get; set; } - public SubnetSnapshot(long number, Hash256 hash, Address[] validators) : base(number, hash, validators) => NextEpochPenalties = []; + public SubnetSnapshot(ulong number, Hash256 hash, Address[] validators) : base(number, hash, validators) => NextEpochPenalties = []; - public SubnetSnapshot(long number, Hash256 hash, Address[] validators, Address[] penalties) : base(number, hash, validators) => NextEpochPenalties = penalties ?? []; + public SubnetSnapshot(ulong number, Hash256 hash, Address[] validators, Address[] penalties) : base(number, hash, validators) => NextEpochPenalties = penalties ?? []; } diff --git a/src/Nethermind/Nethermind.Xdc/VotesManager.cs b/src/Nethermind/Nethermind.Xdc/VotesManager.cs index 114042e98b42..91177a6a70a5 100644 --- a/src/Nethermind/Nethermind.Xdc/VotesManager.cs +++ b/src/Nethermind/Nethermind.Xdc/VotesManager.cs @@ -5,12 +5,12 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Logging; using Nethermind.Serialization.Rlp; using Nethermind.Synchronization.Peers; using Nethermind.Xdc.P2P; +using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Types; using System; @@ -54,22 +54,34 @@ internal class VotesManager( private static readonly EthereumEcdsa _ethereumEcdsa = new(0); private readonly ConcurrentDictionary _qcBuildStartedByRound = new(); private const int _maxBlockDistance = 7; // Maximum allowed backward distance from the chain head - private long _highestVotedRound = -1; + + // null means "never voted"; ulong.MaxValue is a valid round so null is the correct sentinel. + private ulong? _highestVotedRound = null; public Task CastVote(BlockRoundInfo blockInfo) { EpochSwitchInfo epochSwitchInfo = _epochSwitchManager.GetEpochSwitchInfo(blockInfo.Hash) ?? throw new ArgumentException($"Cannot find epoch info for block {blockInfo.Hash}", nameof(blockInfo)); - //Optimize this by fetching with block number and round only if (_blockTree.FindHeader(blockInfo.Hash) is not XdcBlockHeader header) throw new ArgumentException($"Cannot find block header for block {blockInfo.Hash}"); IXdcReleaseSpec spec = _specProvider.GetXdcSpec(header, blockInfo.Round); - long epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - long gapNumber = epochSwitchNumber == 0 ? 0 : Math.Max(0, epochSwitchNumber - epochSwitchNumber % spec.EpochLength - spec.Gap); + ulong epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - Vote vote = new(blockInfo, (ulong)gapNumber, isMyVote: true); + ulong gapNumber; + if (epochSwitchNumber == 0) + { + gapNumber = 0; + } + else + { + ulong offset = epochSwitchNumber % spec.EpochLength + spec.Gap; + // Guard against underflow: if epochSwitchNumber is less than the offset, gap is 0. + gapNumber = epochSwitchNumber > offset ? epochSwitchNumber - offset : 0UL; + } + + Vote vote = new(blockInfo, gapNumber, isMyVote: true); // Sets signature and signer for the vote if (!TrySign(vote)) { @@ -77,7 +89,7 @@ public Task CastVote(BlockRoundInfo blockInfo) return Task.CompletedTask; } - _highestVotedRound = (long)blockInfo.Round; + _highestVotedRound = blockInfo.Round; HandleVote(vote); return Task.CompletedTask; @@ -157,11 +169,12 @@ public bool VerifyVotingRules(BlockRoundInfo roundInfo, QuorumCertificate qc, ou public bool VerifyVotingRules(XdcBlockHeader header, [NotNullWhen(false)] out string? error) => VerifyVotingRules(header.Hash, header.Number, header.ExtraConsensusData.BlockRound, header.ExtraConsensusData.QuorumCert, out error); - public bool VerifyVotingRules(Hash256 blockHash, long blockNumber, ulong roundNumber, QuorumCertificate qc, out string? error) + public bool VerifyVotingRules(Hash256 blockHash, ulong blockNumber, ulong roundNumber, QuorumCertificate qc, out string? error) { - if ((long)_ctx.CurrentRound <= _highestVotedRound) + // _highestVotedRound is null until a vote is cast; once set, any round <= it is rejected. + if (_highestVotedRound.HasValue && _ctx.CurrentRound <= _highestVotedRound.Value) { - error = $"Already voted at round {_highestVotedRound}, current round {_ctx.CurrentRound}"; + error = $"Already voted at round {_highestVotedRound.Value}, current round {_ctx.CurrentRound}"; return false; } @@ -198,9 +211,15 @@ public bool VerifyVotingRules(Hash256 blockHash, long blockNumber, ulong roundNu public Task OnReceiveVote(Vote vote) { - long voteBlockNumber = vote.ProposedBlockInfo.BlockNumber; - long currentBlockNumber = _blockTree.Head?.Number ?? throw new InvalidOperationException("Failed to get current block number"); - if (Math.Abs(voteBlockNumber - currentBlockNumber) > _maxBlockDistance) + ulong voteBlockNumber = vote.ProposedBlockInfo.BlockNumber; + ulong currentBlockNumber = _blockTree.Head?.Number ?? throw new InvalidOperationException("Failed to get current block number"); + + // Math.Abs has no ulong overload; compute absolute difference without risk of underflow. + ulong blockDiff = voteBlockNumber > currentBlockNumber + ? voteBlockNumber - currentBlockNumber + : currentBlockNumber - voteBlockNumber; + + if (blockDiff > _maxBlockDistance) { // Discarded propagated vote, too far away return Task.CompletedTask; @@ -208,7 +227,6 @@ public Task OnReceiveVote(Vote vote) if (FilterVote(vote)) { - return HandleVote(vote); } return Task.CompletedTask; @@ -218,7 +236,7 @@ internal bool FilterVote(Vote vote) { if (vote.ProposedBlockInfo.Round < _ctx.CurrentRound) return false; - Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber((long)vote.GapNumber); + Snapshot snapshot = _snapshotManager.GetSnapshotByGapNumber(vote.GapNumber); if (snapshot is null) return false; // Verify message signature vote.Signer ??= _ethereumEcdsa.RecoverVoteSigner(vote); @@ -241,12 +259,19 @@ private void OnVotePoolThresholdReached(Signature[] validSignatures, Vote currVo CleanupVotes(currVote.ProposedBlockInfo.Round); } - private bool IsExtendingFromAncestor(Hash256 blockHash, long blockNumber, BlockRoundInfo ancestorBlockInfo) + private bool IsExtendingFromAncestor(Hash256 blockHash, ulong blockNumber, BlockRoundInfo ancestorBlockInfo) { - long blockNumDiff = blockNumber - ancestorBlockInfo.BlockNumber; + // blockNumber >= ancestorBlockInfo.BlockNumber is expected; if not, the block cannot + // extend the ancestor and we return false rather than underflowing. + if (blockNumber < ancestorBlockInfo.BlockNumber) + return false; + + ulong blockNumDiff = blockNumber - ancestorBlockInfo.BlockNumber; Hash256 nextBlockHash = blockHash; - for (int i = 0; i < blockNumDiff; i++) + // blockNumDiff is bounded by _maxBlockDistance in practice, so casting to int for + // the loop counter is safe (ulong diff that exceeds int.MaxValue would be a chain error). + for (ulong i = 0; i < blockNumDiff; i++) { if (_blockTree.FindHeader(nextBlockHash) is not XdcBlockHeader parentHeader) return false; diff --git a/src/Nethermind/Nethermind.Xdc/XdcBeaconSyncStrategy.cs b/src/Nethermind/Nethermind.Xdc/XdcBeaconSyncStrategy.cs index 53602ed1b9d0..38657e23dfe5 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcBeaconSyncStrategy.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcBeaconSyncStrategy.cs @@ -22,7 +22,7 @@ public void AllowBeaconHeaderSync() { } public bool MergeTransitionFinished => false; - public long? GetTargetBlockHeight() => _syncConfig.PivotNumber > 0 ? _syncConfig.PivotNumber : null; + public ulong? GetTargetBlockHeight() => _syncConfig.PivotNumber > 0 ? _syncConfig.PivotNumber : null; public Hash256? GetFinalizedHash() => null; diff --git a/src/Nethermind/Nethermind.Xdc/XdcBlockHeader.cs b/src/Nethermind/Nethermind.Xdc/XdcBlockHeader.cs index 89fcd1589515..adaf13b9419c 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcBlockHeader.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcBlockHeader.cs @@ -18,8 +18,8 @@ public class XdcBlockHeader( Hash256 unclesHash, Address beneficiary, in UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[] extraData, bool isSelfMined = false diff --git a/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs b/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs index 1de876de1fd0..05df11a4de18 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs @@ -63,7 +63,7 @@ protected override BlockHeader PrepareBlockHeader(BlockHeader parent, PayloadAtt byte[] extra = [XdcConstants.ConsensusVersion, .. _extraConsensusDataDecoder.Encode(new ExtraFieldsV2(currentRound, highestCert)).Bytes]; Address blockAuthor = sealer.Address; - long gasLimit = GasLimitCalculator.GetGasLimit(parent); + ulong gasLimit = GasLimitCalculator.GetGasLimit(parent); XdcBlockHeader xdcBlockHeader = CreateHeader(parent, extra, blockAuthor, gasLimit); IXdcReleaseSpec spec = specProvider.GetXdcSpec(xdcBlockHeader, currentRound); @@ -109,7 +109,7 @@ protected override BlockToProduce PrepareBlock(BlockHeader parent, PayloadAttrib return new BlockToProduce(header, transactions, Array.Empty(), payloadAttributes?.Withdrawals); } - protected virtual XdcBlockHeader CreateHeader(BlockHeader parent, byte[] extra, Address blockAuthor, long gasLimit) => new( + protected virtual XdcBlockHeader CreateHeader(BlockHeader parent, byte[] extra, Address blockAuthor, ulong gasLimit) => new( parent.Hash!, Keccak.OfAnEmptySequenceRlp, blockAuthor, diff --git a/src/Nethermind/Nethermind.Xdc/XdcBlockTree.cs b/src/Nethermind/Nethermind.Xdc/XdcBlockTree.cs index b08f33ef3150..ca05a12c8744 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcBlockTree.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcBlockTree.cs @@ -30,7 +30,7 @@ internal class XdcBlockTree( IBloomStorage? bloomStorage, ISyncConfig? syncConfig, ILogManager? logManager, - long genesisBlockNumber = 0) : BlockTree(blockStore, headerDb, blockInfoDb, metadataDb, badBlockStore, balStore, chainLevelInfoRepository, specProvider, bloomStorage, syncConfig, logManager, genesisBlockNumber) + ulong genesisBlockNumber = 0) : BlockTree(blockStore, headerDb, blockInfoDb, metadataDb, badBlockStore, balStore, chainLevelInfoRepository, specProvider, bloomStorage, syncConfig, logManager, genesisBlockNumber) { private readonly IXdcConsensusContext _xdcConsensus = xdcConsensus; @@ -52,7 +52,7 @@ protected override AddBlockResult Suggest(Block? block, BlockHeader header, Bloc } BlockHeader current = header; - for (long i = header.Number; i >= finalizedBlockInfo.BlockNumber; i--) + for (ulong i = header.Number; i >= finalizedBlockInfo.BlockNumber; i--) { if (finalizedBlockInfo.BlockNumber >= current.Number) return AddBlockResult.InvalidBlock; diff --git a/src/Nethermind/Nethermind.Xdc/XdcExtensions.cs b/src/Nethermind/Nethermind.Xdc/XdcExtensions.cs index d83b20653578..d7342224f6f6 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcExtensions.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcExtensions.cs @@ -19,11 +19,13 @@ internal static partial class XdcExtensions //TODO can we wire up this so we can use Rlp.Encode()? private static readonly XdcHeaderDecoder _headerDecoder = new(); private static readonly VoteDecoder _voteDecoder = new(); + public static Signature Sign(this IEthereumEcdsa ecdsa, PrivateKey privateKey, XdcBlockHeader header) { ValueHash256 hash = ValueKeccak.Compute(_headerDecoder.Encode(header, RlpBehaviors.ForSealing).Bytes); return ecdsa.Sign(privateKey, in hash); } + public static Address RecoverVoteSigner(this IEthereumEcdsa ecdsa, Vote vote) { KeccakRlpStream stream = new(); @@ -42,7 +44,7 @@ public static IXdcReleaseSpec GetXdcSpec(this ISpecProvider specProvider, XdcBlo return specProvider.GetXdcSpec(xdcBlockHeader.Number, round); } - public static IXdcReleaseSpec GetXdcSpec(this ISpecProvider specProvider, long blockNumber, ulong round = 0) + public static IXdcReleaseSpec GetXdcSpec(this ISpecProvider specProvider, ulong blockNumber, ulong round = 0) { if (specProvider is XdcChainSpecBasedSpecProvider xdcProvider) return xdcProvider.GetXdcSpec(blockNumber, round); @@ -106,6 +108,10 @@ public static bool IsGapPlusOne(this XdcSubnetBlockHeader header, IXdcReleaseSpe { if (header.Number == 1) return true; + // Guard against underflow: Gap should always be < EpochLength by configuration, + // but we check explicitly rather than relying on that invariant holding at runtime. + if (spec.Gap == 0 || spec.EpochLength <= spec.Gap) + return false; return (header.Number % spec.EpochLength) == (spec.EpochLength - spec.Gap + 1); } diff --git a/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs b/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs index a26413a092f0..464d42e28959 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs @@ -12,13 +12,13 @@ namespace Nethermind.Xdc; internal class XdcGasLimitCalculator(ISpecProvider specProvider, IBlocksConfig blocksConfig) : IGasLimitCalculator { private readonly TargetAdjustedGasLimitCalculator targetAdjustedGasLimitCalculator = new(specProvider, blocksConfig); - public long GetGasLimit(BlockHeader parentHeader) + public ulong GetGasLimit(BlockHeader parentHeader) { IXdcReleaseSpec spec = specProvider.GetXdcSpec(parentHeader.Number + 1); if (spec.IsDynamicGasLimitBlock) { return targetAdjustedGasLimitCalculator.GetGasLimit(parentHeader); } - return blocksConfig.TargetBlockGasLimit ?? XdcConstants.DefaultTargetGasLimit; + return (ulong)(blocksConfig.TargetBlockGasLimit ?? XdcConstants.DefaultTargetGasLimit); } } diff --git a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs index 93890198db91..eb4c1e24572f 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs @@ -377,7 +377,7 @@ public Address GetLeaderAddress(XdcBlockHeader currentHead, ulong round, IXdcRel currentMasternodes = epochSwitchInfo.Masternodes; } - int currentLeaderIndex = (int)round % spec.EpochLength % currentMasternodes.Length; + int currentLeaderIndex = (int)(round % spec.EpochLength % (ulong)currentMasternodes.Length); return currentMasternodes[currentLeaderIndex]; } diff --git a/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs b/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs index 9ebf81f4d309..a99ec5347034 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs @@ -61,7 +61,7 @@ public BlockReward[] CalculateRewards(Block block) // Rewards in XDC are calculated only if it's an epoch switch block if (!_epochSwitchManager.IsEpochSwitchAtBlock(xdcHeader)) return Array.Empty(); - long number = xdcHeader.Number; + ulong number = xdcHeader.Number; IXdcReleaseSpec spec = _specProvider.GetXdcSpec(xdcHeader, xdcHeader.ExtraConsensusData.BlockRound); if (number == spec.SwitchBlock + 1) return Array.Empty(); @@ -71,7 +71,7 @@ public BlockReward[] CalculateRewards(Block block) UInt256 totalFoundationWalletReward = UInt256.Zero; UInt256 totalMintedInEpoch = UInt256.Zero; List rewards = []; - (Dictionary masternodeSigners, Dictionary protectorSigners, Dictionary observerSigners, UInt256 burnedInOneEpoch) = GetSigningTxCount(xdcHeader, spec); + (Dictionary masternodeSigners, Dictionary protectorSigners, Dictionary observerSigners, UInt256 burnedInOneEpoch) = GetSigningTxCount(xdcHeader, spec); if (!spec.IsTipUpgradeRewardEnabled) { @@ -108,44 +108,48 @@ public BlockReward[] CalculateRewards(Block block) } private ( - Dictionary MasternodeSigners, - Dictionary ProtectorSigners, - Dictionary ObserverSigners, + Dictionary MasternodeSigners, + Dictionary ProtectorSigners, + Dictionary ObserverSigners, UInt256 BurnedInOneEpoch) GetSigningTxCount(XdcBlockHeader epochHeader, IXdcReleaseSpec spec) { - Dictionary masternodeSigners = []; - Dictionary protectorSigners = []; - Dictionary observerSigners = []; + Dictionary masternodeSigners = []; + Dictionary protectorSigners = []; + Dictionary observerSigners = []; UInt256 burnedInOneEpoch = UInt256.Zero; - long number = epochHeader.Number; + ulong number = epochHeader.Number; if (number == 0) return (masternodeSigners, protectorSigners, observerSigners, burnedInOneEpoch); - long signEpochCount = 1, rewardEpochCount = 2, epochCount = 0, endBlockNumber = 0, startBlockNumber = 0; + ulong signEpochCount = 1, rewardEpochCount = 2, epochCount = 0, endBlockNumber = 0, startBlockNumber = 0; - Dictionary blockNumberToHash = []; + Dictionary blockNumberToHash = []; Dictionary> hashToSigningAddress = []; HashSet
masternodes = []; HashSet
protectors = []; HashSet
observers = []; - long mergeSignRange = spec.MergeSignRange; + ulong mergeSignRange = spec.MergeSignRange; XdcBlockHeader h = epochHeader; - for (long i = number - 1; i >= 0; i--) + // Loop from (number - 1) down to block 0. The ulong loop variable cannot go below 0, + // so we use a while loop with a check at the end to prevent underflow. + ulong blockIdx = number - 1; + while (true) { Hash256 parentHash = h.ParentHash; - h = (XdcBlockHeader)_blockTree.FindHeader(parentHash!, i) ?? throw new InvalidOperationException($"Header with hash {parentHash} not found"); + h = (XdcBlockHeader)_blockTree.FindHeader(parentHash!, blockIdx) ?? throw new InvalidOperationException($"Header with hash {parentHash} not found"); if (epochCount == 0 && !h.BaseFeePerGas.IsZero) { + // h.GasUsed is ulong; widening cast to UInt256 is safe (no overflow possible). UInt256 burnedInBlock = h.BaseFeePerGas * (UInt256)h.GasUsed; burnedInOneEpoch += burnedInBlock; } if (_epochSwitchManager.IsEpochSwitchAtBlock(h) && h.Number != spec.SwitchBlock + 1) { epochCount++; - if (epochCount == signEpochCount) endBlockNumber = i; + if (epochCount == signEpochCount) endBlockNumber = blockIdx; if (epochCount == rewardEpochCount) { - startBlockNumber = i + 1; + startBlockNumber = blockIdx + 1; // Get masternodes from epoch switch header if (h.Number <= spec.SwitchBlock) masternodes = [.. h.ExtraData.ParseV1Masternodes()]; @@ -178,8 +182,8 @@ public BlockReward[] CalculateRewards(Block block) } } - blockNumberToHash[i] = h.Hash; - Transaction[] signingTxs = _signingTxCache.GetSigningTransactions(h.Hash, i, spec); + blockNumberToHash[blockIdx] = h.Hash; + Transaction[] signingTxs = _signingTxCache.GetSigningTransactions(h.Hash, blockIdx, spec); foreach (Transaction tx in signingTxs) { @@ -189,12 +193,15 @@ public BlockReward[] CalculateRewards(Block block) hashToSigningAddress[blockHash] = []; hashToSigningAddress[blockHash].Add(tx.SenderAddress); } + + if (blockIdx == 0) break; + blockIdx--; } // Only blocks at heights that are multiples of MergeSignRange are considered. // Calculate start >= startBlockNumber so that start % MergeSignRange == 0 - long start = ((startBlockNumber + mergeSignRange - 1) / mergeSignRange) * mergeSignRange; - for (long i = start; i < endBlockNumber; i += mergeSignRange) + ulong start = (startBlockNumber + mergeSignRange - 1) / mergeSignRange * mergeSignRange; + for (ulong i = start; i < endBlockNumber; i += mergeSignRange) { if (!blockNumberToHash.TryGetValue(i, out Hash256 blockHash)) continue; if (!hashToSigningAddress.TryGetValue(blockHash, out HashSet
addresses)) continue; @@ -238,7 +245,7 @@ private Address[] GetCandidatesByStakeForReward(XdcBlockHeader checkpointHeader) .ToArray(); } - private static void IncrementSignerCount(Dictionary signers, Address addr) + private static void IncrementSignerCount(Dictionary signers, Address addr) { if (!signers.TryAdd(addr, 1)) signers[addr] += 1; @@ -256,14 +263,14 @@ private Hash256 ExtractBlockHashFromSigningTxData(ReadOnlyMemory data) } private Dictionary CalculateRewardForSigners(UInt256 totalReward, - Dictionary signers) + Dictionary signers) { Dictionary rewardSigners = []; - long totalSigningCount = 0; - foreach (long signerCount in signers.Values) + ulong totalSigningCount = 0; + foreach (ulong signerCount in signers.Values) totalSigningCount += signerCount; - foreach ((Address signer, long count) in signers) + foreach ((Address signer, ulong count) in signers) { UInt256 reward = CalculateProportionalReward(count, totalSigningCount, totalReward); rewardSigners.Add(signer, reward); @@ -273,13 +280,13 @@ private Dictionary CalculateRewardForSigners(UInt256 totalRewa private Dictionary CalculateFixedRewardForSigners( UInt256 rewardPerSigner, - Dictionary signers) + Dictionary signers) { Dictionary rewardSigners = []; if (rewardPerSigner == UInt256.Zero) return rewardSigners; - foreach ((Address signer, long _) in signers) + foreach ((Address signer, ulong _) in signers) rewardSigners[signer] = rewardPerSigner; return rewardSigners; @@ -292,20 +299,19 @@ private Dictionary CalculateFixedRewardForSigners( /// Formula: (totalReward / totalSignatures) * signatureCount /// internal UInt256 CalculateProportionalReward( - long signatureCount, - long totalSignatures, + ulong signatureCount, + ulong totalSignatures, UInt256 totalReward) { - if (signatureCount <= 0 || totalSignatures <= 0) + if (signatureCount == 0 || totalSignatures == 0) { return UInt256.Zero; } - // Convert to UInt256 for precision + // Widening casts from ulong to UInt256 — safe, no overflow possible. UInt256 signatures = (UInt256)signatureCount; UInt256 total = (UInt256)totalSignatures; - UInt256 portion = totalReward / total; UInt256 reward = portion * signatures; diff --git a/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs b/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs index 75602f547108..e816152e131c 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs @@ -72,7 +72,7 @@ public virtual bool ValidateParams(BlockHeader parent, BlockHeader header, [NotN throw new InvalidOperationException($"Snap shot returned no master nodes for header \n{xdcHeader}"); } - ulong currentLeaderIndex = (xdcHeader.ExtraConsensusData.BlockRound % (ulong)xdcSpec.EpochLength % (ulong)masternodes.Length); + ulong currentLeaderIndex = (xdcHeader.ExtraConsensusData.BlockRound % xdcSpec.EpochLength % (ulong)masternodes.Length); if (masternodes[(int)currentLeaderIndex] != header.Author) { error = $"Block proposer {header.Author} is not the current leader."; diff --git a/src/Nethermind/Nethermind.Xdc/XdcSealer.cs b/src/Nethermind/Nethermind.Xdc/XdcSealer.cs index 64b5c6b87a37..da194fb5b2eb 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcSealer.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcSealer.cs @@ -20,7 +20,7 @@ internal class XdcSealer(ISigner signer, ILogManager logManager) : ISealer private readonly ILogger _logger = logManager.GetClassLogger(); public Address Address => signer.Address; - public bool CanSeal(long blockNumber, Hash256 parentHash) => + public bool CanSeal(ulong blockNumber, Hash256 parentHash) => //We might want to add more logic here in the future true; diff --git a/src/Nethermind/Nethermind.Xdc/XdcStateSyncPivot.cs b/src/Nethermind/Nethermind.Xdc/XdcStateSyncPivot.cs index fdf49c1e5188..24950ccbb3a9 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcStateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcStateSyncPivot.cs @@ -48,7 +48,7 @@ public class XdcStateSyncPivot( public void UpdateHeaderForcefully() { } public ConcurrentHashSet UpdatedStorages { get; } = []; - public long Diff => (_blockTree.BestSuggestedHeader?.Number ?? 0) - (_pivotHeader?.Number ?? 0); + public ulong Diff => (_blockTree.BestSuggestedHeader?.Number ?? 0) - (_pivotHeader?.Number ?? 0); public bool CanFinalize(BlockHeader pivot) { EnsureInitialized(); @@ -60,7 +60,7 @@ private void EnsureInitialized() if (_initialized) return; _initialized = true; - long pivotNumber = _syncConfig.PivotNumber; + ulong pivotNumber = _syncConfig.PivotNumber; if (pivotNumber == 0) return; XdcBlockHeader pivotHeader = _blockTree.FindHeader(pivotNumber) as XdcBlockHeader diff --git a/src/Nethermind/Nethermind.Xdc/XdcStateSyncSnapshotManager.cs b/src/Nethermind/Nethermind.Xdc/XdcStateSyncSnapshotManager.cs index 995244cca05a..f9d3cd59ad5e 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcStateSyncSnapshotManager.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcStateSyncSnapshotManager.cs @@ -41,7 +41,7 @@ public XdcBlockHeader[] GetGapBlocks(XdcBlockHeader pivotHeader) epochSwitchHeader = (XdcBlockHeader)_blockTree.FindHeader(epochSwitchHeader.ParentHash); } - long gapBlockNum = Math.Max( + ulong gapBlockNum = Math.Max( epochSwitchHeader.Number - epochSwitchHeader.Number % spec.EpochLength, spec.EpochLength ) - spec.Gap; diff --git a/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockHeader.cs b/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockHeader.cs index b35ac8c28033..98f48a39a4c1 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockHeader.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockHeader.cs @@ -15,8 +15,8 @@ public class XdcSubnetBlockHeader( Hash256 unclesHash, Address beneficiary, in UInt256 difficulty, - long number, - long gasLimit, + ulong number, + ulong gasLimit, ulong timestamp, byte[] extraData, bool isSelfMined = false) : XdcBlockHeader(parentHash, unclesHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData, isSelfMined) diff --git a/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockProducer.cs b/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockProducer.cs index d583e76b3999..da68c511bc25 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockProducer.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcSubnetBlockProducer.cs @@ -61,7 +61,7 @@ protected override BlockHeader PrepareBlockHeader(BlockHeader parent, PayloadAtt return headerCandidate; } - protected override XdcBlockHeader CreateHeader(BlockHeader parent, byte[] extra, Address blockAuthor, long gasLimit) => new XdcSubnetBlockHeader( + protected override XdcBlockHeader CreateHeader(BlockHeader parent, byte[] extra, Address blockAuthor, ulong gasLimit) => new XdcSubnetBlockHeader( parent.Hash!, Keccak.OfAnEmptySequenceRlp, blockAuthor, diff --git a/src/Nethermind/Nethermind.Xdc/XdcTransactionProcessor.cs b/src/Nethermind/Nethermind.Xdc/XdcTransactionProcessor.cs index 9cc782f33859..852fae517c2e 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcTransactionProcessor.cs @@ -41,7 +41,7 @@ protected override void PayFees( IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, - long spentGas, + ulong spentGas, in UInt256 premiumPerGas, in UInt256 blobBaseFee, int statusCode) @@ -62,7 +62,7 @@ protected override void PayFees( return; UInt256 effectiveGasPrice = CalculateEffectiveGasPrice(tx, spec.IsEip1559Enabled, header.BaseFeePerGas, out UInt256 opcodeGasPrice); - UInt256 fee = effectiveGasPrice * (ulong)spentGas; + UInt256 fee = effectiveGasPrice * spentGas; WorldState.AddToBalanceAndCreateIfNotExists(owner, fee, spec); @@ -122,7 +122,7 @@ protected override TransactionResult IncrementNonce(Transaction tx, BlockHeader { if (tx.IsSignTransaction(xdcSpec)) { - UInt256 nonce = WorldState.GetNonce(tx.SenderAddress); + ulong nonce = WorldState.GetNonce(tx.SenderAddress); if (nonce < tx.Nonce) { @@ -142,7 +142,7 @@ protected override TransactionResult IncrementNonce(Transaction tx, BlockHeader return base.IncrementNonce(tx, header, spec, tracer, opts); } - protected override TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec _, in EthereumGasPolicy intrinsicGas, long minGasRequired, bool validate) + protected override TransactionResult ValidateGas(Transaction tx, BlockHeader header, IReleaseSpec _, in EthereumGasPolicy intrinsicGas, ulong minGasRequired, bool validate) { IXdcReleaseSpec spec = SpecProvider.GetXdcSpec((XdcBlockHeader)header); if (tx.RequiresSpecialHandling(spec)) @@ -170,7 +170,7 @@ protected override UInt256 CalculateEffectiveGasPrice(Transaction tx, bool eip15 return base.CalculateEffectiveGasPrice(tx, eip1559Enabled, in baseFee, out opcodeGasPrice); } - protected override IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, long blockGasLimit) => + protected override IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec, ulong blockGasLimit) => tx.RequiresSpecialHandling((IXdcReleaseSpec)spec) ? new IntrinsicGas() : base.CalculateIntrinsicGas(tx, spec, blockGasLimit); diff --git a/tools/Evm/T8n/JsonTypes/EnvJson.cs b/tools/Evm/T8n/JsonTypes/EnvJson.cs index 7a830b840bb3..6f511bd5cd86 100644 --- a/tools/Evm/T8n/JsonTypes/EnvJson.cs +++ b/tools/Evm/T8n/JsonTypes/EnvJson.cs @@ -7,11 +7,11 @@ namespace Evm.T8n.JsonTypes; -public class EnvJson(Address currentCoinbase, long currentGasLimit, long currentNumber, ulong currentTimestamp) +public class EnvJson(Address currentCoinbase, ulong currentGasLimit, ulong currentNumber, ulong currentTimestamp) { public Address CurrentCoinbase { get; set; } = currentCoinbase; - public long CurrentGasLimit { get; set; } = currentGasLimit; - public long CurrentNumber { get; set; } = currentNumber; + public ulong CurrentGasLimit { get; set; } = currentGasLimit; + public ulong CurrentNumber { get; set; } = currentNumber; public ulong CurrentTimestamp { get; set; } = currentTimestamp; public Withdrawal[]? Withdrawals { get; set; } @@ -23,8 +23,8 @@ public class EnvJson(Address currentCoinbase, long currentGasLimit, long current public Hash256? ParentUncleHash { get; set; } public Hash256? ParentBeaconBlockRoot { get; set; } public UInt256? ParentBaseFee { get; set; } - public long ParentGasUsed { get; set; } - public long ParentGasLimit { get; set; } + public ulong ParentGasUsed { get; set; } + public ulong ParentGasLimit { get; set; } public ulong? ParentExcessBlobGas { get; set; } public ulong? CurrentExcessBlobGas { get; set; } public ulong? ParentBlobGasUsed { get; set; } diff --git a/tools/Evm/T8n/JsonTypes/Ommer.cs b/tools/Evm/T8n/JsonTypes/Ommer.cs index ddbf217521da..e19886265fe5 100644 --- a/tools/Evm/T8n/JsonTypes/Ommer.cs +++ b/tools/Evm/T8n/JsonTypes/Ommer.cs @@ -5,4 +5,4 @@ namespace Evm.T8n.JsonTypes; -public readonly record struct Ommer(int Delta, Address Address); +public readonly record struct Ommer(ulong Delta, Address Address); diff --git a/tools/Evm/T8n/JsonTypes/T8nExecutionResult.cs b/tools/Evm/T8n/JsonTypes/T8nExecutionResult.cs index 82df0acdab1f..d58123baa820 100644 --- a/tools/Evm/T8n/JsonTypes/T8nExecutionResult.cs +++ b/tools/Evm/T8n/JsonTypes/T8nExecutionResult.cs @@ -37,7 +37,7 @@ public static T8nExecutionResult ConstructT8nExecutionResult(IWorldState statePr .SelectMany(receipt => receipt.Logs ?? Enumerable.Empty()) .ToArray(); Bloom bloom = new(logEntries); - ulong gasUsed = blockReceiptsTracer.TxReceipts.Length == 0 ? 0 : (ulong)blockReceiptsTracer.LastReceipt.GasUsedTotal; + ulong gasUsed = blockReceiptsTracer.TxReceipts.Length == 0 ? 0UL : blockReceiptsTracer.LastReceipt.GasUsedTotal; ulong? blobGasUsed = test.Spec.IsEip4844Enabled ? BlobGasCalculator.CalculateBlobGas(txReport.ValidTransactions.ToArray()) : null; PostState postState = new() diff --git a/tools/Evm/T8n/T8nBlockHashProvider.cs b/tools/Evm/T8n/T8nBlockHashProvider.cs index 41befa0d10b4..7aa6aab5db6f 100644 --- a/tools/Evm/T8n/T8nBlockHashProvider.cs +++ b/tools/Evm/T8n/T8nBlockHashProvider.cs @@ -10,12 +10,12 @@ namespace Evm.T8n; -public class T8nBlockHashProvider(Dictionary blockHashes) : IBlockhashProvider +public class T8nBlockHashProvider(Dictionary blockHashes) : IBlockhashProvider { - public Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec? spec) + public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec? spec) { - long current = currentBlock.Number; - if (number >= current || number < current - Math.Min(current, BlockhashProvider.MaxDepth)) + ulong current = currentBlock.Number; + if (number >= current || number < current - Math.Min(current, (ulong)BlockhashProvider.MaxDepth)) return null; return blockHashes.TryGetValue(number, out Hash256? hash) diff --git a/tools/Evm/T8n/T8nExecutor.cs b/tools/Evm/T8n/T8nExecutor.cs index 823eaca741ec..7dab770a9e2d 100644 --- a/tools/Evm/T8n/T8nExecutor.cs +++ b/tools/Evm/T8n/T8nExecutor.cs @@ -134,7 +134,7 @@ public static T8nExecutionResult Execute(T8nCommandArguments arguments) } private static IBlockhashProvider ConstructBlockHashProvider(T8nTest test) => - new T8nBlockHashProvider(test.BlockHashes.ToDictionary(kvp => long.Parse(kvp.Key), kvp => kvp.Value)); + new T8nBlockHashProvider(test.BlockHashes.ToDictionary(kvp => ulong.Parse(kvp.Key), kvp => kvp.Value)); private static void ApplyRewards(Block block, IWorldState stateProvider, IReleaseSpec spec, ISpecProvider specProvider) { diff --git a/tools/Evm/T8n/T8nTest.cs b/tools/Evm/T8n/T8nTest.cs index f897772d280c..6ceb7c441aae 100644 --- a/tools/Evm/T8n/T8nTest.cs +++ b/tools/Evm/T8n/T8nTest.cs @@ -26,21 +26,21 @@ public class T8nTest(IReleaseSpec spec, ISpecProvider specProvider, Address curr public Address CurrentCoinbase { get; set; } = currentCoinbase; public UInt256? CurrentDifficulty { get; set; } public UInt256? CurrentBaseFee { get; set; } - public long CurrentGasLimit { get; set; } - public long CurrentNumber { get; set; } + public ulong CurrentGasLimit { get; set; } + public ulong CurrentNumber { get; set; } public ulong CurrentTimestamp { get; set; } public Hash256? CurrentRandom { get; set; } public ulong? CurrentExcessBlobGas { get; set; } - public UInt256? ParentBlobGasUsed { get; set; } - public UInt256? ParentExcessBlobGas { get; set; } + public ulong? ParentBlobGasUsed { get; set; } + public ulong? ParentExcessBlobGas { get; set; } public Withdrawal[]? Withdrawals { get; set; } public ulong ParentTimestamp { get; set; } public UInt256? ParentDifficulty { get; set; } public Hash256? ParentUncleHash { get; set; } public Hash256? ParentBeaconBlockRoot { get; set; } public UInt256? ParentBaseFee { get; set; } - public long ParentGasUsed { get; set; } - public long ParentGasLimit { get; set; } + public ulong ParentGasUsed { get; set; } + public ulong ParentGasLimit { get; set; } public Dictionary BlockHashes { get; set; } = []; public Ommer[] Ommers { get; set; } = []; public ulong StateChainId { get; set; } = MainnetSpecProvider.Instance.ChainId; @@ -62,8 +62,8 @@ private BlockHeader ConstructBlockHeader() if (ParentExcessBlobGas.HasValue && ParentBlobGasUsed.HasValue) { BlockHeader parentHeader = Build.A.BlockHeader - .WithExcessBlobGas((ulong)ParentExcessBlobGas) - .WithBlobGasUsed((ulong)ParentBlobGasUsed) + .WithExcessBlobGas(ParentExcessBlobGas.Value) + .WithBlobGasUsed(ParentBlobGasUsed.Value) .TestObject; header.ExcessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parentHeader, Spec); } diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin.Test/CMSketchTests.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin.Test/CMSketchTests.cs index 2b3d21629c47..67f6329347f9 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin.Test/CMSketchTests.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin.Test/CMSketchTests.cs @@ -121,9 +121,9 @@ public void validate_reset() [Test] public void test_buckets() { - int buckets = 1000; + ulong buckets = 1000UL; CmSketch sketch = _highAccuracyHighConfidence; - for (ulong i = 0; i < (ulong)buckets; i++) + for (ulong i = 0; i < buckets; i++) { Assert.That(sketch.Query(i), Is.EqualTo(0UL)); sketch.Update(i); diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Analyzer/Pattern/CMSketch.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Analyzer/Pattern/CMSketch.cs index b342d08f775c..2dd9857ba33d 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Analyzer/Pattern/CMSketch.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Analyzer/Pattern/CMSketch.cs @@ -124,14 +124,14 @@ private static long[] GenerateSeed(int numberOfhashFunctions) [MethodImpl(MethodImplOptions.AggressiveInlining)] private ulong Increment(ulong item, int hasher) => Interlocked.Increment( - ref _sketch[(ulong)hasher * (ulong)numberOfBuckets + ComputeHash(item, hasher) % (ulong)numberOfBuckets]); + ref _sketch[hasher * numberOfBuckets + (int)(ComputeHash(item, hasher) % (uint)numberOfBuckets)]); public ulong Query(ulong item) { ulong minCount = ulong.MaxValue; for (int hasher = 0; hasher < numberOfhashFunctions; hasher++) minCount = Math.Min(minCount, - _sketch[(ulong)hasher * (ulong)numberOfBuckets + ComputeHash(item, hasher) % (ulong)numberOfBuckets]); + _sketch[hasher * numberOfBuckets + (int)(ComputeHash(item, hasher) % (uint)numberOfBuckets)]); return minCount; } diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallAnalyzerTxTrace.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallAnalyzerTxTrace.cs index c1a31e46684b..c8e7cb736ead 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallAnalyzerTxTrace.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallAnalyzerTxTrace.cs @@ -9,10 +9,10 @@ namespace Nethermind.StatsAnalyzer.Plugin.Tracer.Call; public class CallAnalyzerTxTrace { [JsonPropertyName("initialBlockNumber")] - public long InitialBlockNumber { get; set; } + public ulong InitialBlockNumber { get; set; } [JsonPropertyName("currentBlockNumber")] - public long CurrentBlockNumber { get; set; } + public ulong CurrentBlockNumber { get; set; } [JsonPropertyName("stats")] diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallStatsAnalyzerTxTracer.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallStatsAnalyzerTxTracer.cs index 3bc5f266c11c..ada1c165f3c1 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallStatsAnalyzerTxTracer.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Call/CallStatsAnalyzerTxTracer.cs @@ -18,7 +18,7 @@ public CallStatsAnalyzerTxTracer(ResettableList
buffer, sort, ct) => IsTracingActions = true; - public override CallAnalyzerTxTrace BuildResult(long fromBlock = 0, long toBlock = 0) + public override CallAnalyzerTxTrace BuildResult(ulong fromBlock = 0UL, ulong toBlock = 0UL) { Build(); CallAnalyzerTxTrace trace = new(); @@ -45,7 +45,7 @@ private static bool IsTrackedCallType(ExecutionType t) => t is ExecutionType.CALL or ExecutionType.STATICCALL or ExecutionType.CALLCODE or ExecutionType.DELEGATECALL; - public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + public override void ReportAction(ulong gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { if (Skip) return; diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/IStatsAnalyzerTxTracer.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/IStatsAnalyzerTxTracer.cs index d7dfb09a26b2..24e9d73066a6 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/IStatsAnalyzerTxTracer.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/IStatsAnalyzerTxTracer.cs @@ -2,7 +2,7 @@ namespace Nethermind.StatsAnalyzer.Plugin.Tracer; public interface IStatsAnalyzerTxTracer { - TTrace BuildResult(long fromBlock = 0, long toBlock = 0); + TTrace BuildResult(ulong fromBlock = 0UL, ulong toBlock = 0UL); /// /// When true, per-tx hot paths must short-circuit. Used to skip diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternAnalyzerTxTrace.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternAnalyzerTxTrace.cs index ee9298b21356..c4659c12ffec 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternAnalyzerTxTrace.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternAnalyzerTxTrace.cs @@ -9,10 +9,10 @@ namespace Nethermind.StatsAnalyzer.Plugin.Tracer.Pattern; public class PatternAnalyzerTxTrace { [JsonPropertyName("initialBlockNumber")] - public long InitialBlockNumber { get; set; } + public ulong InitialBlockNumber { get; set; } [JsonPropertyName("currentBlockNumber")] - public long CurrentBlockNumber { get; set; } + public ulong CurrentBlockNumber { get; set; } [JsonPropertyName("errorPerItem")] public double ErrorPerItem { get; set; } diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternStatsAnalyzerTxTracer.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternStatsAnalyzerTxTracer.cs index 4842c1e2199c..582aa95e82bb 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternStatsAnalyzerTxTracer.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/Pattern/PatternStatsAnalyzerTxTracer.cs @@ -28,7 +28,7 @@ public void AddTxEndMarker() } - public override PatternAnalyzerTxTrace BuildResult(long fromBlock = 0, long toBlock = 0) + public override PatternAnalyzerTxTrace BuildResult(ulong fromBlock = 0UL, ulong toBlock = 0UL) { Build(); PatternAnalyzerTxTrace trace = new(); @@ -54,7 +54,7 @@ public override PatternAnalyzerTxTrace BuildResult(long fromBlock = 0, long toBl } - public override void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) + public override void StartOperation(int pc, Instruction opcode, ulong gas, in ExecutionEnvironment env) { if (Skip) return; if (!_ignoreSet.Contains(opcode)) Queue?.Enqueue(opcode); diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerFileTracer.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerFileTracer.cs index 631463ce58c4..77eb3616409e 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerFileTracer.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerFileTracer.cs @@ -39,8 +39,8 @@ public abstract class StatsAnalyzerFileTracer( protected readonly SortOrder Sort = sort; private readonly IBlocksConfig _blocksConfig = blocksConfig ?? throw new ArgumentNullException(nameof(blocksConfig)); private int _pos; - private long _currentBlock; - private long _initialBlock; + private ulong _currentBlock; + private ulong _initialBlock; private Task _lastTask = Task.CompletedTask; protected TxTracer Tracer = tracer; private bool _skipThisBlock; @@ -51,8 +51,8 @@ public abstract class StatsAnalyzerFileTracer( public override void EndBlockTrace() { TxTracer tracer = Tracer; - long initialBlockNumber = _initialBlock; - long currentBlockNumber = _currentBlock; + ulong initialBlockNumber = _initialBlock; + ulong currentBlockNumber = _currentBlock; bool skip = _skipThisBlock; ResetBufferAndTracer(); @@ -123,7 +123,7 @@ private void Enqueue(Action work) public override void StartNewBlockTrace(Block block) { base.StartNewBlockTrace(block); - long number = block.Header.Number; + ulong number = block.Header.Number; // Approximates BlockAccessListManager.ParallelExecutionEnabled; missing // clauses are subtractive, so this never under-skips (no race), only @@ -168,8 +168,8 @@ public override void EndTxTrace() protected override TxTrace OnEnd(TxTracer txTracer) => throw new NotImplementedException(); private static void WriteTrace( - long initialBlockNumber, - long currentBlockNumber, + ulong initialBlockNumber, + ulong currentBlockNumber, IStatsAnalyzerTxTracer tracer, string fileName, IFileSystem fileSystem, diff --git a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerTxTracer.cs b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerTxTracer.cs index 8f227f93889f..cc7c117c5879 100644 --- a/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerTxTracer.cs +++ b/tools/StatsAnalyzer/Nethermind.StatsAnalyzer.Plugin/Tracer/StatsAnalyzerTxTracer.cs @@ -25,7 +25,7 @@ public abstract class StatsAnalyzerTxTracer( public void SetSkip(bool skip) => Skip = skip; - public abstract TTrace BuildResult(long fromBlock = 0, long toBlock = 0); + public abstract TTrace BuildResult(ulong fromBlock = 0UL, ulong toBlock = 0UL); protected void Build() { From df93fb554f15d0ca184e675338d5f1eed0bd273a Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Tue, 9 Jun 2026 02:19:47 +0530 Subject: [PATCH 02/60] fix CI build error --- src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs | 2 +- .../Nethermind.Stateless.Executor/IO/SszForkActivation.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index 41a0f9a4fcd7..f372a4b27520 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -602,7 +602,7 @@ private static void InitializeTestState(BlockchainTest test, IWorldState statePr stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value); } - stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, accountState.Value.Nonce); + stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, (ulong)accountState.Value.Nonce); stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec); } diff --git a/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs b/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs index abab8c1526b1..c200b01e994a 100644 --- a/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs +++ b/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs @@ -29,6 +29,6 @@ public readonly ForkActivation ToForkActivation() if (Timestamp is not { Length: 1 }) throw new InvalidDataException($"{nameof(Timestamp)} must have exactly one element."); - return new(checked((long)BlockNumber[0]), Timestamp[0]); + return new(checked(BlockNumber[0]), Timestamp[0]); } } From 95c13e75299f004200da51455b0f1002ab4318fb Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Wed, 10 Jun 2026 01:59:59 +0530 Subject: [PATCH 03/60] address review comments, fix tests and build, reduce casts --- .../Ethereum.Test.Base/AccountState.cs | 2 +- .../Ethereum.Test.Base/BlockchainTestBase.cs | 2 +- .../Ethereum.Test.Base/GeneralStateTest.cs | 4 +- .../GeneralStateTestBase.cs | 8 +- .../GeneralStateTestEnvJson.cs | 4 +- .../Ethereum.Test.Base/JsonToEthereumTest.cs | 32 ++++---- .../Ethereum.Test.Base/TransactionJson.cs | 4 +- .../TransactionTests.cs | 12 +-- .../AuRaBlockFinalizationManagerTests.cs | 4 +- .../AuRaContractGasLimitOverrideTests.cs | 18 ++--- .../AuRaSealValidatorTests.cs | 20 ++--- .../Nethermind.AuRa.Test/AuRaSealerTests.cs | 20 ++--- .../AuRaStepCalculatorTests.cs | 18 ++--- .../AuraDifficultyCalculatorTests.cs | 18 ++--- .../BuildBlocksOnAuRaStepsTests.cs | 10 +-- .../ChainSpecLoaderTest.cs | 4 +- .../Reward/AuRaRewardCalculatorTests.cs | 6 +- .../Validators/ContractBasedValidatorTests.cs | 16 ++-- .../Validators/ListValidatorTests.cs | 14 ++-- .../Validators/MultiValidatorTests.cs | 28 +++---- .../ReportingContractBasedValidatorTests.cs | 4 +- .../Validators/ValidatorStoreTests.cs | 73 +++++++++--------- .../BlockhashCacheTests.cs | 4 +- .../Bloom/BloomStorageTests.cs | 34 ++++----- .../Eip8037BlockGasIntegrationTests.cs | 4 +- .../Filters/LogIndexFilterVisitorTests.cs | 10 ++- ...PrecompileCachedCodeInfoRepositoryTests.cs | 12 +-- .../Proofs/ReceiptTrieTests.cs | 4 +- .../Proofs/TxTrieTests.cs | 4 +- .../Validators/HeaderValidatorTests.cs | 12 ++- .../BlockTree.Initializer.cs | 4 +- .../Blocks/BlockhashStore.cs | 4 +- .../FullPruning/FullPruner.cs | 2 +- .../PrecompileCachedCodeInfoRepository.cs | 4 +- .../Synchronization/ISyncConfig.cs | 6 +- .../Synchronization/SyncConfig.cs | 6 +- .../Tracing/GethStyle/Custom/JavaScript/Db.cs | 2 +- .../Nethermind.Config/BlocksConfig.cs | 2 +- .../Nethermind.Config/IBlocksConfig.cs | 2 +- .../AuRaBlockFinalizationManager.cs | 2 +- .../AuRaSealValidator.cs | 18 ++--- .../Nethermind.Consensus.AuRa/AuRaSealer.cs | 6 +- .../AuRaStepCalculator.cs | 14 ++-- .../AuraDifficultyCalculator.cs | 11 +-- .../IAuRaStepCalculator.cs | 6 +- .../Nethermind.Consensus.AuRa/Metrics.cs | 2 +- .../Transactions/GeneratedTxSource.cs | 2 +- .../Validators/AuRaValidatorBase.cs | 2 +- .../Validators/ContractBasedValidator.cs | 2 +- .../Validators/IValidSealerStrategy.cs | 2 +- .../ReportingContractBasedValidator.cs | 2 +- .../Validators/ValidSealerStrategy.cs | 2 +- .../Validators/ValidatorStore.cs | 8 +- .../Nethermind.Consensus.Ethash/Ethash.cs | 4 +- .../EthashSealValidator.cs | 2 +- .../HintBasedCache.cs | 8 +- .../Nethermind.Consensus.Ethash/IEthash.cs | 2 +- .../TargetAdjustedGasLimitCalculatorTests.cs | 4 +- .../Nethermind.Consensus/ISealValidator.cs | 2 +- .../BlockAccessListManager.Validation.cs | 5 +- .../TargetAdjustedGasLimitCalculator.cs | 4 +- .../Validators/HeaderValidator.cs | 4 +- .../Nethermind.Core.Test/BlockHeaderTests.cs | 14 ++-- .../Blockchain/BasicTestBlockchain.cs | 2 +- .../Builders/BlockBuilder.cs | 2 +- .../Builders/BlockHeaderBuilder.cs | 2 +- .../Builders/BlockTreeBuilder.cs | 2 +- .../TestTrieStoreFactory.cs | 2 +- .../TestWorldStateFactory.cs | 6 +- src/Nethermind/Nethermind.Core/BlockHeader.cs | 2 +- .../Collections/ListExtensions.cs | 2 + .../Nethermind.Core/Eip1559Constants.cs | 2 +- .../Nethermind.Core/Eip4844Constants.cs | 2 +- .../Nethermind.Core/Specs/IEip1559Spec.cs | 4 +- .../Nethermind.Core/Specs/IReleaseSpec.cs | 2 +- .../Specs/ReleaseSpecDecorator.cs | 4 +- .../Nethermind.Db/Blooms/BloomStorage.cs | 45 ++++++----- .../Nethermind.Db/Blooms/FileReader.cs | 4 +- .../Blooms/FixedSizeFileStore.cs | 6 +- .../Nethermind.Db/Blooms/IFileReader.cs | 2 +- .../Nethermind.Db/Blooms/IFileStore.cs | 4 +- .../Blooms/InMemoryDictionaryFileReader.cs | 2 +- .../Blooms/InMemoryDictionaryFileStore.cs | 6 +- src/Nethermind/Nethermind.Db/FlatDbConfig.cs | 4 +- src/Nethermind/Nethermind.Db/IFlatDbConfig.cs | 4 +- .../Nethermind.Db/IPruningConfig.cs | 2 +- src/Nethermind/Nethermind.Db/PruningConfig.cs | 2 +- src/Nethermind/Nethermind.Era1/EraConfig.cs | 2 +- src/Nethermind/Nethermind.Era1/EraImporter.cs | 2 +- src/Nethermind/Nethermind.Era1/IEraConfig.cs | 2 +- .../Store/RemoteEraStoreDecoratorTests.cs | 37 ++++----- .../Nethermind.EraE/Archive/EraReader.cs | 10 +-- .../Nethermind.EraE/Config/EraEConfig.cs | 6 +- .../Nethermind.EraE/Config/IEraEConfig.cs | 6 +- .../Nethermind.EraE/EraCliRunner.cs | 4 +- .../Nethermind.EraE/Import/EraImporter.cs | 2 +- .../Nethermind.EraE/Store/EraStore.cs | 18 +++-- .../Store/RemoteEraStoreDecorator.cs | 19 +++-- .../BlockProcessingBenchmark.cs | 4 +- .../BN254AddPrecompile.cs | 4 +- .../BN254MulPrecompile.cs | 4 +- .../BN254PairingCheckPrecompile.cs | 6 +- .../Blake2FPrecompile.cs | 8 +- .../Bls12381Fp2ToG2Precompile.cs | 4 +- .../Bls12381FpToG1Precompile.cs | 4 +- .../Bls12381G1AddPrecompile.cs | 4 +- .../Bls12381G1MsmPrecompile.cs | 6 +- .../Bls12381G2AddPrecompile.cs | 4 +- .../Bls12381G2MsmPrecompile.cs | 6 +- .../Bls12381PairingCheckPrecompile.cs | 4 +- .../ECRecoverPrecompile.cs | 4 +- .../IdentityPrecompile.cs | 6 +- .../KzgPointEvaluationPrecompile.cs | 4 +- .../ModExpPrecompile.cs | 16 ++-- .../ModExpPrecompilePreEip2565.cs | 12 +-- .../Ripemd160Precompile.cs | 6 +- .../SecP256r1Precompile.cs | 4 +- .../Sha256Precompile.cs | 6 +- .../Nethermind.Evm.Test/CallDataLoadTests.cs | 2 +- .../Nethermind.Evm.Test/Eip2565Tests.cs | 8 +- .../Nethermind.Evm.Test/Eip7823Tests.cs | 10 +-- .../Nethermind.Evm.Test/Eip7883Tests.cs | 4 +- .../KzgPointEvaluationPrecompileTests.cs | 4 +- .../Nethermind.Evm.Test/PrecompileTests.cs | 4 +- .../Tracing/GasEstimationTests.cs | 4 +- .../Nethermind.Evm/BlobGasCalculator.cs | 9 ++- .../GasPolicy/EthereumGasPolicy.cs | 10 +-- .../Instructions/EvmInstructions.Bitwise.cs | 2 +- .../Instructions/EvmInstructions.Call.cs | 2 +- .../Instructions/EvmInstructions.CodeCopy.cs | 6 +- .../Instructions/EvmInstructions.Crypto.cs | 2 +- .../EvmInstructions.Environment.cs | 6 +- .../Instructions/EvmInstructions.Storage.cs | 8 +- .../Nethermind.Evm/Precompiles/IPrecompile.cs | 4 +- .../Nethermind.Evm/ReleaseSpecExtensions.cs | 2 +- .../ITransactionProcessor.cs | 2 +- .../TransactionProcessor.cs | 4 +- .../Nethermind.Evm/VirtualMachine.cs | 30 ++++---- .../BlobBaseFeeOverrideCalculatorDecorator.cs | 2 +- .../Nethermind.Facade/Eth/BlockForRpc.cs | 4 +- .../Eth/BlockHeaderForRpc.cs | 4 +- .../Filters/LogIndexFilterVisitor.cs | 2 +- .../Find/IndexedLogFinder.cs | 2 +- .../Proxy/Models/TransactionModel.cs | 10 +-- .../HistoryPrunerTests.cs | 76 +++++++++---------- .../Nethermind.History/HistoryConfig.cs | 2 +- .../Nethermind.History/HistoryPruner.cs | 6 +- .../Nethermind.History/IHistoryConfig.cs | 2 +- .../Nethermind.Init/MemoryHintMan.cs | 61 +++++++-------- .../Modules/BlockTreeModule.cs | 2 +- .../Modules/FlatWorldStateModule.cs | 2 +- .../PruningTrieStateFactory.cs | 33 +++----- .../Eth/EthRpcModuleTests.Capabilities.cs | 8 +- .../Modules/Eth/EthCapabilitiesProvider.cs | 4 +- .../Modules/Eth/SimulateTxExecutor.cs | 10 ++- .../Modules/LogIndex/LogIndexRpcModule.cs | 2 +- .../EngineModuleTests.V6.cs | 14 ++-- .../Synchronization/BeaconHeadersSyncTests.cs | 12 +-- .../Synchronization/BeaconPivot.cs | 2 +- .../GasLimitCalculatorTests.cs | 12 +-- .../HintBasedCacheTests.cs | 8 +- .../Eth/V62/Eth62ProtocolHandler.cs | 4 +- .../NewBlockHashesMessageSerializer.cs | 2 +- .../Eth/V62/Messages/StatusMessage.cs | 2 +- .../V62/Messages/StatusMessageSerializer.cs | 2 +- .../Eth/V69/Eth69ProtocolHandler.cs | 4 +- .../Eth/V69/Messages/StatusMessage69.cs | 2 +- .../V69/Messages/StatusMessageSerializer69.cs | 2 +- .../Eth/V70/Eth70ProtocolHandler.cs | 2 +- .../OptimismPayloadPreparationServiceTests.cs | 2 +- .../ConfigFilesTests.cs | 14 ++-- .../MemoryHintManTests.cs | 4 +- .../Module/FlatRocksDbConfigAdjusterTests.cs | 8 +- .../NullableLongConvertercs.cs | 33 ++++++++ .../HeaderDecoder.cs | 2 +- .../ChainSpecBasedSpecProviderTests.cs | 12 +-- .../OverridableReleaseSpec.cs | 4 +- .../ChainSpecStyle/ChainParameters.cs | 4 +- .../ChainSpecStyle/ChainSpecLoader.cs | 2 +- .../Json/ChainSpecAuRaSealJson.cs | 2 +- .../Json/ChainSpecParamsJson.cs | 4 +- .../Nethermind.Specs/ReleaseSpec.cs | 4 +- .../CompactionSchedule.cs | 59 ++++++-------- .../Nethermind.State.Flat/FlatDbManager.cs | 2 +- .../ScopeProvider/FlatWorldStateManager.cs | 2 +- .../Nethermind.State.Flat/TrieNodeCache.cs | 2 +- .../WorldStateManagerTests.cs | 8 +- .../Nethermind.State/IStateBoundary.cs | 2 +- .../Nethermind.State/WorldStateManager.cs | 4 +- .../IO/SszForkActivation.cs | 2 +- .../BlockDownloaderTests.Merge.cs | 47 +++++++----- .../BlockDownloaderTests.cs | 10 +-- .../FastBlocks/FastHeadersSyncTests.cs | 18 ++--- .../FastSync/StateSyncFeedTestsBase.cs | 2 +- ...MultiSyncModeSelectorTestsBase.Scenario.cs | 2 +- .../SnapSync/StateSyncPivotTest.cs | 2 +- .../Blocks/FastSyncFeed.cs | 2 +- .../Blocks/PowForwardHeaderProvider.cs | 3 +- .../FastBlocks/BlockAccessListsSyncFeed.cs | 10 +-- .../FastBlocks/BodiesSyncFeed.cs | 2 +- .../FastBlocks/HeadersSyncBatch.cs | 4 +- .../FastBlocks/HeadersSyncDownloader.cs | 2 +- .../FastBlocks/HeadersSyncFeed.cs | 28 +++---- .../FastBlocks/ReceiptsSyncFeed.cs | 2 +- .../FastSync/StateSyncPivot.cs | 6 +- .../Nethermind.Synchronization/Sync.cs | 2 +- .../Nethermind.Synchronization/SyncServer.cs | 10 +-- .../L1StaticCallPrecompileTests.cs | 10 +-- .../Precompiles/L1PrecompileConstants.cs | 10 +-- .../Precompiles/L1SloadPrecompile.cs | 6 +- .../Precompiles/L1StaticCallPrecompile.cs | 8 +- .../Pruning/TreeStoreTests.cs | 38 +++++----- .../PruningScenariosTests.cs | 6 +- .../Nethermind.Trie.Test/TrieTests.cs | 6 +- .../Pruning/MaxBlockInCachePruneStrategy.cs | 6 +- .../Pruning/MinBlockInCachePruneStrategy.cs | 6 +- .../Nethermind.Trie/Pruning/Prune.cs | 4 +- .../Nethermind.Trie/Pruning/TrieStore.cs | 34 ++++++--- .../Pruning/TrieStoreDirtyNodesCache.cs | 12 ++- .../Nethermind.TxPool.Test/TxPoolTests.cs | 7 +- .../ModuleTests/RpcModuleTests.cs | 10 +-- .../XdcGasLimitCalculatorTests.cs | 14 ++-- .../QuorumCertificateManager.cs | 2 +- .../Nethermind.Xdc/RPC/RpcHelpers.cs | 2 +- .../Nethermind.Xdc/RPC/XdcRpcModule.cs | 10 +-- .../Nethermind.Xdc/XdcGasLimitCalculator.cs | 2 +- .../Nethermind.Xdc/XdcRewardCalculator.cs | 2 +- .../Nethermind.Xdc/XdcSealValidator.cs | 2 +- 228 files changed, 964 insertions(+), 888 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/AccountState.cs b/src/Nethermind/Ethereum.Test.Base/AccountState.cs index 461412662f90..1a628bef243c 100644 --- a/src/Nethermind/Ethereum.Test.Base/AccountState.cs +++ b/src/Nethermind/Ethereum.Test.Base/AccountState.cs @@ -10,7 +10,7 @@ public class AccountState { public byte[] Code { get; set; } = []; public UInt256 Balance { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public Dictionary Storage { get; set; } = []; } } diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index f372a4b27520..41a0f9a4fcd7 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -602,7 +602,7 @@ private static void InitializeTestState(BlockchainTest test, IWorldState statePr stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value); } - stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, (ulong)accountState.Value.Nonce); + stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, accountState.Value.Nonce); stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec); } diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralStateTest.cs b/src/Nethermind/Ethereum.Test.Base/GeneralStateTest.cs index 13bf2fb245c5..3731a722a7a6 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralStateTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralStateTest.cs @@ -24,8 +24,8 @@ public class GeneralStateTest : EthereumTest public UInt256 CurrentDifficulty { get; set; } public UInt256? CurrentBaseFee { get; set; } - public long CurrentGasLimit { get; set; } - public long CurrentNumber { get; set; } + public ulong CurrentGasLimit { get; set; } + public ulong CurrentNumber { get; set; } public ulong CurrentTimestamp { get; set; } public Hash256? PreviousHash { get; set; } public Dictionary Pre { get; set; } diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs index 321485c70241..ccee2fa8214e 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestBase.cs @@ -107,7 +107,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) test.Transaction.ChainId = test.ChainId; } - IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)(ulong)test.CurrentNumber); + IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)test.CurrentNumber); Transaction[] transactions = [test.Transaction]; Withdrawal[]? withdrawals = spec.WithdrawalsEnabled ? [] : null; @@ -116,8 +116,8 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) Keccak.OfAnEmptySequenceRlp, test.CurrentCoinbase, test.CurrentDifficulty, - (ulong)test.CurrentNumber, - (ulong)test.CurrentGasLimit, + test.CurrentNumber, + test.CurrentGasLimit, test.CurrentTimestamp, []) { @@ -209,7 +209,7 @@ public static void InitializeTestState(Dictionary preStat storageItem.Value.WithoutLeadingZeros().ToArray()); } - stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, (ulong)accountState.Value.Nonce); + stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance, accountState.Value.Nonce); stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec); } diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestEnvJson.cs b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestEnvJson.cs index 4b7de2e75963..b6750627a6b8 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralStateTestEnvJson.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralStateTestEnvJson.cs @@ -11,8 +11,8 @@ public class GeneralStateTestEnvJson { public Address CurrentCoinbase { get; set; } public UInt256 CurrentDifficulty { get; set; } - public long CurrentGasLimit { get; set; } - public long CurrentNumber { get; set; } + public ulong CurrentGasLimit { get; set; } + public ulong CurrentNumber { get; set; } public ulong CurrentTimestamp { get; set; } public UInt256? CurrentBaseFee { get; set; } public Hash256 PreviousHash { get; set; } diff --git a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs index 666591872e6f..a43a7768a88c 100644 --- a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs @@ -24,6 +24,12 @@ namespace Ethereum.Test.Base { public static class JsonToEthereumTest { + private static ulong ParseULong(string? hex) => + Bytes.FromHexString(hex).ToULongFromBigEndianByteArrayWithoutLeadingZeros(); + + private static ulong? ParseULongNullable(string? hex) => + hex is null ? null : (ulong?)Bytes.FromHexString(hex).ToULongFromBigEndianByteArrayWithoutLeadingZeros(); + private static ForkActivation TransitionForkActivation(string transitionInfo) { const string timestampPrefix = "Time"; @@ -55,22 +61,22 @@ public static BlockHeader Convert(TestBlockHeaderJson? headerJson) new Hash256(headerJson.UncleHash), new Address(headerJson.Coinbase), Bytes.FromHexString(headerJson.Difficulty).ToUInt256(), - (ulong)Bytes.FromHexString(headerJson.Number).ToUInt256(), - (ulong)Bytes.FromHexString(headerJson.GasLimit).ToUnsignedBigInteger(), - (ulong)Bytes.FromHexString(headerJson.Timestamp).ToUnsignedBigInteger(), + ParseULong(headerJson.Number), + ParseULong(headerJson.GasLimit), + ParseULong(headerJson.Timestamp), Bytes.FromHexString(headerJson.ExtraData), - headerJson.BlobGasUsed is null ? null : (ulong?)Bytes.FromHexString(headerJson.BlobGasUsed).ToUnsignedBigInteger(), - headerJson.ExcessBlobGas is null ? null : (ulong?)Bytes.FromHexString(headerJson.ExcessBlobGas).ToUnsignedBigInteger(), + ParseULongNullable(headerJson.BlobGasUsed), + ParseULongNullable(headerJson.ExcessBlobGas), headerJson.ParentBeaconBlockRoot is null ? null : new Hash256(headerJson.ParentBeaconBlockRoot), headerJson.RequestsHash is null ? null : new Hash256(headerJson.RequestsHash), - headerJson.SlotNumber is null ? null : (ulong)Bytes.FromHexString(headerJson.SlotNumber).ToUnsignedBigInteger() + headerJson.SlotNumber is null ? null : ParseULong(headerJson.SlotNumber) ) { Bloom = new Bloom(Bytes.FromHexString(headerJson.Bloom)), - GasUsed = (ulong)Bytes.FromHexString(headerJson.GasUsed).ToUnsignedBigInteger(), + GasUsed = ParseULong(headerJson.GasUsed), Hash = new Hash256(headerJson.Hash), MixHash = new Hash256(headerJson.MixHash), - Nonce = (ulong)Bytes.FromHexString(headerJson.Nonce).ToUnsignedBigInteger(), + Nonce = ParseULong(headerJson.Nonce), ReceiptsRoot = new Hash256(headerJson.ReceiptTrie), StateRoot = new Hash256(headerJson.StateRoot), TxRoot = new Hash256(headerJson.TransactionsTrie), @@ -80,7 +86,7 @@ public static BlockHeader Convert(TestBlockHeaderJson? headerJson) if (headerJson.BaseFeePerGas is not null) { - header.BaseFeePerGas = (ulong)Bytes.FromHexString(headerJson.BaseFeePerGas).ToUnsignedBigInteger(); + header.BaseFeePerGas = ParseULong(headerJson.BaseFeePerGas); } return header; @@ -116,10 +122,10 @@ public static Transaction Convert(PostStateJson postStateJson, TransactionJson t { Type = transactionJson.Type, Value = transactionJson.Value[postStateJson.Indexes.Value], - GasLimit = (ulong)transactionJson.GasLimit[postStateJson.Indexes.Gas], + GasLimit = transactionJson.GasLimit[postStateJson.Indexes.Gas], GasPrice = transactionJson.GasPrice ?? transactionJson.MaxPriorityFeePerGas ?? 0, DecodedMaxFeePerGas = transactionJson.MaxFeePerGas ?? 0, - Nonce = (ulong)transactionJson.Nonce, + Nonce = transactionJson.Nonce, To = transactionJson.To, Data = transactionJson.Data[postStateJson.Indexes.Data], SenderAddress = new PrivateKey(transactionJson.SecretKey).Address, @@ -226,9 +232,9 @@ public static Transaction Convert(LegacyTransactionJson transactionJson) Transaction transaction = new() { Value = transactionJson.Value, - GasLimit = (ulong)transactionJson.GasLimit, + GasLimit = transactionJson.GasLimit, GasPrice = transactionJson.GasPrice, - Nonce = (ulong)transactionJson.Nonce, + Nonce = transactionJson.Nonce, To = transactionJson.To, Data = transactionJson.Data, Signature = new Signature(transactionJson.R, transactionJson.S, transactionJson.V) diff --git a/src/Nethermind/Ethereum.Test.Base/TransactionJson.cs b/src/Nethermind/Ethereum.Test.Base/TransactionJson.cs index 83c4884f8359..99b603f9492f 100644 --- a/src/Nethermind/Ethereum.Test.Base/TransactionJson.cs +++ b/src/Nethermind/Ethereum.Test.Base/TransactionJson.cs @@ -11,11 +11,11 @@ public class TransactionJson public TxType Type { get; set; } public Address Sender { get; set; } public byte[][]? Data { get; set; } - public long[]? GasLimit { get; set; } + public ulong[]? GasLimit { get; set; } public UInt256? GasPrice { get; set; } public UInt256? MaxFeePerGas { get; set; } public UInt256? MaxPriorityFeePerGas { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public Address? To { get; set; } public UInt256[]? Value { get; set; } public byte[]? SecretKey { get; set; } diff --git a/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs b/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs index b60117fad564..0028854beaa3 100644 --- a/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs +++ b/src/Nethermind/Ethereum.Transaction.Test/TransactionTests.cs @@ -58,9 +58,9 @@ private static TransactionTest CreateTest(string network, string name, Transacti { BlockNumber = Bytes.FromHexString(testJson.BlockNumber).ToUInt256(), Data = Bytes.FromHexString(transactionJson.Data), - GasLimit = Bytes.FromHexString(transactionJson.GasLimit).ToUInt256(), + GasLimit = Bytes.FromHexString(transactionJson.GasLimit).ToULongFromBigEndianByteArrayWithoutLeadingZeros(), GasPrice = Bytes.FromHexString(transactionJson.GasPrice).ToUInt256(), - Nonce = Bytes.FromHexString(transactionJson.Nonce).ToUInt256(), + Nonce = Bytes.FromHexString(transactionJson.Nonce).ToULongFromBigEndianByteArrayWithoutLeadingZeros(), R = Bytes.FromHexString(transactionJson.R).ToUInt256(), S = Bytes.FromHexString(transactionJson.S).ToUInt256(), V = Bytes.FromHexString(transactionJson.V)[0], @@ -97,9 +97,9 @@ private static void RunTest(TransactionTest test, IReleaseSpec spec) { Assert.That(transaction.Value, Is.EqualTo(validTest.Value), "value"); Assert.That(transaction.Data.AsArray(), Is.EqualTo(validTest.Data), "data"); - Assert.That(transaction.GasLimit, Is.EqualTo((ulong)validTest.GasLimit), "gasLimit"); + Assert.That(transaction.GasLimit, Is.EqualTo(validTest.GasLimit), "gasLimit"); Assert.That(transaction.GasPrice, Is.EqualTo(validTest.GasPrice), "gasPrice"); - Assert.That(transaction.Nonce, Is.EqualTo((ulong)validTest.Nonce), "nonce"); + Assert.That(transaction.Nonce, Is.EqualTo(validTest.Nonce), "nonce"); Assert.That(transaction.To, Is.EqualTo(validTest.To), "to"); Assert.That(validator.IsWellFormed(transaction, spec), Is.True); @@ -151,9 +151,9 @@ public class ValidTransactionTest(string network, string name, string rlp) { public Address Sender { get; set; } public UInt256 BlockNumber { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public UInt256 GasPrice { get; set; } - public UInt256 GasLimit { get; set; } + public ulong GasLimit { get; set; } public Address To { get; set; } public UInt256 Value { get; set; } public byte V { get; set; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs index 9fd45b2671ac..9335c87079d7 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockFinalizationManagerTests.cs @@ -111,9 +111,9 @@ public void correctly_finalizes_blocks_in_chain(int chainLength, ulong twoThirds blockTreeBuilder.OfChainLength(chainLength, blockBeneficiaries: blockCreators); int start = 0; - for (int i = start; i < chainLength; i++) + for (ulong i = 0; i < (ulong)chainLength; i++) { - Hash256 blockHash = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i).MainChainBlock.BlockHash; + Hash256 blockHash = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.BlockHash; Block? block = blockTreeBuilder.TestObject.FindBlock(blockHash, BlockTreeLookupOptions.None); _blockProcessor.BlockProcessed += Raise.EventWith(new BlockProcessedEventArgs(block, [])); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs index a138fcfee0ad..0a33aa5c61a8 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaContractGasLimitOverrideTests.cs @@ -18,15 +18,15 @@ namespace Nethermind.AuRa.Test { public class AuRaContractGasLimitOverrideTests { - [TestCase(false, 1UL, 4000000)] - [TestCase(true, 1UL, 4000000)] - [TestCase(false, 3UL, 1000)] - [TestCase(false, 5UL, 3000000)] - [TestCase(true, 3UL, 2000000)] - [TestCase(true, 5UL, 3000000)] - [TestCase(true, 10UL, 4000000)] - [TestCase(false, 10UL, 4000000)] - public void GetGasLimit(bool minimum2MlnGasPerBlockWhenUsingBlockGasLimit, ulong blockNumber, long? expected) + [TestCase(false, 1UL, 4000000UL)] + [TestCase(true, 1UL, 4000000UL)] + [TestCase(false, 3UL, 1000UL)] + [TestCase(false, 5UL, 3000000UL)] + [TestCase(true, 3UL, 2000000UL)] + [TestCase(true, 5UL, 3000000UL)] + [TestCase(true, 10UL, 4000000UL)] + [TestCase(false, 10UL, 4000000UL)] + public void GetGasLimit(bool minimum2MlnGasPerBlockWhenUsingBlockGasLimit, ulong blockNumber, ulong? expected) { IBlockGasLimitContract blockGasLimitContract1 = Substitute.For(); blockGasLimitContract1.ActivationBlock.Returns(3UL); diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs index 6058e61350c4..4a6de4a0bed9 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealValidatorTests.cs @@ -30,7 +30,7 @@ public class AuRaSealValidatorTests private IWallet _wallet; private Address _address; private IEthereumEcdsa _ethereumEcdsa; - private static int _currentStep; + private static ulong _currentStep; private IReportingValidator _reportingValidator; private IBlockTree _blockTree; private IValidSealerStrategy _validSealerStrategy; @@ -45,7 +45,7 @@ public void SetUp() _address = _wallet.NewAccount(new NetworkCredential(string.Empty, "AAA").SecurePassword); _ethereumEcdsa = Substitute.For(); - _currentStep = 11; + _currentStep = 11UL; _auRaStepCalculator.CurrentStep.Returns(_currentStep); _reportingValidator = Substitute.For(); @@ -72,11 +72,11 @@ private static IEnumerable ValidateParamsTests { get { - long step = 10; - long parentStep = 9; + ulong step = 10UL; + ulong parentStep = 9UL; BlockHeaderBuilder GetBlock() => Build.A.BlockHeader - .WithAura(10, []) + .WithAura(10UL, []) .WithBeneficiary(TestItem.AddressA) .WithDifficulty(AuraDifficultyCalculator.CalculateDifficulty(parentStep, step)); @@ -175,8 +175,8 @@ TestCaseData GetTestCaseData( [Test] public void validate_params_out_of_order() { - _auRaStepCalculator.CurrentStep.Returns(15L); - _validSealerStrategy.IsValidSealer(Arg.Any>(), Arg.Any
(), Arg.Any(), out _).Returns(true); + _auRaStepCalculator.CurrentStep.Returns(15UL); + _validSealerStrategy.IsValidSealer(Arg.Any>(), Arg.Any
(), Arg.Any(), out _).Returns(true); object cause = null; _reportingValidator.ReportMalicious(Arg.Any
(), Arg.Any(), Arg.Any(), @@ -222,9 +222,9 @@ private static IEnumerable ValidateSealTests { get { - yield return new TestCaseData(0, null, TestItem.AddressA).Returns(true).SetName("Genesis valid.").SetCategory("ValidSeal"); - yield return new TestCaseData(1, null, TestItem.AddressA).Returns(false).SetName("Wrong sealer.").SetCategory("ValidSeal"); - yield return new TestCaseData(1, null, null).Returns(true).SetName("General valid.").SetCategory("ValidSeal"); + yield return new TestCaseData(0UL, null, TestItem.AddressA).Returns(true).SetName("Genesis valid.").SetCategory("ValidSeal"); + yield return new TestCaseData(1UL, null, TestItem.AddressA).Returns(false).SetName("Wrong sealer.").SetCategory("ValidSeal"); + yield return new TestCaseData(1UL, null, null).Returns(true).SetName("General valid.").SetCategory("ValidSeal"); } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealerTests.cs index 82b6e74800f4..54cba7a5aee2 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaSealerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaSealerTests.cs @@ -23,7 +23,7 @@ public class AuRaSealerTests { private AuRaSealer _auRaSealer; private IBlockTree _blockTree; - private int _headStep; + private ulong _headStep; private IAuRaStepCalculator _auRaStepCalculator; private Address _address; private IValidatorStore _validatorStore; @@ -33,7 +33,7 @@ public class AuRaSealerTests public void Setup() { _blockTree = Substitute.For(); - _headStep = 10; + _headStep = 10UL; _blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithHash(Keccak.Compute("hash")).WithAura(_headStep, []).TestObject).TestObject); _auRaStepCalculator = Substitute.For(); @@ -51,11 +51,11 @@ public void Setup() LimboLogs.Instance); } - [TestCase(9, true, ExpectedResult = false, TestName = "Step too low-1.")] - [TestCase(10, true, ExpectedResult = false, TestName = "Step too low-2.")] - [TestCase(11, false, ExpectedResult = false, TestName = "Invalid sealer.")] - [TestCase(11, true, ExpectedResult = true, TestName = "Can seal.")] - public bool can_seal(long auRaStep, bool validSealer) + [TestCase(9UL, true, ExpectedResult = false, TestName = "Step too low-1.")] + [TestCase(10UL, true, ExpectedResult = false, TestName = "Step too low-2.")] + [TestCase(11UL, false, ExpectedResult = false, TestName = "Invalid sealer.")] + [TestCase(11UL, true, ExpectedResult = true, TestName = "Can seal.")] + public bool can_seal(ulong auRaStep, bool validSealer) { _auRaStepCalculator.CurrentStep.Returns(auRaStep); _validSealerStrategy.IsValidSealer(Arg.Any>(), _address, auRaStep, out _).Returns(validSealer); @@ -65,9 +65,9 @@ public bool can_seal(long auRaStep, bool validSealer) [Test] public async Task seal_can_recover_address() { - _auRaStepCalculator.CurrentStep.Returns(11); - _validSealerStrategy.IsValidSealer(Arg.Any>(), _address, 11, out _).Returns(true); - Block block = Build.A.Block.WithHeader(Build.A.BlockHeader.WithBeneficiary(_address).WithAura(11, null).TestObject).TestObject; + _auRaStepCalculator.CurrentStep.Returns(11UL); + _validSealerStrategy.IsValidSealer(Arg.Any>(), _address, 11UL, out _).Returns(true); + Block block = Build.A.Block.WithHeader(Build.A.BlockHeader.WithBeneficiary(_address).WithAura(11UL, null).TestObject).TestObject; block = await _auRaSealer.SealBlock(block, CancellationToken.None); diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs index 2faaad8e62f0..1c3889ddb599 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaStepCalculatorTests.cs @@ -20,7 +20,7 @@ public void step_increases_after_timeToNextStep(int stepDuration) { ManualTimestamper manualTimestamper = new(DateTime.UtcNow); AuRaStepCalculator calculator = new(GetStepDurationsForSingleStep(stepDuration), manualTimestamper, LimboLogs.Instance); - long step = calculator.CurrentStep; + ulong step = calculator.CurrentStep; manualTimestamper.Add(calculator.TimeToNextStep); Assert.That(calculator.CurrentStep, Is.EqualTo(step + 1), calculator.TimeToNextStep.ToString()); } @@ -41,21 +41,21 @@ public void step_is_calculated_correctly(long milliSeconds, int stepDuration) DateTimeOffset time = DateTimeOffset.FromUnixTimeMilliseconds(milliSeconds); ManualTimestamper timestamper = new(time.UtcDateTime); AuRaStepCalculator calculator = new(GetStepDurationsForSingleStep(stepDuration), timestamper, LimboLogs.Instance); - Assert.That(calculator.CurrentStep, Is.EqualTo(time.ToUnixTimeSeconds() / stepDuration)); + Assert.That(calculator.CurrentStep, Is.EqualTo((ulong)(time.ToUnixTimeSeconds() / stepDuration))); } - [TestCase(100000060005L, 2, 50000030)] - [TestCase(100000060005L, 2, 50000000)] - [TestCase(100000060005L, 2, 50000031)] - [TestCase(100000060005L, 2, 50000035)] - public void time_to_step_is_calculated_correctly(long milliSeconds, int stepDuration, int checkedStep) + [TestCase(100000060005L, 2, 50000030UL)] + [TestCase(100000060005L, 2, 50000000UL)] + [TestCase(100000060005L, 2, 50000031UL)] + [TestCase(100000060005L, 2, 50000035UL)] + public void time_to_step_is_calculated_correctly(long milliSeconds, int stepDuration, ulong checkedStep) { - const long currentStep = 50000030; + const ulong currentStep = 50000030UL; TimeSpan timeToNextStep = TimeSpan.FromMilliseconds(1995); DateTimeOffset time = DateTimeOffset.FromUnixTimeMilliseconds(milliSeconds); ManualTimestamper timestamper = new(time.UtcDateTime); AuRaStepCalculator calculator = new(GetStepDurationsForSingleStep(stepDuration), timestamper, LimboLogs.Instance); - TimeSpan expected = checkedStep <= currentStep ? TimeSpan.FromMilliseconds(0) : TimeSpan.FromSeconds((checkedStep - currentStep - 1) * stepDuration) + timeToNextStep; + TimeSpan expected = checkedStep <= currentStep ? TimeSpan.FromMilliseconds(0) : TimeSpan.FromSeconds((double)(checkedStep - currentStep - 1) * stepDuration) + timeToNextStep; TestContext.Out.WriteLine($"Expected time to step {checkedStep} is {expected}"); Assert.That(calculator.TimeToStep(checkedStep), Is.EqualTo(expected)); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuraDifficultyCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuraDifficultyCalculatorTests.cs index 18db80ea828c..7388238a85f6 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuraDifficultyCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuraDifficultyCalculatorTests.cs @@ -14,20 +14,20 @@ private static IEnumerable DifficultyTestCases { get { - yield return new TestCaseData(1, 0, 0).Returns(UInt256.UInt128MaxValue - 1); - yield return new TestCaseData(10, 0, 0).Returns(UInt256.UInt128MaxValue - 10); - yield return new TestCaseData(10, 9, 0).Returns(UInt256.UInt128MaxValue - 1); - yield return new TestCaseData(100, 10, 0).Returns(UInt256.UInt128MaxValue - 90); + yield return new TestCaseData(1UL, 0UL, 0UL).Returns(UInt256.UInt128MaxValue - 1); + yield return new TestCaseData(10UL, 0UL, 0UL).Returns(UInt256.UInt128MaxValue - 10); + yield return new TestCaseData(10UL, 9UL, 0UL).Returns(UInt256.UInt128MaxValue - 1); + yield return new TestCaseData(100UL, 10UL, 0UL).Returns(UInt256.UInt128MaxValue - 90); - yield return new TestCaseData(1, 0, 1).Returns(UInt256.UInt128MaxValue); - yield return new TestCaseData(10, 0, 5).Returns(UInt256.UInt128MaxValue - 5); - yield return new TestCaseData(10, 9, 3).Returns(new UInt256(1, 0, 1, 0)); - yield return new TestCaseData(100, 10, 10).Returns(UInt256.UInt128MaxValue - 80); + yield return new TestCaseData(1UL, 0UL, 1UL).Returns(UInt256.UInt128MaxValue); + yield return new TestCaseData(10UL, 0UL, 5UL).Returns(UInt256.UInt128MaxValue - 5); + yield return new TestCaseData(10UL, 9UL, 3UL).Returns(new UInt256(1, 0, 1, 0)); + yield return new TestCaseData(100UL, 10UL, 10UL).Returns(UInt256.UInt128MaxValue - 80); } } [TestCaseSource(nameof(DifficultyTestCases))] - public UInt256 calculates_difficulty(long step, long parentStep, long emptyStepCount) => + public UInt256 calculates_difficulty(ulong step, ulong parentStep, ulong emptyStepCount) => AuraDifficultyCalculator.CalculateDifficulty(parentStep, step, emptyStepCount); } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/BuildBlocksOnAuRaStepsTests.cs b/src/Nethermind/Nethermind.AuRa.Test/BuildBlocksOnAuRaStepsTests.cs index f01b063c6202..5dd06522ec12 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/BuildBlocksOnAuRaStepsTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/BuildBlocksOnAuRaStepsTests.cs @@ -69,24 +69,24 @@ public async Task should_not_cancel_block_production_trigger_on_next_step_finish private class TestAuRaStepCalculator : IAuRaStepCalculator { - public const long StepDuration = 10; + public const ulong StepDuration = 10; public static readonly TimeSpan StepDurationTimeSpan = TimeSpan.FromMilliseconds(StepDuration); - public long CurrentStep => UnixTime.MillisecondsLong / StepDuration; + public ulong CurrentStep => (ulong)UnixTime.MillisecondsLong / StepDuration; public TimeSpan TimeToNextStep { get { - long milliseconds = UnixTime.MillisecondsLong; + ulong milliseconds = (ulong)UnixTime.MillisecondsLong; return TimeSpan.FromMilliseconds(((milliseconds / StepDuration) + 1) * StepDuration - milliseconds); } } - public TimeSpan TimeToStep(long step) => + public TimeSpan TimeToStep(ulong step) => throw new NotImplementedException(); - public long CurrentStepDuration => throw new NotImplementedException(); + public ulong CurrentStepDuration => throw new NotImplementedException(); private UnixTime UnixTime => new(DateTimeOffset.UtcNow); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/ChainSpecLoaderTest.cs b/src/Nethermind/Nethermind.AuRa.Test/ChainSpecLoaderTest.cs index cd4052508296..d02f281fe734 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/ChainSpecLoaderTest.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/ChainSpecLoaderTest.cs @@ -72,10 +72,10 @@ public void Can_load_posdao_with_rewriteBytecode() { string path = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Specs/posdao.json"); ChainSpec chainSpec = LoadChainSpec(path); - IDictionary> expected = new Dictionary> + IDictionary> expected = new Dictionary> { { - 21300000, new Dictionary() + 21300000UL, new Dictionary() { {new Address("0x1234000000000000000000000000000000000001"), Bytes.FromHexString("0x111")}, {new Address("0x1234000000000000000000000000000000000002"), Bytes.FromHexString("0x222")}, diff --git a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs index 145244429c38..5baf883e6ed5 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Reward/AuRaRewardCalculatorTests.cs @@ -124,9 +124,9 @@ public static IEnumerable SubsequentTransitionsTestCases { get { - yield return new TestCaseData(10, 100ul, TestItem.AddressA); - yield return new TestCaseData(50, 150ul, TestItem.AddressB); - yield return new TestCaseData(150, 200ul, TestItem.AddressC); + yield return new TestCaseData(10UL, 100ul, TestItem.AddressA); + yield return new TestCaseData(50UL, 150ul, TestItem.AddressB); + yield return new TestCaseData(150UL, 200ul, TestItem.AddressC); } } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs index 6fb72ff317c9..3d85a82a9e69 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs @@ -481,7 +481,7 @@ public static IEnumerable ConsecutiveInitiateChangeData [TestCaseSource(nameof(ConsecutiveInitiateChangeData))] public void consecutive_initiate_change_gets_finalized_and_switch_validators(ConsecutiveInitiateChangeTestParameters test) { - Dictionary hashSeeds = []; + Dictionary hashSeeds = []; Address[] currentValidators = GenerateValidators(1); SetupInitialValidators(currentValidators); @@ -500,18 +500,18 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con blockNumber = test.Current.BlockNumber + i; } - if (hashSeeds.TryGetValue(blockNumber, out int value)) - value++; + if (hashSeeds.TryGetValue(blockNumber, out ulong value)) + hashSeeds[blockNumber] = value + 1; else - hashSeeds[blockNumber] = 0; + hashSeeds[blockNumber] = 0UL; _block.Header.Number = blockNumber; _block.Header.Beneficiary = currentValidators[blockNumber % (ulong)currentValidators.Length]; - _block.Header.AuRaStep = (long)blockNumber; - _block.Header.Hash = Keccak.Compute((blockNumber + (ulong)hashSeeds[blockNumber]).ToString()); + _block.Header.AuRaStep = blockNumber; + _block.Header.Hash = Keccak.Compute((blockNumber + hashSeeds[blockNumber]).ToString()); _block.Header.ParentHash = blockNumber == test.StartBlockNumber ? Keccak.Zero - : Keccak.Compute(((blockNumber - 1UL) + (ulong)hashSeeds[blockNumber - 1UL]).ToString()); + : Keccak.Compute(((blockNumber - 1UL) + hashSeeds[blockNumber - 1UL]).ToString()); TxReceipt[] txReceipts = test.GetReceipts(_validatorContract, _block, _contractAddress, _abiEncoder, SetupAbiAddresses); @@ -529,7 +529,7 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con _blockFinalizationManager.GetLastLevelFinalizedBy(_block.Header.Hash).Returns(finalizedNumber); _blockFinalizationManager.BlocksFinalized += Raise.EventWith( new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(finalizedNumber) - .WithHash(Keccak.Compute((finalizedNumber + (ulong)hashSeeds[finalizedNumber]).ToString())).TestObject)); + .WithHash(Keccak.Compute((finalizedNumber + hashSeeds[finalizedNumber]).ToString())).TestObject)); currentValidators = test.GetCurrentValidators(blockNumber); Assert.That(validator.Validators, Is.EqualTo(currentValidators), $"Validator address should be recognized in block {blockNumber}"); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs index 2bf248a3c5db..853912746022 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs @@ -35,17 +35,17 @@ private static IEnumerable ValidateTestCases { get { - yield return new TestCaseData(TestItem.AddressA, 0L) { ExpectedResult = true }; - yield return new TestCaseData(TestItem.AddressA, 1L) { ExpectedResult = false }; - yield return new TestCaseData(TestItem.AddressB, 1L) { ExpectedResult = true }; - yield return new TestCaseData(TestItem.AddressB, 0L) { ExpectedResult = false }; - yield return new TestCaseData(TestItem.AddressC, 0L) { ExpectedResult = false }; - yield return new TestCaseData(TestItem.AddressC, 1L) { ExpectedResult = false }; + yield return new TestCaseData(TestItem.AddressA, 0UL) { ExpectedResult = true }; + yield return new TestCaseData(TestItem.AddressA, 1UL) { ExpectedResult = false }; + yield return new TestCaseData(TestItem.AddressB, 1UL) { ExpectedResult = true }; + yield return new TestCaseData(TestItem.AddressB, 0UL) { ExpectedResult = false }; + yield return new TestCaseData(TestItem.AddressC, 0UL) { ExpectedResult = false }; + yield return new TestCaseData(TestItem.AddressC, 1UL) { ExpectedResult = false }; } } [TestCaseSource(nameof(ValidateTestCases))] - public bool should_validate_correctly(Address address, long index) => + public bool should_validate_correctly(Address address, ulong index) => _validSealerStrategy.IsValidSealer(GetListValidator(TestItem.AddressA, TestItem.AddressB).Validators, address, index, out _); [TestCase(1)] diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs index 693b74eded3e..a92bbc8e03a5 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/MultiValidatorTests.cs @@ -22,7 +22,7 @@ public class MultiValidatorTests private AuRaParameters.Validator _validator; private IAuRaValidatorFactory _factory; private ILogManager _logManager; - private IDictionary _innerValidators; + private IDictionary _innerValidators; private Block _block; private IAuRaBlockFinalizationManager _finalizationManager; private IBlockTree _blockTree; @@ -32,7 +32,7 @@ public class MultiValidatorTests public void SetUp() { _validator = GetValidator(AuRaParameters.ValidatorType.List); - _innerValidators = new SortedList(); + _innerValidators = new SortedList(); _factory = Substitute.For(); _logManager = LimboLogs.Instance; _finalizationManager = Substitute.For(); @@ -44,7 +44,7 @@ public void SetUp() .ReturnsForAnyArgs(x => { IAuRaValidator innerValidator = Substitute.For(); - _innerValidators[x.Arg() ?? 0] = innerValidator; + _innerValidators[x.Arg() ?? 0UL] = innerValidator; return innerValidator; }); @@ -136,7 +136,7 @@ ulong GetFinalizedIndex(int j) return finalizedIndex == 1 ? finalizedIndex : finalizedIndex + (ulong)blocksToFinalization; } - EnsureInnerValidatorsCalled(i => (_innerValidators[(long)GetFinalizedIndex(i)], callCountPerValidator[i])); + EnsureInnerValidatorsCalled(i => (_innerValidators[GetFinalizedIndex(i)], callCountPerValidator[i])); } [Test] @@ -153,9 +153,9 @@ public void does_not_call_inner_validators_before_start_block() EnsureInnerValidatorsCalled(i => (_innerValidators.ElementAt(i).Value, 0)); } - [TestCase(16UL, ExpectedResult = 11)] - [TestCase(21UL, ExpectedResult = 21)] - public long initializes_validator_when_producing_block(ulong blockNumber) + [TestCase(16UL, ExpectedResult = 11UL)] + [TestCase(21UL, ExpectedResult = 21UL)] + public ulong initializes_validator_when_producing_block(ulong blockNumber) { IAuRaValidator validator = new MultiValidator(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); _block.Header.Number = blockNumber; @@ -164,13 +164,13 @@ public long initializes_validator_when_producing_block(ulong blockNumber) return _innerValidators.Keys.Last(); } - [TestCase(16UL, AuRaParameters.ValidatorType.List, true, ExpectedResult = 11)] - [TestCase(21UL, AuRaParameters.ValidatorType.List, false, ExpectedResult = 21)] - [TestCase(16UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 15)] - [TestCase(23UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 22)] - [TestCase(16UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 1)] - [TestCase(21UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 11)] - public long initializes_validator_when_on_nonconsecutive_block(ulong blockNumber, AuRaParameters.ValidatorType validatorType, bool finalizedLastValidatorBlockLevel) + [TestCase(16UL, AuRaParameters.ValidatorType.List, true, ExpectedResult = 11UL)] + [TestCase(21UL, AuRaParameters.ValidatorType.List, false, ExpectedResult = 21UL)] + [TestCase(16UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 15UL)] + [TestCase(23UL, AuRaParameters.ValidatorType.Contract, true, ExpectedResult = 22UL)] + [TestCase(16UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 1UL)] + [TestCase(21UL, AuRaParameters.ValidatorType.Contract, false, ExpectedResult = 11UL)] + public ulong initializes_validator_when_on_nonconsecutive_block(ulong blockNumber, AuRaParameters.ValidatorType validatorType, bool finalizedLastValidatorBlockLevel) { _validator = GetValidator(validatorType); IAuRaValidator validator = new MultiValidator(_validator, _factory, _blockTree, _validatorStore, _finalizationManager, default, _logManager); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs index 46ad32732437..0184088f3143 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs @@ -79,7 +79,7 @@ public void Resend_malicious_transactions([Values(0, 5, 15)] int validatorsToRep context.ContractBasedValidator.BlockTree.FindHeader(Arg.Any(), BlockTreeLookupOptions.None, blockNumber: Arg.Any()) .Returns(Build.A.BlockHeader.WithNumber(blockNumber - 1).TestObject); - bool isPosDao = blockNumber >= (ulong)context.PosdaoTransition; + bool isPosDao = blockNumber >= context.PosdaoTransition; // resend transactions context.Validator.OnBlockProcessingEnd(block, []); @@ -108,7 +108,7 @@ public void Adds_transactions_to_block([Values(0, 5, 15)] int validatorsToReport } BlockHeader parent = Build.A.BlockHeader.WithNumber(parentBlockNumber).TestObject; - bool isPosDao = parentBlockNumber + 1 >= (ulong)context.PosdaoTransition; + bool isPosDao = parentBlockNumber + 1 >= context.PosdaoTransition; context.ContractBasedValidator.ValidatorContract .ShouldValidatorReport(parent, NodeAddress, MaliciousMinerAddress, Arg.Any()) .Returns(0 < validatorsToReport, Enumerable.Range(1, 15).Select(i => i < validatorsToReport).ToArray()); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs index 88329f10938d..13b924cd048e 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ValidatorStoreTests.cs @@ -26,64 +26,64 @@ public static IEnumerable ValidatorsTests MemDb db = CreateMemDbWithValidators(new[] { - (10L, new[] {TestItem.AddressA}) + (10UL, new[] {TestItem.AddressA}) }); yield return new TestCaseData(db, null, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db1 latest"); - yield return new TestCaseData(db, 11L, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db1 11"); - yield return new TestCaseData(db, 10L, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db1 10"); - yield return new TestCaseData(db, 1L, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db1 1"); + yield return new TestCaseData(db, 11UL, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db1 11"); + yield return new TestCaseData(db, 10UL, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db1 10"); + yield return new TestCaseData(db, 1UL, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db1 1"); db = CreateMemDbWithValidators(new[] { - (1L, new[] {TestItem.AddressA}), - (5L, new[] {TestItem.AddressA, TestItem.AddressB}), - (10L, new[] {TestItem.AddressA, TestItem.AddressC}) + (1UL, new[] {TestItem.AddressA}), + (5UL, new[] {TestItem.AddressA, TestItem.AddressB}), + (10UL, new[] {TestItem.AddressA, TestItem.AddressC}) }); yield return new TestCaseData(db, null, null, new[] { TestItem.AddressA, TestItem.AddressC }).SetCategory("InitializedDb").SetName("Db2 latest"); - yield return new TestCaseData(db, 11L, null, new[] { TestItem.AddressA, TestItem.AddressC }).SetCategory("InitializedDb").SetName("Db2 11"); - yield return new TestCaseData(db, 10L, null, new[] { TestItem.AddressA, TestItem.AddressB }).SetCategory("InitializedDb").SetName("Db2 10"); - yield return new TestCaseData(db, 6L, null, new[] { TestItem.AddressA, TestItem.AddressB }).SetCategory("InitializedDb").SetName("Db2 6"); - yield return new TestCaseData(db, 5L, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db2 5"); - yield return new TestCaseData(db, 2L, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db2 2"); - yield return new TestCaseData(db, 1L, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db2 1"); + yield return new TestCaseData(db, 11UL, null, new[] { TestItem.AddressA, TestItem.AddressC }).SetCategory("InitializedDb").SetName("Db2 11"); + yield return new TestCaseData(db, 10UL, null, new[] { TestItem.AddressA, TestItem.AddressB }).SetCategory("InitializedDb").SetName("Db2 10"); + yield return new TestCaseData(db, 6UL, null, new[] { TestItem.AddressA, TestItem.AddressB }).SetCategory("InitializedDb").SetName("Db2 6"); + yield return new TestCaseData(db, 5UL, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db2 5"); + yield return new TestCaseData(db, 2UL, null, new[] { TestItem.AddressA }).SetCategory("InitializedDb").SetName("Db2 2"); + yield return new TestCaseData(db, 1UL, null, Array.Empty
()).SetCategory("InitializedDb").SetName("Db2 1"); yield return new TestCaseData(CreateMemDbWithValidators(), null, new[] { - (5L, new [] {TestItem.AddressB}) + (5UL, new [] {TestItem.AddressB}) }, new[] { TestItem.AddressB }).SetName("Add one").SetCategory("AddToStore"); yield return new TestCaseData(CreateMemDbWithValidators(), null, new[] { - (5L, new [] {TestItem.AddressB}), - (10L, new [] {TestItem.AddressC}), - (15L, new [] {TestItem.AddressC, TestItem.AddressA}) + (5UL, new [] {TestItem.AddressB}), + (10UL, new [] {TestItem.AddressC}), + (15UL, new [] {TestItem.AddressC, TestItem.AddressA}) }, new[] { TestItem.AddressC, TestItem.AddressA }).SetName("Add multiple, check latest").SetCategory("AddToStore"); - yield return new TestCaseData(CreateMemDbWithValidators(), 12L, new[] + yield return new TestCaseData(CreateMemDbWithValidators(), 12UL, new[] { - (5L, new [] {TestItem.AddressB}), - (10L, new [] {TestItem.AddressC}), - (15L, new [] {TestItem.AddressC, TestItem.AddressA}) + (5UL, new [] {TestItem.AddressB}), + (10UL, new [] {TestItem.AddressC}), + (15UL, new [] {TestItem.AddressC, TestItem.AddressA}) }, new[] { TestItem.AddressC }).SetName("Add multiple, check history").SetCategory("AddToStore"); yield return new TestCaseData(db, null, new[] { - (20L, new [] {TestItem.AddressB}), - (25L, new [] {TestItem.AddressC}), + (20UL, new [] {TestItem.AddressB}), + (25UL, new [] {TestItem.AddressC}), }, new[] { TestItem.AddressC }).SetName("Add multiple, initialized db, check latest").SetCategory("AddToStore"); - yield return new TestCaseData(db, 12L, new[] + yield return new TestCaseData(db, 12UL, new[] { - (20L, new [] {TestItem.AddressB}), - (25L, new [] {TestItem.AddressC}), + (20UL, new [] {TestItem.AddressB}), + (25UL, new [] {TestItem.AddressC}), }, new[] { TestItem.AddressA, TestItem.AddressC }).SetName("Add multiple, initialized db, check history").SetCategory("AddToStore"); } } [TestCaseSource(nameof(ValidatorsTests))] - public void validators_return_as_expected(IDb db, ulong? blockNumber, IEnumerable<(long FinalizingBlock, Address[] Validators)> validatorsToAdd, Address[] expectedValidators) + public void validators_return_as_expected(IDb db, ulong? blockNumber, IEnumerable<(ulong FinalizingBlock, Address[] Validators)> validatorsToAdd, Address[] expectedValidators) { ValidatorStore store = new(db); if (validatorsToAdd is not null) @@ -135,34 +135,33 @@ public void pending_validators_return_as_expected(IDb db, PendingValidators vali public void GetValidators_throws_when_validator_info_missing_from_db() { MemDb db = new(); - db.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, 10L.ToBigEndianByteArrayWithoutLeadingZeros()); + db.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, 10UL.ToBigEndianByteArrayWithoutLeadingZeros()); ValidatorStore store = new(db); Assert.Throws(() => store.GetValidators()); } - private static MemDb CreateMemDbWithValidators(IEnumerable<(long FinalizingBlock, Address[] Validators)> validators = null) + private static MemDb CreateMemDbWithValidators(IEnumerable<(ulong FinalizingBlock, Address[] Validators)> validators = null) { static Hash256 GetKey(in ulong blockNumber) => Keccak.Compute("Validators" + blockNumber); - validators ??= Array.Empty<(long FinalizingBlock, Address[] Validators)>(); - (long FinalizingBlock, Address[] Validators)[] ordered = validators.OrderByDescending(static v => v.FinalizingBlock).ToArray(); + validators ??= Array.Empty<(ulong FinalizingBlock, Address[] Validators)>(); + (ulong FinalizingBlock, Address[] Validators)[] ordered = validators.OrderByDescending(static v => v.FinalizingBlock).ToArray(); MemDb memDb = new(); for (int i = 0; i < ordered.Length; i++) { - (long FinalizingBlock, Address[] Validators) current = ordered[i]; - (long FinalizingBlock, Address[] Validators) next = i + 1 < ordered.Length ? ordered[i + 1] : (-1L, Array.Empty
()); + (ulong FinalizingBlock, Address[] Validators) current = ordered[i]; + (ulong FinalizingBlock, Address[] Validators) next = i + 1 < ordered.Length ? ordered[i + 1] : (ulong.MaxValue, Array.Empty
()); - // Safe: FinalizingBlock is a block number, always non-negative - ValidatorInfo validatorInfo = new((ulong)current.FinalizingBlock, (ulong)next.FinalizingBlock, current.Validators); + ValidatorInfo validatorInfo = new(current.FinalizingBlock, next.FinalizingBlock, current.Validators); if (i == 0) { - memDb.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, ((ulong)current.FinalizingBlock).ToBigEndianByteArrayWithoutLeadingZeros()); + memDb.Set(ValidatorStore.LatestFinalizedValidatorsBlockNumberKey, current.FinalizingBlock.ToBigEndianByteArrayWithoutLeadingZeros()); } - memDb.Set(GetKey((ulong)current.FinalizingBlock), Rlp.Encode(validatorInfo).Bytes); + memDb.Set(GetKey(current.FinalizingBlock), Rlp.Encode(validatorInfo).Bytes); } return memDb; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs index 4ee7b0b6fa00..e75f504a8af0 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs @@ -266,7 +266,7 @@ public async Task Can_prune_old_forks() { const ulong depth = BlockhashCache.MaxDepth * 5 + 1; (BlockTree tree, BlockhashCache cache) = BuildTest((int)depth); - for (ulong i = (ulong)BlockhashCache.MaxDepth; i < depth; i += (ulong)BlockhashCache.MaxDepth) + for (ulong i = BlockhashCache.MaxDepth; i < depth; i += BlockhashCache.MaxDepth) { cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, BlockhashCache.MaxDepth); } @@ -306,7 +306,7 @@ public async Task Prefetch_reuses_parent_data(ulong chainDepth) Hash256[] prevHashes = (await cache.Prefetch(prev, CancellationToken.None))!; Hash256[] headHashes = (await cache.Prefetch(head, CancellationToken.None))!; - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)Math.Min(chainDepth - 1ul, (ulong)FlatCacheItemLength), 1, 2))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)Math.Min(chainDepth - 1ul, FlatCacheItemLength), 1, 2))); Assert.Multiple(() => { int compareLength = headHashes.Length - 1; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs index 8a31b5a7cf8a..882d223bc7a0 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Bloom/BloomStorageTests.cs @@ -71,8 +71,8 @@ public static IEnumerable GetBloomsTestCases static IEnumerable GetRange(long expectedFound, int offset = 0) => Enumerable.Range(offset, (int)expectedFound).Select(static i => (ulong)i); int searchesPerBucket = 1 + LevelMultiplier + LevelMultiplier * LevelMultiplier + LevelMultiplier * LevelMultiplier * LevelMultiplier; - int bucketItems = new BloomStorage(new BloomConfig() { IndexLevelBucketSizes = new[] { LevelMultiplier, LevelMultiplier, LevelMultiplier } }, new MemDb(), new InMemoryDictionaryFileStoreFactory()).MaxBucketSize; - int count = bucketItems * Buckets; + int bucketItems = (int)new BloomStorage(new BloomConfig() { IndexLevelBucketSizes = new[] { LevelMultiplier, LevelMultiplier, LevelMultiplier } }, new MemDb(), new InMemoryDictionaryFileStoreFactory()).MaxBucketSize; + int count = bucketItems * (int)Buckets; int maxIndex = count - 1; yield return new TestCaseData(0UL, (ulong)maxIndex, false, Enumerable.Empty(), Buckets) .SetName("Returns_no_blocks_when_blooms_do_not_match"); @@ -150,15 +150,15 @@ public void Can_find_bloom_with_fromBlock_offset(ulong from, ulong to, ulong[] b Assert.That(foundBlocks, Is.EqualTo(expectedFoundBlocks)); } - private const int Buckets = 3; + private const uint Buckets = 3; private const int LevelMultiplier = 16; private static BloomStorage CreateBloomStorage(BloomConfig? bloomConfig = null) { BloomStorage storage = new(bloomConfig ?? new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); - int bucketItems = storage.MaxBucketSize * Buckets; + ulong bucketItems = storage.MaxBucketSize * Buckets; - for (ulong i = 0; i < (ulong)bucketItems; i++) + for (ulong i = 0; i < bucketItems; i++) { storage.Store(i, Core.Bloom.Empty); } @@ -168,11 +168,11 @@ private static BloomStorage CreateBloomStorage(BloomConfig? bloomConfig = null) [MaxTime(Timeout.MaxTestTime)] [TestCase(byte.MaxValue)] - [TestCase(ushort.MaxValue / 4)] + [TestCase(ushort.MaxValue / 4u)] [TestCase(ushort.MaxValue, Explicit = true)] - [TestCase(ushort.MaxValue * 8 + 7, Explicit = true)] - [TestCase(ushort.MaxValue * 128 + 127, Explicit = true)] - public void Can_safely_insert_concurrently(int maxBlock) => RunInsertAndVerify(maxBlock, (storage, count) => + [TestCase(ushort.MaxValue * 8u + 7u, Explicit = true)] + [TestCase(ushort.MaxValue * 128u + 127u, Explicit = true)] + public void Can_safely_insert_concurrently(uint maxBlock) => RunInsertAndVerify(maxBlock, (storage, count) => { Parallel.For(0, count, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 16 }, @@ -186,11 +186,11 @@ public void Can_safely_insert_concurrently(int maxBlock) => RunInsertAndVerify(m [MaxTime(Timeout.MaxTestTime)] [TestCase(byte.MaxValue)] - [TestCase(ushort.MaxValue / 4)] + [TestCase(ushort.MaxValue / 4u)] [TestCase(ushort.MaxValue, Explicit = true)] - [TestCase(ushort.MaxValue * 8 + 7, Explicit = true)] - [TestCase(ushort.MaxValue * 128 + 127, Explicit = true)] - public void Can_safely_insert_in_batch(int maxBlock) => RunInsertAndVerify(maxBlock, (storage, count) => + [TestCase(ushort.MaxValue * 8u + 7u, Explicit = true)] + [TestCase(ushort.MaxValue * 128u + 127u, Explicit = true)] + public void Can_safely_insert_in_batch(uint maxBlock) => RunInsertAndVerify(maxBlock, (storage, count) => { using ArrayPoolList<(ulong, Core.Bloom)> bloomInsertions = new(count); for (int i = 0; i < count; i++) @@ -202,7 +202,7 @@ public void Can_safely_insert_in_batch(int maxBlock) => RunInsertAndVerify(maxBl storage.Store(bloomInsertions); }); - private static void RunInsertAndVerify(int maxBlock, Action insertAction) + private static void RunInsertAndVerify(uint maxBlock, Action insertAction) { BloomConfig config = new() { IndexLevelBucketSizes = new[] { 16, 16, 16 } }; TempPath tempPath = TempPath.GetTempDirectory(); @@ -212,16 +212,16 @@ private static void RunInsertAndVerify(int maxBlock, Action i FixedSizeFileStoreFactory fileStorageFactory = new(basePath, DbNames.Bloom, Core.Bloom.ByteLength); using BloomStorage storage = new(config, new MemDb(), fileStorageFactory); - insertAction(storage, maxBlock + 1); + insertAction(storage, (int)maxBlock + 1); - IBloomEnumeration blooms = storage.GetBlooms(0, (ulong)maxBlock); + IBloomEnumeration blooms = storage.GetBlooms(0, maxBlock); int j = 0; foreach (Core.Bloom bloom in blooms) { j++; (ulong FromBlock, ulong ToBlock) = blooms.CurrentIndices; int fromBlock = (int)(FromBlock % Core.Bloom.BitLength); - int toBlock = (int)(Math.Min(ToBlock, (ulong)maxBlock) % Core.Bloom.BitLength); + int toBlock = (int)(Math.Min(ToBlock, maxBlock) % Core.Bloom.BitLength); Core.Bloom expectedBloom = new(); for (int i = fromBlock; i <= toBlock; i++) { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs index dfd6027459a5..961d13961e35 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs @@ -119,14 +119,14 @@ public void Eip8037_creation_tx_regular_check_actual_usage_modest_accepts() Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; Transaction createTx = Build.A.Transaction.WithHash(TestItem.KeccakB) .WithCode([]) - .WithGasLimit(53_000ul + (ulong)IntrinsicNewAccountState) + .WithGasLimit(53_000ul + IntrinsicNewAccountState) .WithNonce(1ul).TestObject; (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, filler, createTx); GasValidationResultSlot[] results = ResultsForCount(2); // Filler used full cap; create tx used modest regular + intrinsic state. results[0].TrySetResult(GasResult(block, 0, 16_777_216ul, 0ul)); - results[1].TrySetResult(GasResult(block, 1, 53_000ul, (ulong)IntrinsicNewAccountState)); + results[1].TrySetResult(GasResult(block, 1, 53_000ul, IntrinsicNewAccountState)); Assert.DoesNotThrow(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None)); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs index 9ca31132cc5e..099425ecf792 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs @@ -374,8 +374,8 @@ private static IEnumerable EnumerateOnce(IEnumerator enumerator) yield return enumerator.Current; } - private const long FromBlock = 0; - private const long ToBlock = 99; + private const ulong FromBlock = 0; + private const ulong ToBlock = 99; private static readonly Ranges LogIndexRanges = GenerateLogIndexRanges(); @@ -386,6 +386,7 @@ private static Ranges GenerateLogIndexRanges() Dictionary> addressRanges = []; foreach (Address address in new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD, TestItem.AddressE }) { + // Narrowing ulong -> int is safe here: FromBlock/ToBlock are small test constants (0..99), no overflow risk. List range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.3).ToList(); addressRanges.Add(address, range); } @@ -398,6 +399,7 @@ private static Ranges GenerateLogIndexRanges() { foreach (Hash256 topic in new[] { TestItem.KeccakA, TestItem.KeccakB, TestItem.KeccakC, TestItem.KeccakD, TestItem.KeccakE }) { + // Narrowing ulong -> int is safe here: FromBlock/ToBlock are small test constants (0..99), no overflow risk. List range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.2).ToList(); ranges.Add(topic, range); } @@ -407,6 +409,6 @@ private static Ranges GenerateLogIndexRanges() } private static FilterBuilder BuildFilter() => FilterBuilder.New() - .FromBlock((ulong)FromBlock) - .ToBlock((ulong)ToBlock); + .FromBlock(FromBlock) + .ToBlock(ToBlock); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/PrecompileCachedCodeInfoRepositoryTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/PrecompileCachedCodeInfoRepositoryTests.cs index c9a58c53f1ae..0f3c22b2b766 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/PrecompileCachedCodeInfoRepositoryTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/PrecompileCachedCodeInfoRepositoryTests.cs @@ -516,9 +516,9 @@ private class TestPrecompile(bool supportsCaching, Action? onRun = null, byte[]? { public bool SupportsCaching => supportsCaching; - public long BaseGasCost(IReleaseSpec releaseSpec) => 0; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 0UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0UL; public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { @@ -534,9 +534,9 @@ private class TruncatingTestPrecompile(int effectiveLength, Action? onRun = null public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) => inputData.Length > effectiveLength ? inputData[..effectiveLength] : inputData; - public long BaseGasCost(IReleaseSpec releaseSpec) => 0; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 0UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0UL; public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { @@ -551,9 +551,9 @@ private class FixedLengthTestPrecompile(int validLength, Action? onRun = null) : { public bool SupportsCaching => true; - public long BaseGasCost(IReleaseSpec releaseSpec) => 0; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 0UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0UL; public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs index bdb9899a4084..8aef4442409e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/ReceiptTrieTests.cs @@ -64,9 +64,9 @@ public void Parallel_and_non_parallel_root_hashing_produce_same_root() const int receiptCount = 100; IReleaseSpec spec = MainnetSpecProvider.Instance.GetSpec((MainnetSpecProvider.MuirGlacierBlockNumber, null)); TxReceipt[] receipts = new TxReceipt[receiptCount]; - for (int i = 0; i < receiptCount; i++) + for (uint i = 0; i < receiptCount; i++) { - receipts[i] = Build.A.Receipt.WithAllFieldsFilled.WithGasUsedTotal((ulong)(1000 + i)).TestObject; + receipts[i] = Build.A.Receipt.WithAllFieldsFilled.WithGasUsedTotal(1000 + i).TestObject; } using TrackingCappedArrayPool parallelPool = new(receiptCount * 4, canBeParallel: true); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs index f65009d73e99..1c0392f53f43 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs @@ -105,9 +105,9 @@ public void Parallel_and_non_parallel_root_hashing_produce_same_root() { const int txCount = 100; Transaction[] transactions = new Transaction[txCount]; - for (int i = 0; i < txCount; i++) + for (uint i = 0; i < txCount; i++) { - transactions[i] = Build.A.Transaction.WithNonce((ulong)(i + 1)).Signed().TestObject; + transactions[i] = Build.A.Transaction.WithNonce(i + 1).Signed().TestObject; } using TrackingCappedArrayPool pool = new(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index 3ed8c6e410b7..2061e1b95891 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -81,7 +81,11 @@ public void Valid_when_valid() [TestCase(-1, true, TestName = "When_gas_limit_just_correct_high")] public void When_gas_limit_above_parent(int adjustment, bool expectedResult) { - _block.Header.GasLimit = (ulong)((long)_parentBlock.Header.GasLimit + (long)_parentBlock.Header.GasLimit / 1024 + adjustment); + ulong delta = _parentBlock.Header.GasLimit / 1024ul; + + _block.Header.GasLimit = adjustment >= 0 + ? _parentBlock.Header.GasLimit + delta + (ulong)adjustment + : _parentBlock.Header.GasLimit + delta - (ulong)(-adjustment); _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); @@ -93,7 +97,11 @@ public void When_gas_limit_above_parent(int adjustment, bool expectedResult) [TestCase(0, false, TestName = "When_gas_limit_is_just_too_low")] public void When_gas_limit_below_parent(int adjustment, bool expectedResult) { - _block.Header.GasLimit = (ulong)((long)_parentBlock.Header.GasLimit - (long)_parentBlock.Header.GasLimit / 1024 + adjustment); + ulong delta = _parentBlock.Header.GasLimit / 1024ul; + + _block.Header.GasLimit = adjustment >= 0 + ? _parentBlock.Header.GasLimit + delta + (ulong)adjustment + : _parentBlock.Header.GasLimit + delta - (ulong)(-adjustment); _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs index 3647ace77c49..5ab0c6122008 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs @@ -346,7 +346,7 @@ private void LoadSyncPivot() byte[]? pivotFromDb = _metadataDb.Get(MetadataDbKeys.UpdatedPivotData); if (pivotFromDb is null) { - _syncPivot = ((ulong)_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); + _syncPivot = (_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); return; } @@ -356,7 +356,7 @@ private void LoadSyncPivot() if (updatedPivotBlockHash.IsZero) { - _syncPivot = ((ulong)_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); + _syncPivot = (_syncConfig.PivotNumber, _syncConfig.PivotHash is null ? null : new Hash256(Bytes.FromHexString(_syncConfig.PivotHash))); return; } diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs index b9926ca759bd..a02481af2efd 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs @@ -26,7 +26,7 @@ public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spe if (!worldState.IsContract(eip2935Account)) return; Hash256 parentBlockHash = blockHeader.ParentHash; - UInt256 parentBlockIndex = new((blockHeader.Number - 1) % (ulong)spec.Eip2935RingBufferSize); + UInt256 parentBlockIndex = new((blockHeader.Number - 1) % spec.Eip2935RingBufferSize); StorageCell blockHashStoreCell = new(eip2935Account, parentBlockIndex); worldState.Set(blockHashStoreCell, parentBlockHash!.Bytes.WithoutLeadingZeros().ToArray()); } @@ -39,7 +39,7 @@ public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spe { return null; } - UInt256 blockIndex = new((ulong)(requiredBlockNumber % spec.Eip2935RingBufferSize)); + UInt256 blockIndex = new(requiredBlockNumber % spec.Eip2935RingBufferSize); Address? eip2935Account = spec.Eip2935ContractAddress ?? Eip2935Constants.BlockHashHistoryAddress; StorageCell blockHashStoreCell = new(eip2935Account, blockIndex); ReadOnlySpan data = worldState.Get(blockHashStoreCell); diff --git a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs index 336e3fed2116..26a95459207c 100644 --- a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs +++ b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs @@ -164,7 +164,7 @@ await WaitForMainChainChange((e) => }, cancellationToken); ulong stateToCopy = _blockTree.BestPersistedState.Value; - ulong blockToPruneAfter = stateToCopy + (ulong)_pruningConfig.PruningBoundary; + ulong blockToPruneAfter = stateToCopy + _pruningConfig.PruningBoundary; await WaitForMainChainChange((e) => { diff --git a/src/Nethermind/Nethermind.Blockchain/PrecompileCachedCodeInfoRepository.cs b/src/Nethermind/Nethermind.Blockchain/PrecompileCachedCodeInfoRepository.cs index 6fd680b48e7b..49422951cefb 100644 --- a/src/Nethermind/Nethermind.Blockchain/PrecompileCachedCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Blockchain/PrecompileCachedCodeInfoRepository.cs @@ -66,9 +66,9 @@ private class CachedPrecompile( IPrecompile precompile, ConcurrentDictionary> cache) : IPrecompile { - public long BaseGasCost(IReleaseSpec releaseSpec) => precompile.BaseGasCost(releaseSpec); + public ulong BaseGasCost(IReleaseSpec releaseSpec) => precompile.BaseGasCost(releaseSpec); - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => precompile.DataGasCost(inputData, releaseSpec); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => precompile.DataGasCost(inputData, releaseSpec); public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs index 483b0c8d8094..fd923472d566 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs @@ -155,7 +155,7 @@ public interface ISyncConfig : IConfig bool? SnapServingEnabled { get; set; } [ConfigItem(Description = "The maximum depth (in blocks) for serving snap sync requests. Higher values allow serving requests for older blocks, useful for networks with fast block times like Arbitrum.", DefaultValue = "128")] - int SnapServingMaxDepth { get; set; } + ulong SnapServingMaxDepth { get; set; } [ConfigItem(Description = "_Technical._ Max trie paths per group accepted in snap GetTrieNodes messages. Raise if peers send slightly larger groups (e.g. Geth trienodeHealThrottle sends 1025).", DefaultValue = "1024", HiddenFromDocs = true)] int SnapServingMaxPathsPerGroup { get; set; } @@ -182,13 +182,13 @@ public interface ISyncConfig : IConfig int StateMaxDistanceFromHead { get; set; } [ConfigItem(Description = "_Technical._ Min distance of state sync from best suggested header.", DefaultValue = "32", HiddenFromDocs = true)] - int StateMinDistanceFromHead { get; set; } + ulong StateMinDistanceFromHead { get; set; } [ConfigItem(Description = "_Technical._ Run explicit GC after state sync finished.", DefaultValue = "true", HiddenFromDocs = true)] bool GCOnFeedFinished { get; set; } [ConfigItem(Description = "_Technical._ Max distance between best suggested header and available state to assume state is synced.", DefaultValue = "0", HiddenFromDocs = true)] - int HeaderStateDistance { get; set; } + ulong HeaderStateDistance { get; set; } [ConfigItem(Description = "_Technical._ Memory budget for in memory dependencies of fast headers.", DefaultValue = "0", HiddenFromDocs = true)] ulong FastHeadersMemoryBudget { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index acb731685ee7..7da799f4c630 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -70,7 +70,7 @@ public string? PivotHash public int ExitOnSyncedWaitTimeSec { get; set; } = 60; public int MallocTrimIntervalSec { get; set; } = 300; public bool? SnapServingEnabled { get; set; } = null; - public int SnapServingMaxDepth { get; set; } = 128; + public ulong SnapServingMaxDepth { get; set; } = 128; public int SnapServingMaxPathsPerGroup { get; set; } = 1024; public int MultiSyncModeSelectorLoopTimerMs { get; set; } = 1000; public int AllocationSlots { get; set; } = 2; @@ -80,14 +80,14 @@ public string? PivotHash public bool VerifyTrieOnStateSyncFinished { get; set; } public bool TrieHealing { get; set; } = true; public int StateMaxDistanceFromHead { get; set; } = 128; - public int StateMinDistanceFromHead { get; set; } = 32; + public ulong StateMinDistanceFromHead { get; set; } = 32; public bool GCOnFeedFinished { get; set; } = true; /// /// Additional delay in blocks between best suggested header and synced state to allow faster state switching for PoW chains /// with higher block processing frequency. Effectively this is the max allowed difference between best header (used as sync /// pivot) and synced state block, to assume that state is synced and node can start processing blocks /// - public int HeaderStateDistance { get; set; } = 0; + public ulong HeaderStateDistance { get; set; } = 0; public ulong FastHeadersMemoryBudget { get; set; } = (ulong)128.MB; public bool EnableSnapSyncStorageRangeSplit { get; set; } = false; diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Db.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Db.cs index 7a2d0eaf5739..0cce6e6a3ac7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Db.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GethStyle/Custom/JavaScript/Db.cs @@ -15,7 +15,7 @@ public class Db(IWorldState worldState) public IJavaScriptObject getBalance(object address) => WorldState.GetBalance(address.ToAddress()).ToBigInteger(); - public ulong getNonce(object address) => (ulong)WorldState.GetNonce(address.ToAddress()); + public ulong getNonce(object address) => WorldState.GetNonce(address.ToAddress()); public ITypedArray getCode(object address) => WorldState.GetCode(address.ToAddress()).ToTypedScriptArray(); diff --git a/src/Nethermind/Nethermind.Config/BlocksConfig.cs b/src/Nethermind/Nethermind.Config/BlocksConfig.cs index 330e1c6512f2..b5323ac6803a 100644 --- a/src/Nethermind/Nethermind.Config/BlocksConfig.cs +++ b/src/Nethermind/Nethermind.Config/BlocksConfig.cs @@ -49,7 +49,7 @@ private static string GetDefaultVersionExtraData() } public bool Enabled { get; set; } - public long? TargetBlockGasLimit { get; set; } = null; + public ulong? TargetBlockGasLimit { get; set; } = null; public UInt256 MinGasPrice { get; set; } = 1.Wei; diff --git a/src/Nethermind/Nethermind.Config/IBlocksConfig.cs b/src/Nethermind/Nethermind.Config/IBlocksConfig.cs index 3661dde86f2a..d4ddf058c6e3 100644 --- a/src/Nethermind/Nethermind.Config/IBlocksConfig.cs +++ b/src/Nethermind/Nethermind.Config/IBlocksConfig.cs @@ -16,7 +16,7 @@ public interface IBlocksConfig : IConfig [ConfigItem( Description = "The block gas limit that the block producer should try to reach in the fastest possible way based on the protocol rules. If not specified, then the block producer should follow others.", DefaultValue = "null")] - long? TargetBlockGasLimit { get; set; } + ulong? TargetBlockGasLimit { get; set; } [ConfigItem( Description = "The minimum gas premium (or the gas price before the London hard fork) for transactions accepted by the block producer.", diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs index 576eeb9e0938..0b131eb2e8c9 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs @@ -342,7 +342,7 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) private int GetMinSealersForFinalization(ulong blockNumber) => blockNumber == 0 ? 1 - : _validatorStore.GetValidators(blockNumber).MinSealersForFinalization(blockNumber >= (ulong)twoThirdsMajorityTransition); + : _validatorStore.GetValidators(blockNumber).MinSealersForFinalization(blockNumber >= twoThirdsMajorityTransition); public ulong LastFinalizedBlockLevel { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs index 6d4c00ca880b..867f0bd95a7f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs @@ -56,7 +56,7 @@ public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle } else { - long step = header.AuRaStep.Value; + ulong step = header.AuRaStep.Value; if (step == parent.AuRaStep) { @@ -82,7 +82,7 @@ public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle } } - long currentStep = _stepCalculator.CurrentStep; + ulong currentStep = _stepCalculator.CurrentStep; if (step > currentStep + rejectedStepDrift) { @@ -174,9 +174,9 @@ private readonly struct AuthorBlock(Address author, Hash256 block) : IEquatable< public static bool operator !=(AuthorBlock obj1, AuthorBlock obj2) => !obj1.Equals(obj2); } - private class AuthorBlockForStep(in long step, ReceivedSteps.AuthorBlock? authorBlock) + private class AuthorBlockForStep(in ulong step, ReceivedSteps.AuthorBlock? authorBlock) { - public long Step { get; } = step; + public ulong Step { get; } = step; public AuthorBlock? AuthorBlock { get; set; } = authorBlock; public ISet AuthorBlocks { get; set; } } @@ -197,7 +197,7 @@ public bool ContainsSiblingOrInsert(BlockHeader header, int validatorCount) { using McsLock.Disposable _ = _lock.Acquire(); - long step = header.AuRaStep.Value; + ulong step = header.AuRaStep.Value; Address author = header.Beneficiary; Hash256 hash = header.Hash; int index = BinarySearch(step); @@ -234,17 +234,17 @@ public bool ContainsSiblingOrInsert(BlockHeader header, int validatorCount) return containsSibling; } - private int BinarySearch(long step) => _list.BinarySearch(new AuthorBlockForStep(step, null), StepElementComparer.Instance); + private int BinarySearch(ulong step) => _list.BinarySearch(new AuthorBlockForStep(step, null), StepElementComparer.Instance); /// /// Remove hash records older than two full N of steps (picked as a reasonable trade-off between memory consumption and fault-tolerance). /// /// /// - private void ClearOldCache(long step, int validatorCount) + private void ClearOldCache(ulong step, int validatorCount) { - int siblingMaliceDetectionPeriod = CacheSizeFullRoundsMultiplier * validatorCount; - long oldestStepToKeep = step - siblingMaliceDetectionPeriod; + ulong siblingMaliceDetectionPeriod = (ulong)CacheSizeFullRoundsMultiplier * (ulong)validatorCount; + ulong oldestStepToKeep = step > siblingMaliceDetectionPeriod ? step - siblingMaliceDetectionPeriod : 0UL; int index = BinarySearch(oldestStepToKeep); int positiveIndex = index >= 0 ? index : ~index; if (positiveIndex > 0) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs index ad3aae6c7b06..8ca24375d0c8 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealer.cs @@ -62,17 +62,17 @@ private Block Seal(Block block) public bool CanSeal(ulong blockNumber, Hash256 parentHash) { - bool StepNotYetProduced(long step) => !_blockTree.Head.Header.AuRaStep.HasValue + bool StepNotYetProduced(ulong step) => !_blockTree.Head.Header.AuRaStep.HasValue ? throw new InvalidOperationException("Head block doesn't have AuRaStep specified.'") : _blockTree.Head.Header.AuRaStep.Value < step; - bool IsThisNodeTurn(long step) + bool IsThisNodeTurn(ulong step) { Address[] validators = _validatorStore.GetValidators(); return _validSealerStrategy.IsValidSealer(validators, _signer.Address, step, out _); } - long currentStep = _auRaStepCalculator.CurrentStep; + ulong currentStep = _auRaStepCalculator.CurrentStep; bool stepNotYetProduced = StepNotYetProduced(currentStep); bool isThisNodeTurn = IsThisNodeTurn(currentStep); if (isThisNodeTurn) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs index e1bfa43e93ac..635da0d63aa9 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs @@ -23,22 +23,22 @@ public AuRaStepCalculator(IDictionary stepDurations, ITimestamper t _timestamper = timestamper ?? throw new ArgumentNullException(nameof(timestamper)); } - public long CurrentStep + public ulong CurrentStep { get { ulong timestampSeconds = _timestamper.UnixTime.Seconds; - return (long)GetStepInfo(timestampSeconds).GetCurrentStep(timestampSeconds); + return GetStepInfo(timestampSeconds).GetCurrentStep(timestampSeconds); } } public TimeSpan TimeToNextStep => new(TimeToNextStepInTicks); - public TimeSpan TimeToStep(long step) + public TimeSpan TimeToStep(ulong step) { UnixTime epoch = _timestamper.UnixTime; StepDurationInfo currentStepInfo = GetStepInfo(epoch.Seconds); - long currentStep = (long)currentStepInfo.GetCurrentStep(epoch.Seconds); + ulong currentStep = currentStepInfo.GetCurrentStep(epoch.Seconds); if (step <= currentStep) { return TimeSpan.Zero; @@ -47,16 +47,16 @@ public TimeSpan TimeToStep(long step) { TimeSpan timeToNextStep = new(GetTimeToNextStepInTicks(epoch, currentStepInfo)); // Safe cast: StepDuration is capped at UInt16.MaxValue (65535) so fits in long - return timeToNextStep + TimeSpan.FromSeconds((long)currentStepInfo.StepDuration * (step - currentStep - 1)); + return timeToNextStep + TimeSpan.FromSeconds((long)currentStepInfo.StepDuration * (long)(step - currentStep - 1)); } } - public long CurrentStepDuration + public ulong CurrentStepDuration { get { UnixTime epoch = _timestamper.UnixTime; - return (long)GetStepInfo(epoch.Seconds).StepDuration; + return GetStepInfo(epoch.Seconds).StepDuration; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs index b72a54374889..08cfe90841f9 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs @@ -13,16 +13,17 @@ public class AuraDifficultyCalculator(IAuRaStepCalculator auRaStepCalculator) : static AuraDifficultyCalculator() => MaxDifficulty = UInt256.UInt128MaxValue; - public static UInt256 CalculateDifficulty(long parentStep, long currentStep, long emptyStepsCount = 0L) + public static UInt256 CalculateDifficulty(ulong parentStep, ulong currentStep, ulong emptyStepsCount = 0UL) { - long mod = parentStep - currentStep + emptyStepsCount; - if (mod > 0) + if (parentStep + emptyStepsCount >= currentStep) { - return MaxDifficulty + (UInt256)mod; + ulong diff = parentStep + emptyStepsCount - currentStep; + return MaxDifficulty + (UInt256)diff; } else { - return MaxDifficulty - (UInt256)(-mod); + ulong diff = currentStep - (parentStep + emptyStepsCount); + return MaxDifficulty - (UInt256)diff; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaStepCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaStepCalculator.cs index e28432c2d70f..85c5a2247ab1 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaStepCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/IAuRaStepCalculator.cs @@ -7,10 +7,10 @@ namespace Nethermind.Consensus.AuRa { public interface IAuRaStepCalculator { - long CurrentStep { get; } + ulong CurrentStep { get; } TimeSpan TimeToNextStep { get; } - TimeSpan TimeToStep(long step); + TimeSpan TimeToStep(ulong step); - long CurrentStepDuration { get; } + ulong CurrentStepDuration { get; } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Metrics.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Metrics.cs index 762543bd6845..0e38e29dbb25 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Metrics.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Metrics.cs @@ -10,7 +10,7 @@ public static class Metrics { [GaugeMetric] [Description("Current AuRa step")] - public static long AuRaStep { get; set; } + public static ulong AuRaStep { get; set; } [CounterMetric] [Description("Number of reported benign misbehaviour validators")] diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs index 5345b206e9d6..da228fc9ed51 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs @@ -56,7 +56,7 @@ private ulong CalculateNonce(Address address, BlockHeader baseBlock, IDictionary { if (!nonces.TryGetValue(address, out ulong nonce)) { - nonce = (ulong)_stateReader.GetNonce(baseBlock, address); + nonce = _stateReader.GetNonce(baseBlock, address); } nonces[address] = nonce + 1; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs index d83caf208da7..5e6e91daf5c5 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorBase.cs @@ -39,7 +39,7 @@ public virtual void OnBlockProcessingStart(Block block, ProcessingOptions option { if (!options.ContainsFlag(ProcessingOptions.ProducingBlock) && !block.IsGenesis) { - long auRaStep = block.Header.AuRaStep.Value; + ulong auRaStep = block.Header.AuRaStep.Value; if (!_validSealerStrategy.IsValidSealer(Validators, block.Beneficiary, auRaStep, out Address expectedAddress)) { string reason = $"Incorrect proposer at step {auRaStep}, expected {expectedAddress}, but found {block.Beneficiary}"; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs index a58235ab6e08..f35303543f42 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ContractBasedValidator.cs @@ -189,7 +189,7 @@ private void FinalizePendingValidatorsIfNeeded(BlockHeader block, bool isProduci { ValidatorInfo validatorsInfo = ValidatorStore.GetValidatorsInfo(block.Number); bool isInitialValidatorSet = validatorsInfo.FinalizingBlockNumber == InitBlockNumber - && validatorsInfo.PreviousFinalizingBlockNumber < InitBlockNumber; + && (validatorsInfo.PreviousFinalizingBlockNumber == ulong.MaxValue || validatorsInfo.PreviousFinalizingBlockNumber < InitBlockNumber); if (InitBlockNumber == block.Number || (!isInitialValidatorSet && validatorsInfo.FinalizingBlockNumber == block.Number - 1)) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidSealerStrategy.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidSealerStrategy.cs index d09c0ada06a8..8d20983dff0b 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidSealerStrategy.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/IValidSealerStrategy.cs @@ -16,6 +16,6 @@ public interface IValidSealerStrategy /// Step to be checked. /// Address which should create block in current step. /// 'true' if should seal a block at for supplied collection. Otherwise 'false'. - bool IsValidSealer(IList
validators, Address address, long step, out Address expectedAddress); + bool IsValidSealer(IList
validators, Address address, ulong step, out Address expectedAddress); } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs index a4cd8365007b..618650556d01 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ReportingContractBasedValidator.cs @@ -175,7 +175,7 @@ public void TryReportSkipped(BlockHeader header, BlockHeader parent) $"CurrentValidators [{(string.Join(", ", validators.AsEnumerable()))}"); ISet
reported = new HashSet
(); - for (long step = parent.AuRaStep.Value + 1; step < header.AuRaStep.Value; step++) + for (ulong step = parent.AuRaStep.Value + 1; step < header.AuRaStep.Value; step++) { Address? skippedValidator = validators.GetItemRoundRobin(step); if (skippedValidator is not null) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidSealerStrategy.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidSealerStrategy.cs index 6bb197563862..317848f2dcf6 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidSealerStrategy.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidSealerStrategy.cs @@ -9,7 +9,7 @@ namespace Nethermind.Consensus.AuRa.Validators { public class ValidSealerStrategy : IValidSealerStrategy { - public bool IsValidSealer(IList
validators, Address address, long step, out Address expectedAddress) => + public bool IsValidSealer(IList
validators, Address address, ulong step, out Address expectedAddress) => (expectedAddress = validators.GetItemRoundRobin(step)) == address; } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs index 1f8d1dac4cea..eabfbe51bb9d 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs @@ -32,7 +32,7 @@ public ValidatorStore([KeyFilter(DbNames.BlockInfos)] IDb db) public void SetValidators(ulong finalizingBlockNumber, Address[] validators) { - if (finalizingBlockNumber > _latestFinalizedValidatorsBlockNumber) + if (_latestFinalizedValidatorsBlockNumber == EmptyBlockNumber || finalizingBlockNumber > _latestFinalizedValidatorsBlockNumber) { ValidatorInfo validatorInfo = new(finalizingBlockNumber, _latestFinalizedValidatorsBlockNumber == EmptyBlockNumber ? EmptyBlockNumber : _latestFinalizedValidatorsBlockNumber, validators); Rlp rlp = Rlp.Encode(validatorInfo); @@ -45,11 +45,11 @@ public void SetValidators(ulong finalizingBlockNumber, Address[] validators) } - public Address[] GetValidators(in ulong? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber + public Address[] GetValidators(in ulong? blockNumber = null) => blockNumber is null || _latestFinalizedValidatorsBlockNumber == EmptyBlockNumber || blockNumber > _latestFinalizedValidatorsBlockNumber ? GetLatestValidatorInfo().Validators : FindValidatorInfo(blockNumber.Value).Validators; - public ValidatorInfo GetValidatorsInfo(in ulong? blockNumber = null) => blockNumber is null || blockNumber > _latestFinalizedValidatorsBlockNumber + public ValidatorInfo GetValidatorsInfo(in ulong? blockNumber = null) => blockNumber is null || _latestFinalizedValidatorsBlockNumber == EmptyBlockNumber || blockNumber > _latestFinalizedValidatorsBlockNumber ? GetLatestValidatorInfo() : FindValidatorInfo(blockNumber.Value); @@ -77,7 +77,7 @@ private ValidatorInfo FindValidatorInfo(in ulong blockNumber) currentValidatorInfo = LoadValidatorInfo(currentValidatorInfo.PreviousFinalizingBlockNumber); } - return currentValidatorInfo; + return currentValidatorInfo.FinalizingBlockNumber >= blockNumber ? EmptyValidatorInfo : currentValidatorInfo; } private ValidatorInfo GetLatestValidatorInfo() diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs index 1b4d73befb35..f9e4fab77c16 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs @@ -193,7 +193,7 @@ internal static void Fnv(Span b1, Span b2) private static uint GetUInt(byte[] bytes, uint offset) => BitConverter.ToUInt32(BitConverter.IsLittleEndian ? bytes : Bytes.Reverse(bytes), (int)offset * 4); - public void HintRange(Guid guid, long start, long end) => _hintBasedCache.Hint(guid, start, end); + public void HintRange(Guid guid, ulong start, ulong end) => _hintBasedCache.Hint(guid, start, end); private readonly Guid _hintBasedCacheUser = Guid.Empty; @@ -204,7 +204,7 @@ public bool Validate(BlockHeader header) if (dataSet is null) { if (_logger.IsDebug) _logger.Debug($"Ethash cache miss for block {header.ToString(BlockHeader.Format.Short)}"); - _hintBasedCache.Hint(_hintBasedCacheUser, (long)header.Number, (long)header.Number); + _hintBasedCache.Hint(_hintBasedCacheUser, header.Number, header.Number); dataSet = _hintBasedCache.Get(epoch); if (dataSet is null) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs index 8cca556da184..5d4851bc2408 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs @@ -66,7 +66,7 @@ public bool ValidateSeal(BlockHeader header, bool force) return result; } - public void HintValidationRange(Guid guid, long start, long end) => _ethash.HintRange(guid, start, end); + public void HintValidationRange(Guid guid, ulong start, ulong end) => _ethash.HintRange(guid, start, end); public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle = false) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs index 6d37441f7cfe..514547ace1ec 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/HintBasedCache.cs @@ -34,10 +34,10 @@ private struct DataSetWithTime(DateTimeOffset timestamp, Task da private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); [MethodImpl(MethodImplOptions.Synchronized)] - public void Hint(Guid guid, long start, long end) + public void Hint(Guid guid, ulong start, ulong end) { - uint startEpoch = (uint)((ulong)start / Ethash.EpochLength); - uint endEpoch = (uint)((ulong)end / Ethash.EpochLength); + uint startEpoch = (uint)(start / Ethash.EpochLength); + uint endEpoch = (uint)(end / Ethash.EpochLength); if (endEpoch - startEpoch > 10) { @@ -86,7 +86,7 @@ public void Hint(Guid guid, long start, long end) if (currentMin > startEpoch || currentMax < endEpoch) { - for (long i = startEpoch; i <= endEpoch; i++) + for (uint i = startEpoch; i <= endEpoch; i++) { uint epoch = (uint)i; if (epochForGuid.Add(epoch)) diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/IEthash.cs b/src/Nethermind/Nethermind.Consensus.Ethash/IEthash.cs index 1b65a9fa17b9..1d3ce59f417e 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/IEthash.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/IEthash.cs @@ -9,7 +9,7 @@ namespace Nethermind.Consensus.Ethash { public interface IEthash { - void HintRange(Guid guid, long start, long end); + void HintRange(Guid guid, ulong start, ulong end); bool Validate(BlockHeader header); (Hash256 MixHash, ulong Nonce) Mine(BlockHeader header, ulong? startNonce = null); // TODO: for now only with cache } diff --git a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs index ad830fca4697..589a806eb120 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs @@ -31,8 +31,8 @@ public void Is_bump_on_1559_eip_block() Assert.That(actualValue, Is.EqualTo(gasLimit * (ulong)Eip1559Constants.DefaultElasticityMultiplier)); } - [TestCase(30_000_000ul, 100_000_000, 30029295)] - public void Is_calculating_correct_gasLimit(ulong currentGasLimit, long targetGasLimit, long expectedGasLimit) + [TestCase(30_000_000ul, 100_000_000UL, 30029295UL)] + public void Is_calculating_correct_gasLimit(ulong currentGasLimit, ulong targetGasLimit, ulong expectedGasLimit) { ulong blockNumber = 20_000_000; ulong gasLimit = currentGasLimit; diff --git a/src/Nethermind/Nethermind.Consensus/ISealValidator.cs b/src/Nethermind/Nethermind.Consensus/ISealValidator.cs index 7b2702a64a50..2161cef62b31 100644 --- a/src/Nethermind/Nethermind.Consensus/ISealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/ISealValidator.cs @@ -18,6 +18,6 @@ public interface ISealValidator /// True if seal is valid or was not checked, otherwise false bool ValidateSeal(BlockHeader header, bool force); - public void HintValidationRange(Guid guid, long start, long end) { } + public void HintValidationRange(Guid guid, ulong start, ulong end) { } } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs index 2be2ea9016a4..8db7ddc0935c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs @@ -192,7 +192,10 @@ private void SlowPathFromGeneratedBlockAccessList(Block block, uint index, bool ReadOnlyAccountChanges? sug = suggested.GetAccountChanges(gen.Address); if (sug is not null) { - if (!gen.ChangesAtIndexEqual(sug, index)) ThrowIncorrectChanges(block, gen.Address, index); + if (!gen.ChangesAtIndexEqual(sug, index)) + { + ThrowIncorrectChanges(block, gen.Address, index); + } continue; } diff --git a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs index dfb70b085787..b1a235bcfa26 100644 --- a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs @@ -18,12 +18,12 @@ public ulong GetGasLimit(BlockHeader parentHeader) ulong parentGasLimit = parentHeader.GasLimit; ulong gasLimit = parentGasLimit; - long? targetGasLimit = _blocksConfig.TargetBlockGasLimit; + ulong? targetGasLimit = _blocksConfig.TargetBlockGasLimit; ulong newBlockNumber = parentHeader.Number + 1; IReleaseSpec spec = _specProvider.GetSpec(newBlockNumber, parentHeader.Timestamp); // taking the parent timestamp is a temporary solution if (targetGasLimit is not null) { - ulong target = (ulong)targetGasLimit.Value; + ulong target = targetGasLimit.Value; ulong maxGasLimitDifference = Math.Max(0UL, parentGasLimit / spec.GasLimitBoundDivisor - 1); gasLimit = target > parentGasLimit ? parentGasLimit + Math.Min(target - parentGasLimit, maxGasLimitDifference) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index 071aba383249..c7f695d57855 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -222,8 +222,8 @@ protected virtual bool ValidateExtraData(BlockHeader header, IReleaseSpec spec, && (isUncle || _daoBlockNumber is null // Safe cast: DaoBlockNumber is a known small constant (~1.9M), always fits ulong - || header.Number < (ulong)_daoBlockNumber.Value - || header.Number >= (ulong)(_daoBlockNumber.Value + 10) + || header.Number < _daoBlockNumber.Value + || header.Number >= _daoBlockNumber.Value + 10 || Bytes.AreEqual(header.ExtraData, DaoExtraData)); if (!extraDataValid) { diff --git a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs index fe7867c11cea..635b45c61477 100644 --- a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs @@ -180,7 +180,7 @@ public void Eip_1559_CalculateBaseFee(long gasTarget, long baseFee, long expecte BlockHeader blockHeader = Build.A.BlockHeader.TestObject; blockHeader.Number = 2001; - blockHeader.GasLimit = (ulong)(gasTarget * Eip1559Constants.DefaultElasticityMultiplier); + blockHeader.GasLimit = (ulong)gasTarget * Eip1559Constants.DefaultElasticityMultiplier; blockHeader.BaseFeePerGas = (UInt256)baseFee; blockHeader.GasUsed = gasUsed; UInt256 actualBaseFee = BaseFeeCalculator.Calculate(blockHeader, releaseSpec); @@ -194,8 +194,9 @@ public void Should_have_empty_body_as_expected((BlockHeader Header, bool HasBody public class BaseFeeTestCases { public int ParentBaseFee { get; set; } - public int ParentGasUsed { get; set; } - public int ParentTargetGasUsed { get; set; } + // Gas quantities are always non-negative; ulong matches BlockHeader.GasUsed and GasLimit post-migration. + public ulong ParentGasUsed { get; set; } + public ulong ParentTargetGasUsed { get; set; } public int ExpectedBaseFee { get; set; } } @@ -210,9 +211,12 @@ public void Eip_1559_CalculateBaseFee_shared_test_cases((BaseFeeTestCases Info, BlockHeader blockHeader = Build.A.BlockHeader.TestObject; blockHeader.Number = 2001; - blockHeader.GasLimit = (ulong)(testCase.Info.ParentTargetGasUsed * Eip1559Constants.DefaultElasticityMultiplier); + // No cast needed: ParentTargetGasUsed is ulong, GasLimit is ulong post-migration. + // ElasticityMultiplier is a small protocol constant (currently 2); product fits in ulong. + blockHeader.GasLimit = testCase.Info.ParentTargetGasUsed * (ulong)Eip1559Constants.DefaultElasticityMultiplier; blockHeader.BaseFeePerGas = (UInt256)testCase.Info.ParentBaseFee; - blockHeader.GasUsed = (ulong)testCase.Info.ParentGasUsed; + // No cast needed: ParentGasUsed is ulong, GasUsed is ulong post-migration. + blockHeader.GasUsed = testCase.Info.ParentGasUsed; UInt256 actualBaseFee = BaseFeeCalculator.Calculate(blockHeader, releaseSpec); Assert.That(actualBaseFee, Is.EqualTo((UInt256)testCase.Info.ExpectedBaseFee), testCase.Description); } diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs index 8382033277ec..2351112591d2 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs @@ -27,7 +27,7 @@ public static async Task Create(Action? c public async Task BuildSomeBlocks(int numOfBlocks) { - ulong nonce = (ulong)WorldStateManager.GlobalStateReader.GetNonce(BlockTree.Head!.Header, TestItem.PrivateKeyA.Address); + ulong nonce = WorldStateManager.GlobalStateReader.GetNonce(BlockTree.Head!.Header, TestItem.PrivateKeyA.Address); for (int i = 0; i < numOfBlocks; i++) { IReleaseSpec spec = SpecProvider.GetSpec(BlockTree.Head!.Header); diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs index b558825a6df5..8912426ffe3f 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs @@ -221,7 +221,7 @@ public BlockBuilder WithBloom(Bloom bloom) return this; } - public BlockBuilder WithAura(long step, byte[]? signature = null) + public BlockBuilder WithAura(ulong step, byte[]? signature = null) { TestObjectInternal.Header.AuRaStep = step; TestObjectInternal.Header.AuRaSignature = signature; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs index 7fd4ec1a691f..06668236a285 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs @@ -172,7 +172,7 @@ public BlockHeaderBuilder WithNonce(ulong nonce) return this; } - public BlockHeaderBuilder WithAura(long step, byte[]? signature = null) + public BlockHeaderBuilder WithAura(ulong step, byte[]? signature = null) { TestObjectInternal.AuRaStep = step; TestObjectInternal.AuRaSignature = signature; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs index 5c245fbf82bf..bdb912626b9a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs @@ -377,7 +377,7 @@ private Block CreateBlock(int splitVariant, int splitFrom, int blockIndex, Block { currentBlock.Header.StateRoot = _stateRootGen(currentBlock); } - currentBlock.Header.AuRaStep = blockIndex; + currentBlock.Header.AuRaStep = (ulong)blockIndex; return currentBlock; } diff --git a/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs b/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs index 6dca105406c2..a56591896ec4 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestTrieStoreFactory.cs @@ -23,7 +23,7 @@ public static class TestTrieStoreFactory public static TrieStore Build(IKeyValueStoreWithBatching keyValueStore, IPruningStrategy pruningStrategy, IPersistenceStrategy persistenceStrategy, ILogManager logManager) { - TestFinalizedStateProvider finalizedStateProvider = new((ulong)_testPruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(_testPruningConfig.PruningBoundary); TrieStore trieStore = new(new NodeStorage(keyValueStore), pruningStrategy, persistenceStrategy, finalizedStateProvider, _testPruningConfig, logManager); finalizedStateProvider.TrieStore = trieStore; return trieStore; diff --git a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs index dbba6f2bea9c..b2b612d50afe 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs @@ -19,7 +19,7 @@ public static class TestWorldStateFactory public static IWorldState CreateForTest(IDbProvider? dbProvider = null, ILogManager? logManager = null) { PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); dbProvider ??= TestMemDbProvider.Init(); logManager ??= LimboLogs.Instance; TrieStore trieStore = new( @@ -39,7 +39,7 @@ public static (IWorldState, IStateReader) CreateForTestWithStateReader(IDbProvid logManager ??= LimboLogs.Instance; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(dbProvider.StateDb), No.Pruning, @@ -78,7 +78,7 @@ private static IContainer BuildFlatContainer() public static WorldStateManager CreateWorldStateManagerForTest(IDbProvider dbProvider, ILogManager logManager) { PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(dbProvider.StateDb), No.Pruning, diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index b29a8b12f5b1..c79ac2770439 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -70,7 +70,7 @@ public BlockHeader( public Hash256? Hash { get; set; } public UInt256? TotalDifficulty { get; set; } public byte[]? AuRaSignature { get; set; } - public long? AuRaStep { get; set; } + public ulong? AuRaStep { get; set; } public UInt256 BaseFeePerGas; public Hash256? WithdrawalsRoot { get; set; } public Hash256? ParentBeaconBlockRoot { get; set; } diff --git a/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs b/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs index 607bfa011d29..e7b1256a9c3b 100644 --- a/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Collections/ListExtensions.cs @@ -18,6 +18,8 @@ public static void ForEach(this IReadOnlyList list, Action action) public static T? GetItemRoundRobin(this IList array, long index) => array.Count == 0 ? default : array[(int)(index % array.Count)]; + public static T? GetItemRoundRobin(this IList array, ulong index) => array.Count == 0 ? default : array[(int)(index % (ulong)array.Count)]; + /// /// Performs a binary search on the specified collection. /// diff --git a/src/Nethermind/Nethermind.Core/Eip1559Constants.cs b/src/Nethermind/Nethermind.Core/Eip1559Constants.cs index d3064af75008..83243b7f6066 100644 --- a/src/Nethermind/Nethermind.Core/Eip1559Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip1559Constants.cs @@ -13,6 +13,6 @@ public class Eip1559Constants public static readonly UInt256 DefaultBaseFeeMaxChangeDenominator = 8; - public static readonly int DefaultElasticityMultiplier = 2; + public static readonly ulong DefaultElasticityMultiplier = 2; } } diff --git a/src/Nethermind/Nethermind.Core/Eip4844Constants.cs b/src/Nethermind/Nethermind.Core/Eip4844Constants.cs index acf38a1c7697..2f2e4d3c2d02 100644 --- a/src/Nethermind/Nethermind.Core/Eip4844Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip4844Constants.cs @@ -34,7 +34,7 @@ public static class Eip4844Constants /// Gets the BLOB_GASPRICE_UPDATE_FRACTION parameter. ///
/// Defaults to 3338477. - public static UInt256 DefaultBlobGasPriceUpdateFraction { get; private set; } = 3338477; + public static ulong DefaultBlobGasPriceUpdateFraction { get; private set; } = 3338477; /// /// Gets the MIN_BLOB_GASPRICE parameter, in wei. diff --git a/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs b/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs index bab13a3107ac..6e315a28582c 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs @@ -20,7 +20,7 @@ public interface IEip1559Spec public UInt256? Eip1559BaseFeeMinValue => null; public UInt256 ForkBaseFee { get; } public UInt256 BaseFeeMaxChangeDenominator { get; } - public long ElasticityMultiplier { get; } + public ulong ElasticityMultiplier { get; } public IBaseFeeCalculator BaseFeeCalculator { get; } } @@ -32,7 +32,7 @@ public sealed class OverridableEip1559Spec(IEip1559Spec spec) : IEip1559Spec public UInt256? Eip1559BaseFeeMinValue { get; init; } = spec.Eip1559BaseFeeMinValue; public UInt256 ForkBaseFee { get; init; } = spec.ForkBaseFee; public UInt256 BaseFeeMaxChangeDenominator { get; init; } = spec.BaseFeeMaxChangeDenominator; - public long ElasticityMultiplier { get; init; } = spec.ElasticityMultiplier; + public ulong ElasticityMultiplier { get; init; } = spec.ElasticityMultiplier; public IBaseFeeCalculator BaseFeeCalculator { get; init; } = spec.BaseFeeCalculator; } } diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index d033bf70e874..ed5ebe12ad14 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -402,7 +402,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec public ulong TargetBlobCount { get; } public ulong MaxBlobCount { get; } public ulong MaxBlobsPerTx { get; } - public UInt256 BlobBaseFeeUpdateFraction { get; } + public ulong BlobBaseFeeUpdateFraction { get; } public ulong WithdrawalTimestamp { get; } diff --git a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs index 7e0d34a45fc2..657d0e932f2a 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs @@ -100,7 +100,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual ulong TargetBlobCount => spec.TargetBlobCount; public virtual ulong MaxBlobCount => spec.MaxBlobCount; public virtual ulong MaxBlobsPerTx => spec.MaxBlobsPerTx; - public virtual UInt256 BlobBaseFeeUpdateFraction => spec.BlobBaseFeeUpdateFraction; + public virtual ulong BlobBaseFeeUpdateFraction => spec.BlobBaseFeeUpdateFraction; public virtual ulong WithdrawalTimestamp => spec.WithdrawalTimestamp; public virtual ulong Eip4844TransitionTimestamp => spec.Eip4844TransitionTimestamp; public virtual bool IsEip4844FeeCollectorEnabled => spec.IsEip4844FeeCollectorEnabled; @@ -108,7 +108,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual Address? FeeCollector => spec.FeeCollector; public virtual UInt256 ForkBaseFee => spec.ForkBaseFee; public virtual UInt256 BaseFeeMaxChangeDenominator => spec.BaseFeeMaxChangeDenominator; - public virtual long ElasticityMultiplier => spec.ElasticityMultiplier; + public virtual ulong ElasticityMultiplier => spec.ElasticityMultiplier; public virtual IBaseFeeCalculator BaseFeeCalculator => spec.BaseFeeCalculator; Array? IReleaseSpec.EvmInstructionsNoTrace { get => spec.EvmInstructionsNoTrace; set => spec.EvmInstructionsNoTrace = value; } Array? IReleaseSpec.EvmInstructionsTraced { get => spec.EvmInstructionsTraced; set => spec.EvmInstructionsTraced = value; } diff --git a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs index f035aee63c07..3ba6da2aa2a6 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs @@ -18,7 +18,7 @@ namespace Nethermind.Db.Blooms public class BloomStorage : IBloomStorage { public byte Levels { get; private set; } - public int MaxBucketSize => _storageLevels.FirstOrDefault()?.LevelElementSize ?? 1; + public uint MaxBucketSize => _storageLevels.FirstOrDefault()?.LevelElementSize ?? 1; internal static readonly Hash256 MinBlockNumberKey = Keccak.Compute(nameof(MinBlockNumber)); internal static readonly Hash256 MaxBlockNumberKey = Keccak.Compute(nameof(MaxBlockNumber)); @@ -121,12 +121,12 @@ void ValidateCurrentDbStructure(IList sizes) List configIndexLevelBucketSizes = InsertBaseLevelIfNeeded(); ValidateCurrentDbStructure(configIndexLevelBucketSizes); - int lastLevelSize = 1; + uint lastLevelSize = 1; return configIndexLevelBucketSizes .Select((size, i) => { byte level = (byte)(configIndexLevelBucketSizes.Count - i - 1); - int levelElementSize = lastLevelSize * size; + uint levelElementSize = lastLevelSize * (uint)size; lastLevelSize = levelElementSize; return new BloomStorageLevel(_fileStoreFactory.Create(level.ToString()), level, levelElementSize, size, _config.MigrationStatistics); }) @@ -177,11 +177,11 @@ public void Store(IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms) public void Migrate(IEnumerable headers) { - int batchSize = _storageLevels.First().LevelElementSize; + uint batchSize = _storageLevels.First().LevelElementSize; (BloomStorageLevel Level, Bloom Bloom)[] levelBlooms = _storageLevels.SkipLast(1).Select(static l => (l, new Bloom())).ToArray(); BloomStorageLevel lastLevel = _storageLevels.Last(); - long i = 0; + ulong i = 0; ulong lastBlockNumber = 0; bool hasBlocks = false; @@ -204,7 +204,7 @@ public void Migrate(IEnumerable headers) if (level.LevelElementSize == batchSize) { - MigratedBlockNumber += (ulong)batchSize; + MigratedBlockNumber += batchSize; } } } @@ -220,7 +220,7 @@ public void Migrate(IEnumerable headers) level.Store((lastBlockNumber, bloom)); } - MigratedBlockNumber += (ulong)i; + MigratedBlockNumber += i; } if (MigratedBlockNumber >= MinBlockNumber - 1) @@ -241,30 +241,30 @@ public void Dispose() public IBloomEnumeration GetBlooms(ulong fromBlock, ulong toBlock) => new BloomEnumeration(_storageLevels, Math.Max(fromBlock, MinBlockNumber), Math.Min(toBlock, MaxBlockNumber)); - private class BloomStorageLevel(IFileStore fileStore, in byte level, in int levelElementSize, in int levelMultiplier, bool migrationStatistics) : IDisposable + private class BloomStorageLevel(IFileStore fileStore, in byte level, in uint levelElementSize, in int levelMultiplier, bool migrationStatistics) : IDisposable { // ReSharper disable InconsistentNaming private readonly byte Level = level; - public readonly int LevelElementSize = levelElementSize; + public readonly uint LevelElementSize = levelElementSize; private readonly int LevelMultiplier = levelMultiplier; public readonly Average Average = new(); // ReSharper restore InconsistentNaming private readonly IFileStore _fileStore = fileStore; private readonly bool _migrationStatistics = migrationStatistics; - private readonly LruCache _cache = new(levelMultiplier, levelMultiplier, "blooms"); + private readonly LruCache _cache = new(levelMultiplier, levelMultiplier, "blooms"); public void Store(params IReadOnlyList<(ulong BlockNumber, Bloom Bloom)> blooms) { lock (_fileStore) { - long currentBucket = -1; + ulong currentBucket = ulong.MaxValue; Bloom currentBloom = null; byte[] bloomBuff = new byte[Bloom.ByteLength]; void WriteCurrentBloom() { - if (currentBucket != -1) + if (currentBucket != ulong.MaxValue) { _fileStore.Write(currentBucket, currentBloom.Bytes); _cache.Set(currentBucket, currentBloom); @@ -275,7 +275,7 @@ void WriteCurrentBloom() { try { - long bucket = GetBucket(blockNumber); + ulong bucket = GetBucket(blockNumber); if (bucket != currentBucket) { WriteCurrentBloom(); @@ -309,7 +309,7 @@ void WriteCurrentBloom() private static uint CountBits(Bloom bloom) => bloom.Bytes.CountBits(); - public long GetBucket(ulong blockNumber) => (long)(blockNumber / (ulong)LevelElementSize); + public ulong GetBucket(ulong blockNumber) => blockNumber / LevelElementSize; public IFileReader CreateReader() => _fileStore.CreateFileReader(); @@ -333,7 +333,7 @@ private class BloomEnumeration(BloomStorageLevel[] storageLevels, ulong fromBloc private readonly ulong _toBlock = toBlock; private BloomEnumerator _current; - public IEnumerator GetEnumerator() => _current = new BloomEnumerator(_storageLevels, (long)_fromBlock, (long)_toBlock); + public IEnumerator GetEnumerator() => _current = new BloomEnumerator(_storageLevels, _fromBlock, _toBlock); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -365,17 +365,16 @@ private byte CurrentLevel private bool _currentLevelRead; private byte _currentLevel; - public BloomEnumerator(BloomStorageLevel[] storageLevels, in long fromBlock, in long toBlock) - // TODO: Change fromBlock/toBlock to ulong once callers are updated + public BloomEnumerator(BloomStorageLevel[] storageLevels, in ulong fromBlock, in ulong toBlock) { _storageLevels = GetStorageLevels(storageLevels, fromBlock, toBlock); - _fromBlock = (ulong)fromBlock; - _toBlock = (ulong)toBlock; + _fromBlock = fromBlock; + _toBlock = toBlock; _maxLevel = _storageLevels.Length - 1; Reset(); } - private static (BloomStorageLevel Storage, IFileReader Reader)[] GetStorageLevels(BloomStorageLevel[] storageLevels, long fromBlock, long toBlock) + private static (BloomStorageLevel Storage, IFileReader Reader)[] GetStorageLevels(BloomStorageLevel[] storageLevels, ulong fromBlock, ulong toBlock) { // Skip higher levels if we would do only 1 or 2 lookups in them. Thanks to that we can skip a lot of IO operations on that file IList levels = new List(storageLevels.Length); @@ -385,8 +384,8 @@ private static (BloomStorageLevel Storage, IFileReader Reader)[] GetStorageLevel if (i != storageLevels.Length - 1) { - long fromBucket = level.GetBucket((ulong)fromBlock); - long toBucket = level.GetBucket((ulong)toBlock); + ulong fromBucket = level.GetBucket(fromBlock); + ulong toBucket = level.GetBucket(toBlock); if (toBucket - fromBucket + 1 <= 2) { continue; @@ -449,7 +448,7 @@ public Bloom Current { BloomStorageLevel level = _storageLevels[_currentLevel].Storage; ulong bucket = (ulong)level.GetBucket(_currentPosition); - return (bucket * (ulong)level.LevelElementSize, (bucket + 1) * (ulong)level.LevelElementSize - 1); + return (bucket * level.LevelElementSize, (bucket + 1) * level.LevelElementSize - 1); } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/FileReader.cs b/src/Nethermind/Nethermind.Db/Blooms/FileReader.cs index 8c671b3d3a51..5edd7db29638 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/FileReader.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/FileReader.cs @@ -13,9 +13,9 @@ public class FileReader(string filePath, int elementSize) : IFileReader private readonly int _elementSize = elementSize; private readonly SafeFileHandle _file = File.OpenHandle(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - public int Read(long index, Span element) => RandomAccess.Read(_file, element, GetPosition(index)); + public int Read(ulong index, Span element) => RandomAccess.Read(_file, element, GetPosition(index)); - private long GetPosition(long index) => index * _elementSize; + private long GetPosition(ulong index) => (long)index * _elementSize; public void Dispose() => _file.Dispose(); } diff --git a/src/Nethermind/Nethermind.Db/Blooms/FixedSizeFileStore.cs b/src/Nethermind/Nethermind.Db/Blooms/FixedSizeFileStore.cs index 311b5ea550df..e0bdfa0e3b03 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/FixedSizeFileStore.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/FixedSizeFileStore.cs @@ -14,7 +14,7 @@ public class FixedSizeFileStore(string path, int elementSize) : IFileStore private readonly int _elementSize = elementSize; private readonly SafeFileHandle _file = File.OpenHandle(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read); - public void Write(long index, ReadOnlySpan element) + public void Write(ulong index, ReadOnlySpan element) { if (element.Length != _elementSize) { @@ -42,11 +42,11 @@ public void Write(long index, ReadOnlySpan element) } } - public int Read(long index, Span element) => RandomAccess.Read(_file, element, GetPosition(index)); + public int Read(ulong index, Span element) => RandomAccess.Read(_file, element, GetPosition(index)); public IFileReader CreateFileReader() => new FileReader(_path, _elementSize); - private long GetPosition(long index) => index * _elementSize; + private long GetPosition(ulong index) => (long)index * _elementSize; public void Dispose() => _file.Dispose(); } diff --git a/src/Nethermind/Nethermind.Db/Blooms/IFileReader.cs b/src/Nethermind/Nethermind.Db/Blooms/IFileReader.cs index dab1bd7babba..0796a665a6ae 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/IFileReader.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/IFileReader.cs @@ -7,6 +7,6 @@ namespace Nethermind.Db.Blooms { public interface IFileReader : IDisposable { - int Read(long index, Span element); + int Read(ulong index, Span element); } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/IFileStore.cs b/src/Nethermind/Nethermind.Db/Blooms/IFileStore.cs index 3c2c30ba631e..0ac0a771b9a5 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/IFileStore.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/IFileStore.cs @@ -7,9 +7,9 @@ namespace Nethermind.Db.Blooms { public interface IFileStore : IDisposable { - void Write(long index, ReadOnlySpan element); + void Write(ulong index, ReadOnlySpan element); - int Read(long index, Span element); + int Read(ulong index, Span element); IFileReader CreateFileReader(); } diff --git a/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileReader.cs b/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileReader.cs index 4fdc89977396..ce10dc658dd8 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileReader.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileReader.cs @@ -11,6 +11,6 @@ public class InMemoryDictionaryFileReader(IFileStore store) : IFileReader public void Dispose() { } - public int Read(long index, Span element) => _store.Read(index, element); + public int Read(ulong index, Span element) => _store.Read(index, element); } } diff --git a/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileStore.cs b/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileStore.cs index 688509ea83f9..57c8e13f1ae2 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileStore.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/InMemoryDictionaryFileStore.cs @@ -8,13 +8,13 @@ namespace Nethermind.Db.Blooms { public class InMemoryDictionaryFileStore : IFileStore { - readonly IDictionary _store = new Dictionary(); + readonly IDictionary _store = new Dictionary(); public void Dispose() => _store.Clear(); - public void Write(long index, ReadOnlySpan element) => _store[index] = element.ToArray(); + public void Write(ulong index, ReadOnlySpan element) => _store[index] = element.ToArray(); - public int Read(long index, Span element) + public int Read(ulong index, Span element) { if (_store.TryGetValue(index, out byte[] found)) { diff --git a/src/Nethermind/Nethermind.Db/FlatDbConfig.cs b/src/Nethermind/Nethermind.Db/FlatDbConfig.cs index 6fd4e42f35d3..b9f1880305e4 100644 --- a/src/Nethermind/Nethermind.Db/FlatDbConfig.cs +++ b/src/Nethermind/Nethermind.Db/FlatDbConfig.cs @@ -19,6 +19,6 @@ public class FlatDbConfig : IFlatDbConfig public int MaxReorgDepth { get; set; } = 256; public int MinReorgDepth { get; set; } = 128; public int TrieWarmerWorkerCount { get; set; } = -1; - public long BlockCacheSizeBudget { get; set; } = 1.GiB; - public long TrieCacheMemoryBudget { get; set; } = 512.MiB; + public ulong BlockCacheSizeBudget { get; set; } = 1UL.GiB; + public ulong TrieCacheMemoryBudget { get; set; } = 512UL.MiB; } diff --git a/src/Nethermind/Nethermind.Db/IFlatDbConfig.cs b/src/Nethermind/Nethermind.Db/IFlatDbConfig.cs index 9ea88ab2222f..9ea6d362f6ea 100644 --- a/src/Nethermind/Nethermind.Db/IFlatDbConfig.cs +++ b/src/Nethermind/Nethermind.Db/IFlatDbConfig.cs @@ -8,7 +8,7 @@ namespace Nethermind.Db; public interface IFlatDbConfig : IConfig { [ConfigItem(Description = "Block cache size budget", DefaultValue = "1073741824")] - long BlockCacheSizeBudget { get; set; } + ulong BlockCacheSizeBudget { get; set; } [ConfigItem(Description = "Compact size", DefaultValue = "32")] int CompactSize { get; set; } @@ -41,7 +41,7 @@ public interface IFlatDbConfig : IConfig bool RegenerateCompactionOffset { get; set; } [ConfigItem(Description = "Trie cache memory target", DefaultValue = "536870912")] - long TrieCacheMemoryBudget { get; set; } + ulong TrieCacheMemoryBudget { get; set; } [ConfigItem(Description = "Trie warmer worker count (-1 for processor count - 1, 0 to disable)", DefaultValue = "-1")] int TrieWarmerWorkerCount { get; set; } diff --git a/src/Nethermind/Nethermind.Db/IPruningConfig.cs b/src/Nethermind/Nethermind.Db/IPruningConfig.cs index efd534d69528..dc434ab45fd0 100644 --- a/src/Nethermind/Nethermind.Db/IPruningConfig.cs +++ b/src/Nethermind/Nethermind.Db/IPruningConfig.cs @@ -81,7 +81,7 @@ The max number of parallel tasks that can be used by full pruning. bool TrackPastKeys { get; set; } [ConfigItem(Description = "The number of past states before the state gets pruned. Used to determine how old of a state to keep from the head.", DefaultValue = "64")] - int PruningBoundary { get; set; } + ulong PruningBoundary { get; set; } [ConfigItem(Description = "Dirty node shard count", DefaultValue = "8")] int DirtyNodeShardBit { get; set; } diff --git a/src/Nethermind/Nethermind.Db/PruningConfig.cs b/src/Nethermind/Nethermind.Db/PruningConfig.cs index e990ed9d01d1..cb287ec14062 100644 --- a/src/Nethermind/Nethermind.Db/PruningConfig.cs +++ b/src/Nethermind/Nethermind.Db/PruningConfig.cs @@ -39,7 +39,7 @@ public bool Enabled public bool AvailableSpaceCheckEnabled { get; set; } = true; public double TrackedPastKeyCountMemoryRatio { get; set; } = 0.1; public bool TrackPastKeys { get; set; } = true; - public int PruningBoundary { get; set; } = (int)Reorganization.MaxDepth; + public ulong PruningBoundary { get; set; } = Reorganization.MaxDepth; private int _dirtyNodeShardBit = 8; diff --git a/src/Nethermind/Nethermind.Era1/EraConfig.cs b/src/Nethermind/Nethermind.Era1/EraConfig.cs index feed323ab33f..09c249e8cc0b 100644 --- a/src/Nethermind/Nethermind.Era1/EraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/EraConfig.cs @@ -13,5 +13,5 @@ public class EraConfig : IEraConfig public int MaxEra1Size { get; set; } = EraWriter.MaxEra1Size; public string? NetworkName { get; set; } public int Concurrency { get; set; } - public long ImportBlocksBufferSize { get; set; } = 1024 * 4; + public ulong ImportBlocksBufferSize { get; set; } = 1024 * 4; } diff --git a/src/Nethermind/Nethermind.Era1/EraImporter.cs b/src/Nethermind/Nethermind.Era1/EraImporter.cs index 1654ca44f155..54c5e43506a2 100644 --- a/src/Nethermind/Nethermind.Era1/EraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraImporter.cs @@ -113,7 +113,7 @@ private async Task ImportInternal( using ProgressReporter progress = new("Era import", logManager, to - from + 1); ulong blocksProcessed = 0; - using BlockTreeSuggestPacer pacer = new(blockTree, (ulong)eraConfig.ImportBlocksBufferSize, (ulong)(eraConfig.ImportBlocksBufferSize - 1024)); + using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, eraConfig.ImportBlocksBufferSize - 1024UL); CurrentPacer = pacer; ulong blockNumber = from; diff --git a/src/Nethermind/Nethermind.Era1/IEraConfig.cs b/src/Nethermind/Nethermind.Era1/IEraConfig.cs index 473138cf6b54..f04754742124 100644 --- a/src/Nethermind/Nethermind.Era1/IEraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/IEraConfig.cs @@ -32,5 +32,5 @@ public interface IEraConfig : IConfig int Concurrency { get; set; } [ConfigItem(Description = "[Technical] Buffer size during full sync when era importing. Lower number reduces memory usage.", DefaultValue = "4096", HiddenFromDocs = true)] - long ImportBlocksBufferSize { get; set; } + ulong ImportBlocksBufferSize { get; set; } } diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs index 6d2eeae4e8f5..10903ae5e7d8 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs @@ -37,11 +37,11 @@ public void SetUp() public async Task FindBlockAndReceipts_WhenEpochMissingLocally_DownloadsAndReturnsBlock() { await using IContainer ctx = await EraETestModule.CreateExportedEraEnv(chainLength: 32, from: 0, to: 0); - (int epoch, string filename) = await StageRemoteEpochAsync(ctx); + (ulong epoch, string filename) = await StageRemoteEpochAsync(ctx); using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16); - (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: false); + (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts(epoch * 16, ensureValidated: false); Assert.That(block, Is.Not.Null); Assert.That(receipts, Is.Not.Null); @@ -112,27 +112,26 @@ public async Task FindBlockAndReceipts_WhenDownloadedFileHasWrongChecksum_Throws public async Task FindBlockAndReceipts_WhenEnsureValidated_EnforcesContentTrust(bool contentValid, bool accumulatorTrusted) { await using IContainer ctx = await EraETestModule.CreateExportedEraEnv(chainLength: 32, from: 0, to: 0); - (int epoch, string filename) = await StageRemoteEpochAsync(ctx); + (ulong epoch, string filename) = await StageRemoteEpochAsync(ctx); IBlockValidator blockValidator = contentValid ? Always.Valid : Always.Invalid; - // A trusted set excluding the epoch's real accumulator root forces the untrusted-root rejection. ISet? trustedAccumulators = accumulatorTrusted ? null : new HashSet { new("0x1111111111111111111111111111111111111111111111111111111111111111") }; using RemoteEraStoreDecorator sut = CreateDecorator( localStore: null, maxEraSize: 16, ctx.Resolve(), blockValidator, trustedAccumulators); + ulong blockNumber = epoch * 16; if (contentValid && accumulatorTrusted) { - (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts((ulong)epoch * 16); + (Block? block, TxReceipt[]? receipts) = await sut.FindBlockAndReceipts(blockNumber); Assert.That(block, Is.Not.Null); Assert.That(receipts, Is.Not.Null); - Assert.That(block!.Number, Is.EqualTo(epoch * 16)); + Assert.That(block!.Number, Is.EqualTo(blockNumber)); } else { - Assert.That(async () => await sut.FindBlockAndReceipts((ulong)epoch * 16), Throws.TypeOf()); - // Rejected content caches nothing: the file is removed so a retry re-downloads. + Assert.That(async () => await sut.FindBlockAndReceipts(blockNumber), Throws.TypeOf()); Assert.That(File.Exists(Path.Join(_downloadDir.Path, filename)), Is.False); } } @@ -141,20 +140,18 @@ public async Task FindBlockAndReceipts_WhenEnsureValidated_EnforcesContentTrust( public async Task FindBlockAndReceipts_WhenUnvalidatedReadPrecedesValidatedRead_StillRunsContentValidation() { await using IContainer ctx = await EraETestModule.CreateExportedEraEnv(chainLength: 32, from: 0, to: 0); - (int epoch, _) = await StageRemoteEpochAsync(ctx); + (ulong epoch, _) = await StageRemoteEpochAsync(ctx); IBlockValidator blockValidator = Substitute.For(); blockValidator.ValidateBodyAgainstHeader(Arg.Any(), Arg.Any(), out Arg.Any()) .Returns(true); using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16, ctx.Resolve(), blockValidator); - // An unvalidated read caches availability only and must not run content validation. - await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: false); + ulong blockNumber = epoch * 16; + await sut.FindBlockAndReceipts(blockNumber, ensureValidated: false); blockValidator.DidNotReceiveWithAnyArgs().ValidateBodyAgainstHeader(default!, default!, out Arg.Any()); - // A later validated read on the same epoch must still run VerifyContent — the availability - // cache alone cannot satisfy it. - await sut.FindBlockAndReceipts((ulong)epoch * 16, ensureValidated: true); + await sut.FindBlockAndReceipts(blockNumber, ensureValidated: true); blockValidator.ReceivedWithAnyArgs().ValidateBodyAgainstHeader(default!, default!, out Arg.Any()); } @@ -164,18 +161,16 @@ private RemoteEraStoreDecorator CreateDecorator( new(localStore, _client, _downloadDir.Path, maxEraSize, specProvider ?? Substitute.For(), blockValidator ?? Always.Valid, trustedAccumulators); - // Wires the mock client to serve a freshly exported era file (with a matching SHA-256) and - // returns its epoch and filename. - private async Task<(int Epoch, string Filename)> StageRemoteEpochAsync(IContainer ctx) + private async Task<(ulong Epoch, string Filename)> StageRemoteEpochAsync(IContainer ctx) { string exportDir = ctx.ResolveTempDirPath(); string eraFile = EraPathUtils.GetAllEraFiles(exportDir, EraETestModule.TestNetwork).First(); string filename = Path.GetFileName(eraFile); - int epoch = ParseEpoch(filename); + ulong epoch = ParseEpoch(filename); byte[] sha256 = SHA256.HashData(await File.ReadAllBytesAsync(eraFile)); _client.FetchManifestAsync(Arg.Any()) - .Returns(new Dictionary { [epoch] = new(filename, sha256) }); + .Returns(new Dictionary { [(int)epoch] = new(filename, sha256) }); // BOUNDARY CAST: manifest key is int by upstream API design; epoch fits safely in int _client.DownloadFileAsync(filename, Arg.Any(), Arg.Any()) .Returns(callInfo => CopyFile(eraFile, callInfo.ArgAt(1))); @@ -200,10 +195,10 @@ public async Task FindBlockAndReceipts_WhenManifestFilenameEscapesDownloadDir_Th Assert.That(File.Exists(escapedPath), Is.False); } - private static int ParseEpoch(string filename) + private static ulong ParseEpoch(string filename) { string[] parts = Path.GetFileNameWithoutExtension(filename).Split('-'); - return int.Parse(parts[1]); + return ulong.Parse(parts[1]); } private static Task CopyFile(string source, string destination) diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs index 81993d9820cc..980f01e3f5bc 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs @@ -41,9 +41,9 @@ public EraReader(string fileName) : this(new E2StoreReader(fileName)) { } public async Task<(Block, TxReceipt[])> GetBlockByNumber(ulong number, CancellationToken cancellation = default) { - if (number < (ulong)e2.First) + if (number < e2.First) throw new ArgumentOutOfRangeException(nameof(number), $"Cannot be less than first block {e2.First}."); - if (number > (ulong)e2.LastBlock) + if (number > e2.LastBlock) throw new ArgumentOutOfRangeException(nameof(number), $"Cannot exceed last block {e2.LastBlock}."); return await ReadBlockAndReceipts(number, cancellation); @@ -77,14 +77,14 @@ public async Task VerifyContent( if (verifyConcurrency <= 0) verifyConcurrency = Environment.ProcessorCount; - ulong startBlock = (ulong)e2.First; + ulong startBlock = e2.First; int blockCount = (int)e2.BlockCount; (Hash256 Hash, UInt256 Td, bool IsPreMerge)[] blockMeta = new (Hash256 Hash, UInt256 Td, bool IsPreMerge)[blockCount]; ConcurrentQueue blockNumbers = new(); - for (ulong n = startBlock; n <= (ulong)e2.LastBlock; n++) + for (ulong n = startBlock; n <= e2.LastBlock; n++) { blockNumbers.Enqueue(n); } @@ -107,7 +107,7 @@ public async Task VerifyContent( throw new EraVerificationException($"Mismatched receipt root at block {blockNumber}."); // Safe: each dequeued blockNumber is unique, so each idx is written by exactly one worker. - int idx = (int)(block.Header.Number - (ulong)startBlock); + int idx = (int)(block.Header.Number - startBlock); blockMeta[idx] = ( block.Header.Hash!, block.TotalDifficulty ?? UInt256.Zero, diff --git a/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs b/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs index 876f8ff9b5ab..26918873fb27 100644 --- a/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs +++ b/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs @@ -9,13 +9,13 @@ public class EraEConfig : IEraEConfig { public string? ImportDirectory { get; set; } public string? ExportDirectory { get; set; } - public long From { get; set; } - public long To { get; set; } + public ulong From { get; set; } + public ulong To { get; set; } public string? TrustedAccumulatorFile { get; set; } public int MaxEraSize { get; set; } = EraWriter.MaxEraSize; public string? NetworkName { get; set; } public int Concurrency { get; set; } - public long ImportBlocksBufferSize { get; set; } = 4096; + public ulong ImportBlocksBufferSize { get; set; } = 4096; public string? BeaconNodeUrl { get; set; } public string? RemoteBaseUrl { get; set; } public string? RemoteDownloadDirectory { get; set; } diff --git a/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs b/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs index 0339e4eb20d4..2f2a7cbe1820 100644 --- a/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs +++ b/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs @@ -14,10 +14,10 @@ public interface IEraEConfig : IConfig string? ExportDirectory { get; set; } [ConfigItem(Description = "Block number to import/export from.", DefaultValue = "0")] - long From { get; set; } + ulong From { get; set; } [ConfigItem(Description = "Block number to import/export to. 0 means head.", DefaultValue = "0")] - long To { get; set; } + ulong To { get; set; } [ConfigItem(Description = "Accumulator file for trusting EraE archives.", DefaultValue = "null")] string? TrustedAccumulatorFile { get; set; } @@ -32,7 +32,7 @@ public interface IEraEConfig : IConfig int Concurrency { get; set; } [ConfigItem(Description = "[Technical] Block buffer size during era import.", DefaultValue = "4096", HiddenFromDocs = true)] - long ImportBlocksBufferSize { get; set; } + ulong ImportBlocksBufferSize { get; set; } [ConfigItem(Description = "Beacon node URL for fetching beacon block roots and state roots during post-merge EraE export. When set, enables BeaconApiRootsProvider and HistoricalSummariesRpcProvider.", DefaultValue = "null")] string? BeaconNodeUrl { get; set; } diff --git a/src/Nethermind/Nethermind.EraE/EraCliRunner.cs b/src/Nethermind/Nethermind.EraE/EraCliRunner.cs index 57ca1266228f..68718acbda8b 100644 --- a/src/Nethermind/Nethermind.EraE/EraCliRunner.cs +++ b/src/Nethermind/Nethermind.EraE/EraCliRunner.cs @@ -27,11 +27,11 @@ public async Task Run(CancellationToken token) "Either disable history pruning or remove the import directory."); } - await eraImporter.Import(eraConfig.ImportDirectory!, (ulong)eraConfig.From, (ulong)eraConfig.To, eraConfig.TrustedAccumulatorFile, token); + await eraImporter.Import(eraConfig.ImportDirectory!, eraConfig.From, eraConfig.To, eraConfig.TrustedAccumulatorFile, token); } else if (!string.IsNullOrEmpty(eraConfig.ExportDirectory)) { - await eraExporter.Export(eraConfig.ExportDirectory!, (ulong)eraConfig.From, (ulong)eraConfig.To, token); + await eraExporter.Export(eraConfig.ExportDirectory!, eraConfig.From, eraConfig.To, token); } } } diff --git a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs index a203b198a0cd..5ef7e6bccb9e 100644 --- a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs +++ b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs @@ -92,7 +92,7 @@ private async Task ImportInternal(ulong from, ulong to, IEraStore eraStore, Canc using ProgressReporter progress = new("EraE import", logManager, to - from + 1); ulong blocksProcessed = 0; - using BlockTreeSuggestPacer pacer = new(blockTree, (ulong)eraConfig.ImportBlocksBufferSize, (ulong)(eraConfig.ImportBlocksBufferSize - 1024)); + using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, eraConfig.ImportBlocksBufferSize - 1024UL); ulong blockNumber = from; ulong suggestFromBlock = (blockTree.Head?.Number ?? 0UL) + 1; diff --git a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs index 8b4ca04fee3f..64917758c23c 100644 --- a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs +++ b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs @@ -34,7 +34,10 @@ public sealed class EraStore : IEraStore private readonly int _maxOpenFile; private readonly ConcurrentDictionary _openedReader = new(); - private readonly int _maxEraSize; + // Changed int → uint: era size is always a small positive count (e.g. 8192), + // never negative, so uint is the honest type and avoids the (ulong) cast in + // GetEpochNumber without overstating the range as ulong. + private readonly uint _maxEraSize; private readonly int _verifyConcurrency; private volatile bool _disposed; @@ -65,7 +68,9 @@ public EraStore( _blockValidator = blockValidator; _trustedAccumulators = trustedAccumulators; _validator = validator; - _maxEraSize = maxEraSize; + // Boundary cast — safe: validated > 0 immediately above, and era sizes + // are small counts (e.g. 8192) that trivially fit in uint. + _maxEraSize = (uint)maxEraSize; _maxOpenFile = Environment.ProcessorCount * 2; _verifyConcurrency = verifyConcurrency == 0 ? Environment.ProcessorCount : verifyConcurrency; @@ -104,11 +109,14 @@ public EraStore( { using EraRenter f = RentReader(FirstEpoch, out EraReader firstReader); using EraRenter l = RentReader(LastEpoch, out EraReader lastReader); - return ((ulong)firstReader.FirstBlock, (ulong)lastReader.LastBlock); + return (firstReader.FirstBlock, lastReader.LastBlock); }); } - private long GetEpochNumber(ulong blockNumber) => (long)(blockNumber / (ulong)_maxEraSize); + // uint promotes cleanly to ulong in the division — no cast needed. + // The (long) cast on the result is a necessary boundary: epoch dictionary + // keys are long throughout this file. + private long GetEpochNumber(ulong blockNumber) => (long)(blockNumber / _maxEraSize); private EraReader GetReader(long epoch) => !_epochs.TryGetValue(epoch, out string? path) ? throw new ArgumentOutOfRangeException(nameof(epoch), epoch, "Epoch not available.") @@ -158,7 +166,7 @@ public ulong NextEraStart(ulong blockNumber) { long epoch = GetEpochNumber(blockNumber); using EraRenter _ = RentReader(epoch, out EraReader reader); - return (ulong)reader.LastBlock + 1; + return reader.LastBlock + 1; } public async Task<(Block?, TxReceipt[]?)> FindBlockAndReceipts(ulong number, bool ensureValidated = true, CancellationToken cancellation = default) diff --git a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs index 9e67020d2f24..3600e3a6a2bc 100644 --- a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs +++ b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs @@ -25,7 +25,10 @@ public sealed class RemoteEraStoreDecorator : IEraStore private readonly IEraStore? _localStore; private readonly IRemoteEraClient _client; private readonly string _downloadDir; - private readonly int _maxEraSize; + // Changed int → uint: era size is always a small positive count (e.g. 8192), + // never negative, so uint is the honest type and avoids (ulong) casts in + // epoch arithmetic. + private readonly uint _maxEraSize; private readonly ISpecProvider _specProvider; private readonly IBlockValidator _blockValidator; private readonly Proofs.Validator? _validator; @@ -76,7 +79,9 @@ public RemoteEraStoreDecorator( _localStore = localStore; _client = client; _downloadDir = downloadDir; - _maxEraSize = maxEraSize; + // Boundary cast — safe: validated > 0 immediately above, and era sizes + // are small counts (e.g. 8192) that trivially fit in uint. + _maxEraSize = (uint)maxEraSize; _specProvider = specProvider; _blockValidator = blockValidator; _trustedAccumulators = trustedAccumulators; @@ -95,11 +100,12 @@ public RemoteEraStoreDecorator( if (b is not null) return (b, r); } - int epoch = (int)(number / (ulong)_maxEraSize); + // uint promotes cleanly to ulong — no cast needed. + int epoch = (int)(number / _maxEraSize); string localPath = await EnsureEpochAvailableAsync(epoch, ensureValidated, cancellation).ConfigureAwait(false); using EraRenter renter = RentReader(epoch, localPath); - if (number > (ulong)renter.Reader.LastBlock) return (null, null); + if (number > renter.Reader.LastBlock) return (null, null); (Block block, TxReceipt[] receipts) = await renter.Reader.GetBlockByNumber(number, cancellation).ConfigureAwait(false); return (block, receipts); } @@ -111,10 +117,11 @@ public ulong NextEraStart(ulong blockNumber) if (_localStore is not null && _localStore.HasEpoch(blockNumber)) return _localStore.NextEraStart(blockNumber); - int epoch = (int)(blockNumber / (ulong)_maxEraSize); + // uint promotes cleanly to ulong — no cast needed. + int epoch = (int)(blockNumber / _maxEraSize); string localPath = EnsureEpochAvailableAsync(epoch, ensureValidated: false).GetAwaiter().GetResult(); using EraReader reader = new(localPath); - return (ulong)reader.LastBlock + 1; + return reader.LastBlock + 1; } public void Dispose() diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs index 929624222270..50b01989dd15 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs @@ -358,14 +358,14 @@ private Transaction[] BuildLegacyTransfers(int count, int startNonce) return txs; } - private Transaction[] BuildEip1559Transfers(int count, uint startNonce) + private Transaction[] BuildEip1559Transfers(int count, int startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction .WithType(TxType.EIP1559) - .WithNonce(startNonce + i) + .WithNonce((ulong)(startNonce + i)) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(21_000) diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs index fb54e572c28b..fa8ad668e019 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs @@ -24,9 +24,9 @@ public partial class BN254AddPrecompile : IPrecompile public static string Name => "BN254_ADD"; /// - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 150L : 500L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 150UL : 500UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) { diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs index eeece3e27179..8f6d91536459 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs @@ -24,9 +24,9 @@ public partial class BN254MulPrecompile : IPrecompile public static string Name => "BN254_MUL"; /// - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 6_000L : 40_000L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 6_000UL : 40_000UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) { diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingCheckPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingCheckPrecompile.cs index 64c1a606a3a1..217c5723dcbd 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingCheckPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingCheckPrecompile.cs @@ -22,10 +22,10 @@ public partial class BN254PairingCheckPrecompile : IPrecompile "BN254_PAIRING"; /// - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 45_000L : 100_000L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 45_000UL : 100_000UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - (releaseSpec.IsEip1108Enabled ? 34_000L : 80_000L) * (inputData.Length / BN254.PairSize); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + (releaseSpec.IsEip1108Enabled ? 34_000UL : 80_000UL) * (ulong)(inputData.Length / BN254.PairSize); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs index 50c32fa7d5ab..2dff0761a486 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs @@ -27,7 +27,7 @@ private Blake2FPrecompile() { } public static string Name => "BLAKE2F"; - public long BaseGasCost(IReleaseSpec _) => 0; + public ulong BaseGasCost(IReleaseSpec _) => 0UL; public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) { @@ -36,15 +36,15 @@ public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) return inputData; } - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) { if (inputData.Length != RequiredInputLength) - return 0; + return 0UL; byte finalBlock = inputData.Span[212]; if (finalBlock != 0 && finalBlock != 1) - return 0; + return 0UL; uint rounds = BinaryPrimitives.ReadUInt32BigEndian(inputData[..4].Span); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381Fp2ToG2Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381Fp2ToG2Precompile.cs index 72e0a12aaf47..78ce54c581bd 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381Fp2ToG2Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381Fp2ToG2Precompile.cs @@ -20,9 +20,9 @@ private Bls12381Fp2ToG2Precompile() { } public static string Name => "BLS12_MAP_FP2_TO_G2"; - public long BaseGasCost(IReleaseSpec _) => 23800L; + public ulong BaseGasCost(IReleaseSpec _) => 23800UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381FpToG1Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381FpToG1Precompile.cs index 90b34c120b98..8eecd9d2254e 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381FpToG1Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381FpToG1Precompile.cs @@ -20,9 +20,9 @@ private Bls12381FpToG1Precompile() { } public static string Name => "BLS12_MAP_FP_TO_G1"; - public long BaseGasCost(IReleaseSpec _) => 5500L; + public ulong BaseGasCost(IReleaseSpec _) => 5500UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1AddPrecompile.cs index 25646c73642b..17f71c26827c 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1AddPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1AddPrecompile.cs @@ -20,9 +20,9 @@ private Bls12381G1AddPrecompile() { } public static string Name => "BLS12_G1ADD"; - public long BaseGasCost(IReleaseSpec _) => 375L; + public ulong BaseGasCost(IReleaseSpec _) => 375UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs index bac2e9028b33..fdcb088bc2a7 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs @@ -22,12 +22,12 @@ private Bls12381G1MsmPrecompile() { } public static string Name => "BLS12_G1MSM"; - public long BaseGasCost(IReleaseSpec _) => 0L; + public ulong BaseGasCost(IReleaseSpec _) => 0UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) { int k = inputData.Length / ItemSize; - return 12000L * k * Eip2537.DiscountForG1(k) / 1000; + return 12000UL * (ulong)k * (ulong)Eip2537.DiscountForG1(k) / 1000UL; } public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2AddPrecompile.cs index 457a2517bb6c..da13475c026f 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2AddPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2AddPrecompile.cs @@ -20,9 +20,9 @@ private Bls12381G2AddPrecompile() { } public static string Name => "BLS12_G2ADD"; - public long BaseGasCost(IReleaseSpec _) => 600L; + public ulong BaseGasCost(IReleaseSpec _) => 600UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs index ac1eba0864c5..54fb248dc3aa 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs @@ -22,12 +22,12 @@ private Bls12381G2MsmPrecompile() { } public static string Name => "BLS12_G2MSM"; - public long BaseGasCost(IReleaseSpec _) => 0L; + public ulong BaseGasCost(IReleaseSpec _) => 0UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) { int k = inputData.Length / ItemSize; - return 22500L * k * Eip2537.DiscountForG2(k) / 1000; + return 22500UL * (ulong)k * (ulong)Eip2537.DiscountForG2(k) / 1000UL; } public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs index 6ce3295ce8c0..b67b734e03b1 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs @@ -22,9 +22,9 @@ private Bls12381PairingCheckPrecompile() { } public static string Name => "BLS12_PAIRING_CHECK"; - public long BaseGasCost(IReleaseSpec _) => 37700L; + public ulong BaseGasCost(IReleaseSpec _) => 37700UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 32600L * (inputData.Length / PairSize); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 32600UL * (ulong)(inputData.Length / PairSize); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ECRecoverPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ECRecoverPrecompile.cs index 43b971eeb485..b22aede3e2cc 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/ECRecoverPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ECRecoverPrecompile.cs @@ -25,9 +25,9 @@ private ECRecoverPrecompile() { } private const int InputLength = 128; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0UL; - public long BaseGasCost(IReleaseSpec releaseSpec) => 3000L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 3000UL; // RunInternal zero-pads short inputs to InputLength, so trailing zeros are insignificant. // Trimming them normalizes e.g. a 64-byte input and its 128-byte zero-padded equivalent to the same key. diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs index ea9007407045..d129e08fd85a 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs @@ -23,10 +23,10 @@ private IdentityPrecompile() // making caching strictly worse than direct execution for this precompile. public bool SupportsCaching => false; - public long BaseGasCost(IReleaseSpec releaseSpec) => 15L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 15UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - (long)(3UL * EvmCalculations.Div32Ceiling(inputData.Length)); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + 3UL * EvmCalculations.Div32Ceiling(inputData.Length); public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => inputData.ToArray(); } diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/KzgPointEvaluationPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/KzgPointEvaluationPrecompile.cs index 17058b1cb1c5..d16b2b96e1b8 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/KzgPointEvaluationPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/KzgPointEvaluationPrecompile.cs @@ -23,9 +23,9 @@ public partial class KzgPointEvaluationPrecompile : IPrecompile "KZG_POINT_EVALUATION"; - public long BaseGasCost(IReleaseSpec releaseSpec) => 50_000L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 50_000UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0UL; public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs index 28f8f511f55f..0dfe52e01b3f 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs @@ -43,7 +43,7 @@ private ModExpPrecompile() { } public static string Name => "MODEXP"; - public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 0UL; /// /// @@ -55,7 +55,7 @@ private ModExpPrecompile() { } /// /// /// Gas cost of the MODEXP operation in the context of EIP2565 - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { if (!releaseSpec.IsEip2565Enabled) { @@ -73,7 +73,7 @@ public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec } catch (OverflowException) { - return long.MaxValue; + return ulong.MaxValue; } } @@ -94,7 +94,7 @@ public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec); [MethodImpl(MethodImplOptions.NoInlining)] - private static long DataGasCostShortInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) + private static ulong DataGasCostShortInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) { Debug.Assert(inputData.Length < LengthsLengths); @@ -104,7 +104,7 @@ private static long DataGasCostShortInternal(ReadOnlySpan inputData, IRele return DataGasCostInternal(extendedInput, releaseSpec); } - private static long DataGasCostInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) + private static ulong DataGasCostInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) { (uint baseLength, uint expLength, uint modulusLength) = GetInputLengths(inputData); ulong complexity = MultComplexity(baseLength, modulusLength, releaseSpec.IsEip7883Enabled); @@ -129,9 +129,9 @@ private static long DataGasCostInternal(ReadOnlySpan inputData, IReleaseSp result /= 3; } - return result > long.MaxValue || overflow - ? long.MaxValue - : (long)Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (ulong)result); + return result > ulong.MaxValue || overflow + ? ulong.MaxValue + : Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (ulong)result); } /// diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs index 233771619e60..c71b3ed15855 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs @@ -28,7 +28,7 @@ private ModExpPrecompilePreEip2565() public static string Name => "MODEXP"; - public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 0UL; public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) { @@ -57,7 +57,7 @@ private static int ReadCappedLength32(ReadOnlySpan span) return low > int.MaxValue ? int.MaxValue : (int)low; } - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { try { @@ -67,11 +67,11 @@ public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec } catch (OverflowException) { - return long.MaxValue; + return ulong.MaxValue; } } - private static long DataGasCostInternal(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + private static ulong DataGasCostInternal(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { Span extendedInput = stackalloc byte[96]; inputData[..Math.Min(96, inputData.Length)].Span @@ -80,7 +80,7 @@ private static long DataGasCostInternal(ReadOnlyMemory inputData, IRelease return DataGasCostInternal(extendedInput, inputData); } - private static long DataGasCostInternal(ReadOnlySpan extendedInput, ReadOnlyMemory inputData) + private static ulong DataGasCostInternal(ReadOnlySpan extendedInput, ReadOnlyMemory inputData) { UInt256 baseLength = new(extendedInput[..32], true); UInt256 expLength = new(extendedInput.Slice(32, 32), true); @@ -94,7 +94,7 @@ private static long DataGasCostInternal(ReadOnlySpan extendedInput, ReadOn UInt256 lengthOver32 = expLength <= 32 ? 0 : expLength - 32; UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes); UInt256 gas = complexity * UInt256.Max(adjusted, UInt256.One) / 20; - return gas > long.MaxValue ? long.MaxValue : (long)gas; + return gas > ulong.MaxValue ? ulong.MaxValue : (ulong)gas; } public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs index afa0fecae8c6..e960692247d3 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs @@ -17,10 +17,10 @@ private Ripemd160Precompile() { } public static string Name => "RIPEMD160"; - public long BaseGasCost(IReleaseSpec releaseSpec) => 600L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 600UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - (long)(120UL * EvmCalculations.Div32Ceiling(inputData.Length)); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + 120UL * EvmCalculations.Div32Ceiling(inputData.Length); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); } diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/SecP256r1Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/SecP256r1Precompile.cs index 267ec17986ff..fda881c491af 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/SecP256r1Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/SecP256r1Precompile.cs @@ -20,9 +20,9 @@ public partial class SecP256r1Precompile : IPrecompile public static string Name => "P256VERIFY"; - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip7951Enabled ? 6900L : 3450L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip7951Enabled ? 6900UL : 3450UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0L; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 0UL; // should produce empty valid output for all invalid-length inputs public ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) => diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs index 554b12a9eea2..aa456b8abc86 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs @@ -17,10 +17,10 @@ private Sha256Precompile() { } public static string Name => "SHA256"; - public long BaseGasCost(IReleaseSpec releaseSpec) => 60L; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => 60UL; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => - (long)(12UL * EvmCalculations.Div32Ceiling(inputData.Length)); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => + 12UL * EvmCalculations.Div32Ceiling(inputData.Length); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); } diff --git a/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs b/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs index df27a3953c3c..1af43bea1277 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CallDataLoadTests.cs @@ -94,7 +94,7 @@ public static IEnumerable CallDataLoadCases() // 0x_1_0000_0009: low 32 bits = 9, true value > 4 billion. A buggy truncate-to-uint // implementation would read bytes[9..32]||zeros instead of the spec-correct zero word. - yield return new TestCaseData(ThirtyTwoSequential, (UInt256)((ulong)uint.MaxValue + 10UL), new byte[32]) + yield return new TestCaseData(ThirtyTwoSequential, (UInt256)(uint.MaxValue + 10UL), new byte[32]) .SetName("offset_above_uint32_returns_zero"); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs index 36cbce385a2c..590de0ee5b30 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs @@ -39,8 +39,8 @@ public void Simple_routine([Random(int.MinValue, int.MaxValue, 100)] int seed) public void Overflow_gas_cost() { Prepare input = Prepare.EvmCode.FromCode("0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010001"); - long gas = ModExpPrecompile.Instance.DataGasCost(input.Done, Berlin.Instance); - Assert.That(gas, Is.EqualTo(long.MaxValue)); + ulong gas = ModExpPrecompile.Instance.DataGasCost(input.Done, Berlin.Instance); + Assert.That(gas, Is.EqualTo(ulong.MaxValue)); } [TestCase("0x00000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")] @@ -49,8 +49,8 @@ public void ModExp_run_should_not_throw_exception(string inputStr) { Prepare input = Prepare.EvmCode.FromCode(inputStr); Assert.DoesNotThrow(() => ModExpPrecompile.Instance.Run(input.Done.ToArray(), London.Instance)); - long gas = ModExpPrecompile.Instance.DataGasCost(input.Done, London.Instance); - Assert.That(gas, Is.EqualTo(200)); + ulong gas = ModExpPrecompile.Instance.DataGasCost(input.Done, London.Instance); + Assert.That(gas, Is.EqualTo(200UL)); } // empty base diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs index 9a2de53e8662..9128f1bef29c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs @@ -38,10 +38,10 @@ public void TestEip7823(bool isEip7823Enabled, bool success, uint inputBaseLengt Assert.That(TestSuccess(input, spec), Is.EqualTo(success)); - long gas = TestGas(input, spec); + ulong gas = TestGas(input, spec); if (success) { - Assert.That(gas, Is.LessThan(long.MaxValue)); + Assert.That(gas, Is.LessThan(ulong.MaxValue)); } } @@ -58,8 +58,8 @@ public void TestInvalid(string inputHex) Assert.That(TestSuccess(input, specDisabled), Is.EqualTo(false)); Assert.That(TestSuccess(input, specEnabled), Is.EqualTo(false)); - Assert.That(TestGas(input, specDisabled), Is.EqualTo(long.MaxValue)); - Assert.That(TestGas(input, specEnabled), Is.EqualTo(long.MaxValue)); + Assert.That(TestGas(input, specDisabled), Is.EqualTo(ulong.MaxValue)); + Assert.That(TestGas(input, specEnabled), Is.EqualTo(ulong.MaxValue)); } private static IEnumerable LimitTests @@ -89,6 +89,6 @@ private static bool TestSuccess(byte[] input, IReleaseSpec spec) return result; } - private static long TestGas(byte[] input, IReleaseSpec spec) + private static ulong TestGas(byte[] input, IReleaseSpec spec) => ModExpPrecompile.Instance.DataGasCost(input, spec); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs index 818ab34fcf82..5c95265a02f8 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs @@ -20,8 +20,8 @@ public void DataGasCost([ValueSource(nameof(Eip7883TestCases))] Eip7883TestCase ReadOnlyMemory inputData = PrepareInput(test.BaseLength, test.ExpLength, test.ModulusLength); IReleaseSpec? spec = test.FusakaEnabled ? Osaka.Instance : Prague.Instance; - long gas = ModExpPrecompile.Instance.DataGasCost(inputData, spec); - Assert.That(gas, Is.EqualTo(test.Result)); + ulong gas = ModExpPrecompile.Instance.DataGasCost(inputData, spec); + Assert.That(gas, Is.EqualTo((ulong)test.Result)); } public class Eip7883TestCase diff --git a/src/Nethermind/Nethermind.Evm.Test/KzgPointEvaluationPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/KzgPointEvaluationPrecompileTests.cs index b850af212f9b..55549df07152 100644 --- a/src/Nethermind/Nethermind.Evm.Test/KzgPointEvaluationPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/KzgPointEvaluationPrecompileTests.cs @@ -55,8 +55,8 @@ static TestCaseData AddExpectedResult(TestCaseData t, bool expectedResult) => [TestCaseSource(nameof(GasTests))] public void Test_PointEvaluationPrecompile_Has_Specific_Constant_Gas_Cost(byte[] input) { - const long fixedGasCost = 50000; - long gasSpent = KzgPointEvaluationPrecompile.Instance.DataGasCost(input, Cancun.Instance) + + const ulong fixedGasCost = 50000; + ulong gasSpent = KzgPointEvaluationPrecompile.Instance.DataGasCost(input, Cancun.Instance) + KzgPointEvaluationPrecompile.Instance.BaseGasCost(Cancun.Instance); Assert.That(gasSpent, Is.EqualTo(fixedGasCost)); } diff --git a/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs index 3a40956cae65..2079e376bad1 100644 --- a/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs @@ -82,7 +82,7 @@ protected void RunTest(string input, string output, bool status, IReleaseSpec? s private static void RunTestCore(TestCase testCase, string? reason = null) { - long gas = Instance.BaseGasCost(testCase.Spec) + Instance.DataGasCost(testCase.Input, testCase.Spec); + ulong gas = Instance.BaseGasCost(testCase.Spec) + Instance.DataGasCost(testCase.Input, testCase.Spec); Result result = Instance.Run(testCase.Input, testCase.Spec); @@ -93,7 +93,7 @@ private static void RunTestCore(TestCase testCase, string? reason = null) if (testCase.Gas is not null) { - Assert.That(gas, Is.EqualTo(testCase.Gas), reason); + Assert.That((long)gas, Is.EqualTo(testCase.Gas), reason); } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index d5d4613e7cfb..36ed44365fcf 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -288,7 +288,7 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi Transaction tx = Build.A.Transaction.WithGasLimit(30000).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; EstimateGasTracer tracer = new(); - tracer.MarkAsSuccess(Address.Zero, (ulong)totalGas, [], []); + tracer.MarkAsSuccess(Address.Zero, totalGas, [], []); IReadOnlyStateProvider stateProvider = Substitute.For(); stateProvider.GetBalance(Arg.Any
()).Returns(new UInt256(1)); GasEstimator sut = new( @@ -338,7 +338,7 @@ public void Estimate_simple_transfer_with_errorMargin_should_be_exact() using (Assert.EnterMultipleScope()) { Assert.That(err, Is.Null); - Assert.That(result, Is.EqualTo((ulong)totalGas)); + Assert.That(result, Is.EqualTo(totalGas)); } } diff --git a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs index f275a3beb183..3a13edf8afb8 100644 --- a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs @@ -49,7 +49,7 @@ public static ulong CalculateBlobGas(Transaction[] transactions) return CalculateBlobGas(blobCount); } - public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction transaction, UInt256 blobGasPriceUpdateFraction, out UInt256 blobBaseFee) + public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction transaction, ulong blobGasPriceUpdateFraction, out UInt256 blobBaseFee) { if (!TryCalculateFeePerBlobGas(header.ExcessBlobGas.Value, blobGasPriceUpdateFraction, out UInt256 feePerBlobGas)) { @@ -59,14 +59,14 @@ public static bool TryCalculateBlobBaseFee(BlockHeader header, Transaction trans return !UInt256.MultiplyOverflow(CalculateBlobGas(transaction), feePerBlobGas, out blobBaseFee); } - public static bool TryCalculateFeePerBlobGas(BlockHeader header, UInt256 blobGasPriceUpdateFraction, out UInt256 feePerBlobGas) + public static bool TryCalculateFeePerBlobGas(BlockHeader header, ulong blobGasPriceUpdateFraction, out UInt256 feePerBlobGas) { feePerBlobGas = UInt256.MaxValue; return header.ExcessBlobGas is not null && TryCalculateFeePerBlobGas(header.ExcessBlobGas.Value, blobGasPriceUpdateFraction, out feePerBlobGas); } - public static bool TryCalculateFeePerBlobGas(ulong excessBlobGas, UInt256 blobGasPriceUpdateFraction, out UInt256 feePerBlobGas) + public static bool TryCalculateFeePerBlobGas(ulong excessBlobGas, ulong blobGasPriceUpdateFraction, out UInt256 feePerBlobGas) { static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denominator, out UInt256 feePerBlobGas) { @@ -110,7 +110,8 @@ static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denomin return false; } - return !FakeExponentialOverflow(Eip4844Constants.MinBlobGasPrice, excessBlobGas, blobGasPriceUpdateFraction, out feePerBlobGas); + UInt256 denominator = blobGasPriceUpdateFraction; + return !FakeExponentialOverflow(Eip4844Constants.MinBlobGasPrice, excessBlobGas, denominator, out feePerBlobGas); } public static ulong? CalculateExcessBlobGas(BlockHeader? parentBlockHeader, IReleaseSpec releaseSpec) diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 91dbfb065211..0b3866ba9bd2 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -421,7 +421,7 @@ public static bool ConsumeLogEmission(ref EthereumGasPolicy gas, long topicCount [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ConsumeDataCopyGas(ref EthereumGasPolicy gas, bool isExternalCode, ulong baseCost, ulong dataCost) - => Consume(ref gas, (ulong)(baseCost + dataCost)); + => Consume(ref gas, baseCost + dataCost); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void OnBeforeInstructionTrace(in EthereumGasPolicy gas, int pc, Instruction instruction, int depth) { } @@ -459,11 +459,11 @@ public static IntrinsicGas CalculateIntrinsicGas(Transaction (ulong authRegularCost, ulong authStateCost) = IGasPolicy.AuthorizationListCost(tx, spec); ulong accessListCost = IGasPolicy.AccessListCost(tx, spec, floorTokensInAccessList); - ulong regularGas = (ulong)(GasCostOf.Transaction + ulong regularGas = GasCostOf.Transaction + DataCost(tx, spec, tokensInCallData) + CreateCost(tx, spec) + accessListCost - + authRegularCost); + + authRegularCost; ulong floorCost = IGasPolicy.CalculateFloorCost(tx, spec, tokensInCallData, floorTokensInAccessList); ulong createStateCost = CreateStateCost(tx, spec); ulong totalStateCost = authStateCost + createStateCost; @@ -472,8 +472,8 @@ public static IntrinsicGas CalculateIntrinsicGas(Transaction new EthereumGasPolicy { Value = regularGas, - StateReservoir = (ulong)totalStateCost, - StateGasUsed = (ulong)totalStateCost, + StateReservoir = totalStateCost, + StateGasUsed = totalStateCost, }, FromULong(floorCost)) : new IntrinsicGas(FromULong(regularGas), FromULong(floorCost)); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs index 8ca97385722e..93c79c74f913 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Bitwise.cs @@ -47,7 +47,7 @@ public static EvmExceptionType InstructionBitwise(Virtua where TOpBitwise : struct, IOpBitwise { // Deduct the operation's gas cost. - TGasPolicy.Consume(ref gas, (ulong)TOpBitwise.GasCost); + TGasPolicy.Consume(ref gas, TOpBitwise.GasCost); // Pop the first operand from the stack by reference to minimize copying. ref byte bytesRef = ref stack.PopBytesByRef(); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs index 26e8c7d7b27e..ef35a96ee1f7 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs @@ -146,7 +146,7 @@ public static EvmExceptionType InstructionCall( if (!stack.PopUInt256(out UInt256 a, out UInt256 b, out UInt256 result)) goto StackUnderflow; - TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: false, GasCostOf.VeryLow, GasCostOf.Memory * (ulong)EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); + TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: false, GasCostOf.VeryLow, GasCostOf.Memory * EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); if (outOfGas) goto OutOfGas; if (!result.IsZero) @@ -164,7 +164,7 @@ public static EvmExceptionType InstructionExtCodeCopy( goto StackUnderflow; // Deduct gas cost: cost for external code access plus memory expansion cost. - TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: true, spec.GasCosts.ExtCodeCost, GasCostOf.Memory * (ulong)EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); + TGasPolicy.ConsumeDataCopyGas(ref gas, isExternalCode: true, spec.GasCosts.ExtCodeCost, GasCostOf.Memory * EvmCalculations.Div32Ceiling(in result, out bool outOfGas)); if (outOfGas) goto OutOfGas; // Charge gas for account access (considering hot/cold storage costs). @@ -235,7 +235,7 @@ public static EvmExceptionType InstructionExtCodeSize( { IReleaseSpec spec = vm.Spec; // Deduct the gas cost for external code access. - TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.ExtCodeCost); + TGasPolicy.Consume(ref gas, spec.GasCosts.ExtCodeCost); // Pop the account address from the stack. Address address = stack.PopAddress(); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Crypto.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Crypto.cs index d2ef3f4f9205..d47130c0dec8 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Crypto.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Crypto.cs @@ -28,7 +28,7 @@ public static EvmExceptionType InstructionKeccak256(Vi goto StackUnderflow; // Deduct gas: base cost plus additional cost per 32-byte word. - TGasPolicy.Consume(ref gas, (ulong)(GasCostOf.Sha3 + GasCostOf.Sha3Word * (ulong)EvmCalculations.Div32Ceiling(in b, out bool outOfGas))); + TGasPolicy.Consume(ref gas, GasCostOf.Sha3 + GasCostOf.Sha3Word * EvmCalculations.Div32Ceiling(in b, out bool outOfGas)); if (outOfGas) goto OutOfGas; VmState vmState = vm.VmState; diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs index f3c1c2113860..9b6182581ac5 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs @@ -545,7 +545,7 @@ public static EvmExceptionType InstructionBalance(Virt { IReleaseSpec spec = vm.Spec; // Deduct gas cost for balance operation as per specification. - TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.BalanceCost); + TGasPolicy.Consume(ref gas, spec.GasCosts.BalanceCost); Address address = stack.PopAddress(); if (address is null) goto StackUnderflow; @@ -605,7 +605,7 @@ public static EvmExceptionType InstructionExtCodeHash( where TTracingInst : struct, IFlag { IReleaseSpec spec = vm.Spec; - TGasPolicy.Consume(ref gas, (ulong)spec.GasCosts.ExtCodeHashCost); + TGasPolicy.Consume(ref gas, spec.GasCosts.ExtCodeHashCost); Address address = stack.PopAddress(); if (address is null) goto StackUnderflow; @@ -673,7 +673,7 @@ public static EvmExceptionType InstructionGas(VirtualM if (TGasPolicy.GetRemainingGas(in gas) < 0) goto OutOfGas; // Push the remaining gas (as unsigned 64-bit) onto the stack. - return stack.PushUInt64((ulong)TGasPolicy.GetRemainingGas(in gas)); + return stack.PushUInt64(TGasPolicy.GetRemainingGas(in gas)); // Jump forward to be unpredicted by the branch predictor. OutOfGas: return EvmExceptionType.OutOfGas; diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index 43d609389941..ba1fd327a858 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -297,7 +297,7 @@ public static EvmExceptionType InstructionMCopy(Virtua if (!stack.PopUInt256(out UInt256 a, out UInt256 b, out UInt256 c)) goto StackUnderflow; // Calculate additional gas cost based on the length (using a division rounding-up method) and deduct the total cost. - TGasPolicy.Consume(ref gas, GasCostOf.VeryLow + GasCostOf.VeryLow * (ulong)(EvmCalculations.Div32Ceiling(c, out bool outOfGas))); + TGasPolicy.Consume(ref gas, GasCostOf.VeryLow + GasCostOf.VeryLow * EvmCalculations.Div32Ceiling(c, out bool outOfGas)); if (outOfGas) goto OutOfGas; if (c.IsZero) @@ -365,7 +365,7 @@ internal static EvmExceptionType InstructionSStoreUnmetered ReadOnlyMemory NormalizeInput(ReadOnlyMemory inputData) => inputData; - long BaseGasCost(IReleaseSpec releaseSpec); - long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec); + ulong BaseGasCost(IReleaseSpec releaseSpec); + ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec); // N.B. returns a byte array so that inputData cannot be returned // this can lead to the wrong value being returned due to the cache modifying inputData diff --git a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs index f1e8f8ca915c..5cc8e538ceef 100644 --- a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs @@ -19,7 +19,7 @@ public int MaxProductionBlobCount(int? blockProductionBlobLimit) => public ulong GetBaseDataCost(Transaction tx) => tx.IsContractCreation && spec.IsEip3860Enabled - ? (ulong)EvmCalculations.Div32Ceiling((UInt256)tx.Data.Length) * GasCostOf.InitCodeWord + ? EvmCalculations.Div32Ceiling((UInt256)tx.Data.Length) * GasCostOf.InitCodeWord : 0; } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs index 8a5215754d06..3c363695fd21 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs @@ -20,7 +20,7 @@ TransactionResult Process( public interface IBlobBaseFeeCalculator { bool TryCalculateBlobFees(BlockHeader header, Transaction transaction, - UInt256 blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee); + ulong blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee); } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 771237f887ec..1922edf74188 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -57,7 +57,7 @@ public class BlobBaseFeeCalculator : ITransactionProcessor.IBlobBaseFeeCalculato public static BlobBaseFeeCalculator Instance { get; } = new BlobBaseFeeCalculator(); public bool TryCalculateBlobFees(BlockHeader header, Transaction transaction, - UInt256 blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee) + ulong blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee) { if (!BlobGasCalculator.TryCalculateFeePerBlobGas(header, blobGasPriceUpdateFraction, out feePerBlobGas)) { @@ -1488,7 +1488,7 @@ protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec WorldState.AddToBalanceAndCreateIfNotExists(header.GasBeneficiary!, fees, spec); } - UInt256 eip1559Fees = !tx.IsFree() ? header.BaseFeePerGas * (ulong)spentGas : UInt256.Zero; + UInt256 eip1559Fees = !tx.IsFree() ? header.BaseFeePerGas * spentGas : UInt256.Zero; UInt256 collectedFees = spec.IsEip1559Enabled ? eip1559Fees : UInt256.Zero; if (tx.SupportsBlobs && spec.IsEip4844FeeCollectorEnabled) diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 153417102827..59aaebf0afac 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -477,7 +477,9 @@ private void TryChargeAndDepositCode( } else if (!chargedCodeDeposit && _txTracer.IsTracingActions) { - _txTracer.ReportActionEnd(0L, callCodeOwner, code); + // Cast note: 0UL is the canonical gas value here — no gas remains after a failed-but-non-halting + // deposit. ReportActionEnd takes ulong; using 0UL avoids any implicit narrowing ambiguity. + _txTracer.ReportActionEnd(0UL, callCodeOwner, code); } } @@ -991,8 +993,9 @@ private CallResult RunPrecompile(VmState state) IPrecompile precompile = state.Env.CodeInfo.Precompile!; IReleaseSpec spec = BlockExecutionContext.Spec; - long baseGasCost = precompile.BaseGasCost(spec); - long dataGasCost = precompile.DataGasCost(callData, spec); + // Both fields are ulong after IPrecompile.BaseGasCost / DataGasCost interface migration. + ulong baseGasCost = precompile.BaseGasCost(spec); + ulong dataGasCost = precompile.DataGasCost(callData, spec); bool wasCreated = _worldState.AddToBalanceAndCreateIfNotExists(state.Env.ExecutingAccount, in transferValue, spec); @@ -1012,8 +1015,11 @@ private CallResult RunPrecompile(VmState state) _parityTouchBugAccount.ShouldDelete = true; } - if ((ulong)baseGasCost + (ulong)dataGasCost > (ulong)long.MaxValue || - !TGasPolicy.UpdateGas(ref gas, (ulong)(baseGasCost + dataGasCost))) + // Guard against addition overflow before summing into UpdateGas. + // The previous form — (ulong)a + (ulong)b > ulong.MaxValue — was tautologically false: + // the addition already happened in ulong and silently wrapped before the comparison. + if (baseGasCost > ulong.MaxValue - dataGasCost || + !TGasPolicy.UpdateGas(ref gas, baseGasCost + dataGasCost)) { return new(default, precompileSuccess: false, shouldRevert: true, EvmExceptionType.OutOfGas); } @@ -1300,12 +1306,9 @@ protected virtual CallResult RunByteCode( exceptionType = opcodeMethod(this, ref stack, ref gas, ref programCounter); } - // If gas is exhausted, jump to the out-of-gas handler. - if (TGasPolicy.GetRemainingGas(in gas) < 0) - { - OpCodeCount += opCodeCount; - goto OutOfGas; - } + // GetRemainingGas returns ulong; the previous < 0 check here was dead code. + // Gas exhaustion is signalled by opcodes returning EvmExceptionType.OutOfGas + // (via TGasPolicy.UpdateGas returning false), caught by the exceptionType check below. // Call gas policy hook after instruction execution. TGasPolicy.OnAfterInstructionTrace(in gas); @@ -1373,11 +1376,6 @@ protected virtual CallResult RunByteCode( Revert: // Return a CallResult indicating a revert. return new CallResult((byte[])ReturnData, null, shouldRevert: true, exceptionType); - - OutOfGas: - TGasPolicy.SetOutOfGas(ref gas); - // Set the exception type to OutOfGas if gas has been exhausted. - exceptionType = EvmExceptionType.OutOfGas; ReturnFailure: // EIP-8037: write gas back to state on failure so RestoreChildStateGasOnHalt // can read accumulated StateGasUsed/StateGasSpill from the child frame. diff --git a/src/Nethermind/Nethermind.Facade/BlobBaseFeeOverrideCalculatorDecorator.cs b/src/Nethermind/Nethermind.Facade/BlobBaseFeeOverrideCalculatorDecorator.cs index 4478577200b6..40814a34dd5b 100644 --- a/src/Nethermind/Nethermind.Facade/BlobBaseFeeOverrideCalculatorDecorator.cs +++ b/src/Nethermind/Nethermind.Facade/BlobBaseFeeOverrideCalculatorDecorator.cs @@ -13,7 +13,7 @@ public class BlobBaseFeeOverrideCalculatorDecorator( IBlobBaseFeeOverrideProvider overrideProvider) : ITransactionProcessor.IBlobBaseFeeCalculator { public bool TryCalculateBlobFees(BlockHeader header, Transaction transaction, - UInt256 blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee) + ulong blobGasPriceUpdateFraction, out UInt256 feePerBlobGas, out UInt256 totalBlobBaseFee) { if (overrideProvider.BlobBaseFeeOverride is not null) { diff --git a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs index 24ba32b96f73..fc6bdb0e06ed 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs @@ -128,8 +128,8 @@ public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider s public byte[]? Signature { get; set; } public long Size { get; set; } public Hash256 StateRoot { get; set; } - [JsonConverter(typeof(NullableRawLongConverter))] - public long? Step { get; set; } + [JsonConverter(typeof(NullableRawULongConverter))] + public ulong? Step { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? TotalDifficulty { get; set; } public UInt256 Timestamp { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs index eed8d955bbc9..ce644e582e59 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/BlockHeaderForRpc.cs @@ -85,8 +85,8 @@ public BlockHeaderForRpc(BlockHeader header, ISpecProvider? specProvider = null) public byte[]? Signature { get; set; } - [JsonConverter(typeof(NullableRawLongConverter))] - public long? Step { get; set; } + [JsonConverter(typeof(NullableRawULongConverter))] + public ulong? Step { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Bloom? LogsBloom { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs b/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs index 1cbbcca5e396..a39e535dd111 100644 --- a/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs +++ b/src/Nethermind/Nethermind.Facade/Filters/LogIndexFilterVisitor.cs @@ -181,6 +181,6 @@ private IEnumerator Visit(int topicIndex, Hash256 topic) => public static class LogIndexFilterVisitorExtensions { - public static IEnumerable EnumerateBlockNumbersFor(this ILogIndexStorage storage, LogFilter filter, long fromBlock, long toBlock) => + public static IEnumerable EnumerateBlockNumbersFor(this ILogIndexStorage storage, LogFilter filter, ulong fromBlock, ulong toBlock) => new LogIndexFilterVisitor(storage, filter, (int)fromBlock, (int)toBlock).Select(static i => (long)i); } diff --git a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs index 93ff7f3f7e6e..af874b947b63 100644 --- a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs @@ -53,7 +53,7 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro // EnumerateBlockNumbersFor returns IEnumerable (log-index contract kept as long for performance). // Block numbers from the index are non-negative so the cast is safe. - IEnumerable indexNumbers = _logIndexStorage.EnumerateBlockNumbersFor(filter, indexRange.from, indexRange.to) + IEnumerable indexNumbers = _logIndexStorage.EnumerateBlockNumbersFor(filter, (ulong)indexRange.from, (ulong)indexRange.to) .Select(static n => (ulong)n); foreach (FilterLog log in FilterLogsInBlocksParallel(filter, indexNumbers, cancellationToken)) { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs index a679c9e6682c..6627f2908759 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/TransactionModel.cs @@ -15,7 +15,7 @@ public class TransactionModel public UInt256 BlockNumber { get; set; } public Address From { get; set; } public Address To { get; set; } - public UInt256 Gas { get; set; } + public ulong Gas { get; set; } public UInt256 GasPrice { get; set; } public byte[] Input { get; set; } public UInt256 Value { get; set; } @@ -24,15 +24,13 @@ public Transaction ToTransaction() => new() { Hash = Hash, - // CAST NOTE: Nonce/Value/GasPrice/Gas are UInt256 for JSON proxy model compat. - // Actual transaction field values are constrained well within ulong range. Nonce = Nonce, SenderAddress = From, To = To, Data = Input, - Value = (ulong)Value, - GasLimit = (ulong)Gas, - GasPrice = (ulong)GasPrice + Value = Value, + GasLimit = Gas, + GasPrice = GasPrice }; } } diff --git a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs index c9ea3b7d3313..927960aaa8b3 100644 --- a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs +++ b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs @@ -47,27 +47,27 @@ public class HistoryPrunerTests private static IEnumerable PruningCases() { - const int blocks = 100; + const uint blocks = 100; yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 2, PruningInterval = 0 }, - /*syncPivot:*/ (long)blocks, + /*syncPivot:*/ blocks, /*primeWithOldestRead:*/ true, - /*expectedPruneBelow:*/ 36L, - /*finalCutoff:*/ 36L + /*expectedPruneBelow:*/ 36UL, + /*finalCutoff:*/ 36UL ).SetName("Can_prune_blocks_older_than_specified_epochs"); yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 2, PruningInterval = 0 }, - /*syncPivot:*/ (long)blocks, + /*syncPivot:*/ blocks, /*primeWithOldestRead:*/ false, // regression: pruner must self-bootstrap without external OldestBlockHeader call - /*expectedPruneBelow:*/ 36L, - /*finalCutoff:*/ 36L + /*expectedPruneBelow:*/ 36UL, + /*finalCutoff:*/ 36UL ).SetName("Can_prune_without_prior_oldest_block_read"); yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.UseAncientBarriers, RetentionEpochs = 100 /* no effect in UseAncientBarriers mode */, PruningInterval = 0 }, - /*syncPivot:*/ (long)blocks, + /*syncPivot:*/ blocks, /*primeWithOldestRead:*/ true, /*expectedPruneBelow:*/ BeaconGenesisBlockNumber, /*finalCutoff:*/ BeaconGenesisBlockNumber @@ -75,9 +75,9 @@ private static IEnumerable PruningCases() yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.UseAncientBarriers, PruningInterval = 0 }, - /*syncPivot:*/ 20L, // below BeaconGenesisBlockNumber — sync pivot caps the prune boundary + /*syncPivot:*/ 20UL, // below BeaconGenesisBlockNumber — sync pivot caps the prune boundary /*primeWithOldestRead:*/ true, - /*expectedPruneBelow:*/ 20L, + /*expectedPruneBelow:*/ 20UL, /*finalCutoff:*/ BeaconGenesisBlockNumber ).SetName("Prunes_up_to_sync_pivot"); @@ -85,10 +85,10 @@ private static IEnumerable PruningCases() // Retention window (5 × 32 = 160 blocks) exceeds chain length (100), so the cutoff is clamped to 0 and no pruning occurs. yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 5, PruningInterval = 0 }, - /*syncPivot:*/ (long)blocks, + /*syncPivot:*/ blocks, /*primeWithOldestRead:*/ false, - /*expectedPruneBelow:*/ 1L, - /*finalCutoff:*/ 0L + /*expectedPruneBelow:*/ 1UL, + /*finalCutoff:*/ 0UL ).SetName("Rolling_mode_with_retention_larger_than_chain_age_does_not_prune"); } @@ -97,34 +97,34 @@ private static IEnumerable BalPruningCases() // head=100, SlotsPerEpoch=32 → cutoff = 100 - retentionEpochs*32 (clamped at 0) yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 2, BalRetentionEpochs = 1, PruningInterval = 0 }, - /*expectedBlocksPointer:*/ 36L, - /*expectedBalsPointer:*/ 68L + /*expectedBlocksPointer:*/ 36UL, + /*expectedBalsPointer:*/ 68UL ).SetName("Bals_pruned_past_block_cutoff_when_bal_retention_is_shorter"); yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 2, BalRetentionEpochs = 2, PruningInterval = 0 }, - /*expectedBlocksPointer:*/ 36L, - /*expectedBalsPointer:*/ 36L + /*expectedBlocksPointer:*/ 36UL, + /*expectedBalsPointer:*/ 36UL ).SetName("Bals_pruned_alongside_blocks_when_retentions_equal"); yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.Rolling, RetentionEpochs = 1, BalRetentionEpochs = 2, PruningInterval = 0 }, - /*expectedBlocksPointer:*/ 68L, - /*expectedBalsPointer:*/ 68L + /*expectedBlocksPointer:*/ 68UL, + /*expectedBalsPointer:*/ 68UL ).SetName("Bals_forced_forward_when_block_retention_is_shorter"); yield return new TestCaseData( new HistoryConfig { Pruning = PruningModes.UseAncientBarriers, BalRetentionEpochs = 1, PruningInterval = 0 }, /*expectedBlocksPointer:*/ BeaconGenesisBlockNumber, - /*expectedBalsPointer:*/ 68L + /*expectedBalsPointer:*/ 68UL ).SetName("Bals_use_separate_rolling_cutoff_in_ancient_barriers_mode"); } [TestCaseSource(nameof(BalPruningCases))] public async Task Bal_pruning_uses_separate_cutoff( IHistoryConfig historyConfig, - long expectedBlocksPointer, - long expectedBalsPointer) + ulong expectedBlocksPointer, + ulong expectedBalsPointer) { const int blocks = 100; @@ -141,10 +141,10 @@ public async Task Bal_pruning_uses_separate_cutoff( } } - [TestCase(100L, 1u, 68L)] - [TestCase(100L, 4u, 0L)] // negative pre-clamp - [TestCase(100L, 0u, 100L)] - public async Task Bal_cutoff_block_number_uses_separate_retention(long head, uint balRetentionEpochs, long expectedCutoff) + [TestCase(100UL, 1u, 68UL)] + [TestCase(100UL, 4u, 0UL)] // negative pre-clamp + [TestCase(100UL, 0u, 100UL)] + public async Task Bal_cutoff_block_number_uses_separate_retention(ulong head, uint balRetentionEpochs, ulong expectedCutoff) { IHistoryConfig historyConfig = new HistoryConfig { @@ -163,10 +163,10 @@ public async Task Bal_cutoff_block_number_uses_separate_retention(long head, uin [TestCaseSource(nameof(PruningCases))] public async Task Prunes_history( IHistoryConfig historyConfig, - long syncPivot, + ulong syncPivot, bool primeWithOldestRead, - long expectedPruneBelow, - long finalCutoff) + ulong expectedPruneBelow, + ulong finalCutoff) { const int blocks = 100; @@ -181,12 +181,12 @@ public async Task Prunes_history( historyPruner.TryPruneHistory(CancellationToken.None); CheckGenesisPreserved(testBlockchain, blockHashes[0]); - for (int i = 1; i <= blocks; i++) + for (uint i = 1; i <= blocks; i++) { if (i < expectedPruneBelow) - CheckBlockPruned(testBlockchain, blockHashes, (ulong)i); + CheckBlockPruned(testBlockchain, blockHashes, i); else - CheckBlockPreserved(testBlockchain, blockHashes, (ulong)i); + CheckBlockPreserved(testBlockchain, blockHashes, i); } CheckHeadPreserved(testBlockchain, blocks); @@ -249,9 +249,9 @@ public async Task Does_not_prune_when_disabled() CheckGenesisPreserved(testBlockchain, blockHashes[0]); - for (int i = 1; i <= blocks; i++) + for (uint i = 1; i <= blocks; i++) { - CheckBlockPreserved(testBlockchain, blockHashes, (ulong)i); + CheckBlockPreserved(testBlockchain, blockHashes, i); } CheckHeadPreserved(testBlockchain, blocks); @@ -326,7 +326,7 @@ public async Task SchedulePruneHistory_passes_configured_timeout_to_scheduler(ui public async Task Delete_pointer_is_not_reset_on_restart() { const int blocks = 100; - const long storedPointer = 50; + const ulong storedPointer = 50; IHistoryConfig historyConfig = new HistoryConfig { @@ -389,7 +389,7 @@ private static void CheckBlockPruned(BasicTestBlockchain testBlockchain, List CreateBlockchainWithBlocks( IHistoryConfig historyConfig, int blocks, - long? syncPivot = null, + ulong? syncPivot = null, List blockHashes = null, IBackgroundTaskScheduler scheduler = null) { @@ -414,7 +414,7 @@ private static async Task CreateBlockchainWithBlocks( blockHashes?.Add(bc.BlockTree.Head!.Hash!); } if (syncPivot is { } pivot) - bc.BlockTree.SyncPivot = ((ulong)pivot, Hash256.Zero); + bc.BlockTree.SyncPivot = (pivot, Hash256.Zero); return bc; } diff --git a/src/Nethermind/Nethermind.History/HistoryConfig.cs b/src/Nethermind/Nethermind.History/HistoryConfig.cs index 0f38ce9ebf1e..84d3ce56be8e 100644 --- a/src/Nethermind/Nethermind.History/HistoryConfig.cs +++ b/src/Nethermind/Nethermind.History/HistoryConfig.cs @@ -8,6 +8,6 @@ public class HistoryConfig : IHistoryConfig public PruningModes Pruning { get; set; } = PruningModes.Disabled; public uint RetentionEpochs { get; set; } = 82125; public uint BalRetentionEpochs { get; set; } = 3533; - public uint PruningInterval { get; set; } = 8; + public ulong PruningInterval { get; set; } = 8; public uint PruningTimeoutSeconds { get; set; } = 2; } diff --git a/src/Nethermind/Nethermind.History/HistoryPruner.cs b/src/Nethermind/Nethermind.History/HistoryPruner.cs index ed3fcdc1956d..77f54c162de2 100644 --- a/src/Nethermind/Nethermind.History/HistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/HistoryPruner.cs @@ -89,8 +89,8 @@ public HistoryPruner( _backgroundTaskScheduler = backgroundTaskScheduler; _historyConfig = historyConfig; _enabled = historyConfig.Enabled(); - // PruningInterval is uint, SlotsPerEpoch is int; promote both to ulong before multiply. - _pruningInterval = (ulong)historyConfig.PruningInterval * (ulong)SlotsPerEpoch; + // SlotsPerEpoch is int; promote to ulong before multiply. + _pruningInterval = historyConfig.PruningInterval * (ulong)SlotsPerEpoch; _minHistoryRetentionEpochs = specProvider.GenesisSpec.MinHistoryRetentionEpochs; _minBalRetentionEpochs = specProvider.GenesisSpec.MinBalRetentionEpochs; _minDeletableBlockNumber = (_blockTree.Genesis?.Number ?? 0) + 1; // do not remove genesis @@ -179,7 +179,7 @@ public BlockHeader? OldestBlockHeader } ulong blocksToRetain = retentionEpochs * SlotsPerEpoch; - return ulong.Max(head.Value - blocksToRetain, 0); + return head.Value >= blocksToRetain ? head.Value - blocksToRetain : 0; } private void OnBlockProcessorQueueEmpty(object? sender, EventArgs e) diff --git a/src/Nethermind/Nethermind.History/IHistoryConfig.cs b/src/Nethermind/Nethermind.History/IHistoryConfig.cs index 4db528cf65b7..e6b3b86a2db2 100644 --- a/src/Nethermind/Nethermind.History/IHistoryConfig.cs +++ b/src/Nethermind/Nethermind.History/IHistoryConfig.cs @@ -30,7 +30,7 @@ public interface IHistoryConfig : IConfig [ConfigItem( Description = "Number of epochs to wait between each history pruning.", DefaultValue = "8")] - uint PruningInterval { get; set; } + ulong PruningInterval { get; set; } [ConfigItem( Description = "Maximum time in seconds allowed for a single history pruning pass. Set to 0 to disable the timeout.", diff --git a/src/Nethermind/Nethermind.Init/MemoryHintMan.cs b/src/Nethermind/Nethermind.Init/MemoryHintMan.cs index ef5e008eef84..13ee60a68ab9 100644 --- a/src/Nethermind/Nethermind.Init/MemoryHintMan.cs +++ b/src/Nethermind/Nethermind.Init/MemoryHintMan.cs @@ -34,7 +34,8 @@ public void SetMemoryAllowances( ITxPoolConfig txPoolConfig, uint cpuCount) { - TotalMemory = initConfig.MemoryHint ?? 1.GB; + ulong? memoryHint = initConfig.MemoryHint is { } h ? (ulong)h : null; + TotalMemory = memoryHint ?? 1UL.GB; ValidateCpuCount(cpuCount); checked @@ -43,7 +44,7 @@ public void SetMemoryAllowances( if (_logger.IsInfo) _logger.Info("Setting up memory allowances"); if (_logger.IsInfo) _logger.Info($" Memory hint: {TotalMemory / 1000 / 1000,5} MB"); - _remainingMemory = initConfig.MemoryHint ?? 1.GB; + _remainingMemory = memoryHint ?? 1UL.GB; _remainingMemory -= GeneralMemory; if (_logger.IsInfo) _logger.Info($" General memory: {GeneralMemory / 1000 / 1000,5} MB"); AssignPeersMemory(networkConfig); @@ -83,31 +84,31 @@ private void SetupMallocOpts(IInitConfig initConfig) // On 16C/32T machine, this reduces memory usage by about 7GB. // There aren't much difference between 16KB to 64KB, but the system cpu time increase slightly as threshold // lowers. 4k significantly increase cpu system time. - bool success = MallocHelper.Instance.MallOpt(MallocHelper.Option.M_MMAP_THRESHOLD, (int)64.KiB); + bool success = MallocHelper.Instance.MallOpt(MallocHelper.Option.M_MMAP_THRESHOLD, (int)64UL.KiB); if (!success && _logger.IsDebug) _logger.Debug("Unable to set M_MAP_THRESHOLD"); } - private long _remainingMemory; + private ulong _remainingMemory; - public long TotalMemory = 1024 * 1024 * 1024; - public long GeneralMemory { get; } = 32.MB; - public long FastBlocksMemory { get; private set; } - public long DbMemory { get; private set; } - public long NettyMemory { get; private set; } - public long TxPoolMemory { get; private set; } - public long PeersMemory { get; private set; } - public long TrieCacheMemory { get; private set; } + public ulong TotalMemory = 1024UL * 1024UL * 1024UL; + public ulong GeneralMemory { get; } = 32UL.MB; + public ulong FastBlocksMemory { get; private set; } + public ulong DbMemory { get; private set; } + public ulong NettyMemory { get; private set; } + public ulong TxPoolMemory { get; private set; } + public ulong PeersMemory { get; private set; } + public ulong TrieCacheMemory { get; private set; } private void AssignTrieCacheMemory(IDbConfig dbConfig) { - TrieCacheMemory = (long)(0.2 * _remainingMemory); - dbConfig.StateDbRowCacheSize = (ulong)TrieCacheMemory; + TrieCacheMemory = (ulong)(0.2 * _remainingMemory); + dbConfig.StateDbRowCacheSize = TrieCacheMemory; } private void AssignPeersMemory(INetworkConfig networkConfig) { - PeersMemory = networkConfig.MaxActivePeers.MB; - if (PeersMemory > _remainingMemory * 0.75) + PeersMemory = (ulong)networkConfig.MaxActivePeers.MB; + if (PeersMemory > (ulong)(_remainingMemory * 0.75)) { throw new InvalidDataException( $"Memory hint is not enough to satisfy the {nameof(NetworkConfig)}.{nameof(INetworkConfig.MaxActivePeers)}. " + @@ -117,17 +118,17 @@ private void AssignPeersMemory(INetworkConfig networkConfig) private void AssignTxPoolMemory(ITxPoolConfig txPoolConfig) { - long hashCacheMemory = txPoolConfig.Size / 1024L * 128L; + ulong hashCacheMemory = (ulong)txPoolConfig.Size / 1024UL * 128UL; if ((_remainingMemory * 0.05) < hashCacheMemory) { - hashCacheMemory = Math.Min((long)(_remainingMemory * 0.05), hashCacheMemory); + hashCacheMemory = Math.Min((ulong)(_remainingMemory * 0.05), hashCacheMemory); } - MemoryAllowance.TxHashCacheSize = (int)(hashCacheMemory / 128); - hashCacheMemory = MemoryAllowance.TxHashCacheSize * 128; + MemoryAllowance.TxHashCacheSize = (int)(hashCacheMemory / 128UL); + hashCacheMemory = (ulong)MemoryAllowance.TxHashCacheSize * 128UL; - long txPoolMemory = txPoolConfig.Size * 40.KB + hashCacheMemory; - if (txPoolMemory > _remainingMemory * 0.5) + ulong txPoolMemory = (ulong)txPoolConfig.Size * 40UL.KB + hashCacheMemory; + if (txPoolMemory > (ulong)(_remainingMemory * 0.5)) { throw new InvalidDataException( $"Memory hint is not enough to satisfy the {nameof(TxPoolConfig)}.{nameof(TxPoolConfig.Size)}"); @@ -142,14 +143,14 @@ private void AssignFastBlocksMemory(ISyncConfig syncConfig) { if (!syncConfig.DownloadBodiesInFastSync && !syncConfig.DownloadReceiptsInFastSync) { - FastBlocksMemory = Math.Min(128.MB, (long)(0.1 * _remainingMemory)); + FastBlocksMemory = Math.Min(128UL.MB, (ulong)(0.1 * _remainingMemory)); } else { - FastBlocksMemory = Math.Min(1.GB, (long)(0.1 * _remainingMemory)); + FastBlocksMemory = Math.Min(1UL.GB, (ulong)(0.1 * _remainingMemory)); } - syncConfig.FastHeadersMemoryBudget = (ulong)FastBlocksMemory; + syncConfig.FastHeadersMemoryBudget = FastBlocksMemory; } } @@ -164,7 +165,7 @@ private void UpdateDbConfig(IDbConfig dbConfig, IInitConfig initConfig) if (dbConfig.SkipMemoryHintSetting) return; DbMemory = _remainingMemory; - dbConfig.SharedBlockCacheSize = (ulong)DbMemory; + dbConfig.SharedBlockCacheSize = DbMemory; } private struct DbNeeds( @@ -187,7 +188,7 @@ private void AssignNettyMemory(INetworkConfig networkConfig, uint cpuCount) { ValidateCpuCount(cpuCount); - NettyMemory = Math.Min(256.MB, (long)(0.2 * _remainingMemory)); + NettyMemory = Math.Min(256UL.MB, (ulong)(0.2 * _remainingMemory)); uint arenaCount = (uint)Math.Min(cpuCount * 2, networkConfig.MaxNettyArenaCount); @@ -208,8 +209,8 @@ private void AssignNettyMemory(INetworkConfig networkConfig, uint cpuCount) for (int i = INetworkConfig.MaxNettyArenaOrder; i > 0; i--) { estimate = NettyMemoryEstimator.Estimate(arenaCount, i); - long maxAvailableFoNetty = NettyMemory; - if (estimate <= maxAvailableFoNetty) + ulong maxAvailableFoNetty = NettyMemory; + if ((ulong)estimate <= maxAvailableFoNetty) { targetNettyArenaOrder = i; break; @@ -219,7 +220,7 @@ private void AssignNettyMemory(INetworkConfig networkConfig, uint cpuCount) networkConfig.NettyArenaOrder = Math.Min(11, targetNettyArenaOrder); } - NettyMemory = estimate; + NettyMemory = (ulong)estimate; // Set PooledByteBufferAllocator.Default configuration. // Set it to a fixed 1 MB, 1 arena. Code should prefer NethermindBuffers.Default instead as it is easier to override. diff --git a/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs b/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs index 58ab22d641c3..5137d1f06378 100644 --- a/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs @@ -54,7 +54,7 @@ protected override void Load(ContainerBuilder builder) .AddDecorator((ctx, config) => { IPruningConfig pruningConfig = ctx.Resolve(); - config.MaxReorgDepth ??= pruningConfig.PruningBoundary; + config.MaxReorgDepth ??= (int)pruningConfig.PruningBoundary; return config; }); diff --git a/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs b/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs index d00faa04bd6a..fcd4d412c9df 100644 --- a/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs @@ -66,7 +66,7 @@ protected override void Load(ContainerBuilder builder) .AddSingleton() .AddSingleton((ctx) => new FlatStateRootIndex( ctx.Resolve(), - ctx.Resolve().SnapServingMaxDepth)) + (int)ctx.Resolve().SnapServingMaxDepth)) .AddSingleton() .AddSingleton() diff --git a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs index 46547da95861..2991643a272c 100644 --- a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs +++ b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs @@ -74,7 +74,7 @@ public class PruningTrieStateFactory( dbProvider, logManager, pruningConfig, - new LastNStateRootTracker(blockTree, syncConfig.SnapServingMaxDepth)); + new LastNStateRootTracker(blockTree, (int)syncConfig.SnapServingMaxDepth)); disposeStack.Push(mainWorldTrieStore); @@ -122,17 +122,16 @@ ILogManager logManager if (syncConfig.SnapServingEnabled == true && pruningConfig.PruningBoundary < syncConfig.SnapServingMaxDepth) { - // use PruningBoundary for log-index MaxReorgDepth before it's overwritten - logIndexConfig.MaxReorgDepth ??= pruningConfig.PruningBoundary; + logIndexConfig.MaxReorgDepth ??= (int)pruningConfig.PruningBoundary; if (_logger.IsInfo) _logger.Info($"Snap serving enabled, but {nameof(pruningConfig.PruningBoundary)} is less than {syncConfig.SnapServingMaxDepth}. Setting to {syncConfig.SnapServingMaxDepth}."); pruningConfig.PruningBoundary = syncConfig.SnapServingMaxDepth; } - if (pruningConfig.PruningBoundary < 64) + if (pruningConfig.PruningBoundary < 64UL) { if (_logger.IsWarn) _logger.Warn($"Pruning boundary must be at least 64. Setting to 64."); - pruningConfig.PruningBoundary = 64; + pruningConfig.PruningBoundary = 64UL; } IDb stateDb = dbProvider.StateDb; @@ -149,8 +148,8 @@ ILogManager logManager IPruningStrategy pruningStrategy = Prune .WhenCacheReaches(pruningConfig.DirtyCacheMb.MB) .WhenPersistedCacheReaches(pruningConfig.CacheMb.MB - pruningConfig.DirtyCacheMb.MB) - .WhenLastPersistedBlockIsTooOld(pruningConfig.MaxUnpersistedBlockCount, pruningConfig.PruningBoundary) - .UnlessLastPersistedBlockIsTooNew(pruningConfig.MinUnpersistedBlockCount, pruningConfig.PruningBoundary); + .WhenLastPersistedBlockIsTooOld((ulong)pruningConfig.MaxUnpersistedBlockCount, pruningConfig.PruningBoundary) + .UnlessLastPersistedBlockIsTooNew((ulong)pruningConfig.MinUnpersistedBlockCount, pruningConfig.PruningBoundary); if (!pruningConfig.Mode.IsMemory()) { @@ -167,9 +166,7 @@ ILogManager logManager if (pruningConfig.SimulateLongFinalizationDepth != 0) { - // Merge plugin also decorate this, but we want it to be the last decorator for this purpose, so its done - // manually here. - finalizedStateProvider = new DelayedFinalizedStateProvider(finalizedStateProvider, blockTree, pruningConfig.SimulateLongFinalizationDepth); + finalizedStateProvider = new DelayedFinalizedStateProvider(finalizedStateProvider, blockTree, (ulong)pruningConfig.SimulateLongFinalizationDepth); } PruningTrieStore = new TrieStore( @@ -185,8 +182,6 @@ private void AdviseConfig(IPruningConfig pruningConfig, IDbConfig dbConfig, IHar { if (hardwareInfo.AvailableMemoryBytes >= IHardwareInfo.StateDbLargerMemoryThreshold) { - // Default is 1280 MB, which translate to 280 MB of persisted cache memory (dirty node cache is 1000 MB). - // So this actually increase it from 280 MB to 1000 MB, reducing dirty node load at DB by 50%. if (pruningConfig.CacheMb < 2000) { if (_logger.IsDebug) _logger.Debug($"Increasing pruning cache to 2 GB due to available additional memory."); @@ -194,16 +189,10 @@ private void AdviseConfig(IPruningConfig pruningConfig, IDbConfig dbConfig, IHar } } - // On a 7950x (32 logical cores), assuming write buffer is large enough, the pruning time is about 3 second - // with 8GB of pruning cache. Lets assume that this is a safe estimate as the ssd can be a limitation also. long maximumDirtyCacheMb = Environment.ProcessorCount * 250; - // It must be at least 1GB as on mainnet at least 500MB will remain to support snap sync. So pruning cache only drop to about 500MB after pruning. maximumDirtyCacheMb = Math.Max(1000, maximumDirtyCacheMb); if (pruningConfig.DirtyCacheMb > maximumDirtyCacheMb) { - // The user can also change `--Db.StateDbWriteBufferSize`. - // Which may or may not be better as each read will need to go through each write buffer. - // So having less of them is probably better.. if (_logger.IsWarn) _logger.Warn($"Detected {pruningConfig.DirtyCacheMb}MB of dirty pruning cache config. Dirty cache more than {maximumDirtyCacheMb}MB is not recommended with {Environment.ProcessorCount} logical core as it may cause long memory pruning time which affect attestation."); } @@ -215,11 +204,10 @@ private void AdviseConfig(IPruningConfig pruningConfig, IDbConfig dbConfig, IHar public IPruningTrieStore PruningTrieStore { get; } - // Used to simulate long reorg by delaying `FinalizedBlockNumber` private class DelayedFinalizedStateProvider( IFinalizedStateProvider finalizedStateProvider, IBlockTree blockTree, - int pruningConfigSimulateLongFinalizationDepth + ulong pruningConfigSimulateLongFinalizationDepth ) : IFinalizedStateProvider { private ulong? _lastFinalizedBlockNumber = null; @@ -230,11 +218,10 @@ public ulong FinalizedBlockNumber { ulong baseFinalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; - // Need to limit by head, otherwise it does not work for forward sync. ulong headNumber = blockTree.Head?.Number ?? 0UL; - baseFinalizedBlockNumber = Math.Min(baseFinalizedBlockNumber, headNumber + (ulong)pruningConfigSimulateLongFinalizationDepth / 2); + baseFinalizedBlockNumber = Math.Min(baseFinalizedBlockNumber, headNumber + pruningConfigSimulateLongFinalizationDepth / 2); - if (_lastFinalizedBlockNumber is null || baseFinalizedBlockNumber - _lastFinalizedBlockNumber.Value > (ulong)pruningConfigSimulateLongFinalizationDepth) + if (_lastFinalizedBlockNumber is null || baseFinalizedBlockNumber - _lastFinalizedBlockNumber.Value > pruningConfigSimulateLongFinalizationDepth) { _lastFinalizedBlockNumber = baseFinalizedBlockNumber; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs index 78d54c1e19c9..b9c192898185 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs @@ -26,7 +26,7 @@ public partial class EthRpcModuleTests private static readonly ResourceAvailability Disabled = new(Disabled: true, OldestBlock: null); private static EthCapabilities GetCaps( - long? retentionWindow = null, + ulong? retentionWindow = null, ulong headNumber = 1000, long? oldestStateBlock = null, SyncConfig? syncConfig = null, @@ -72,7 +72,7 @@ public sealed record CapabilitiesScenario( ResourceAvailability ExpectedReceipts, ResourceAvailability ExpectedBlocks) { - public long? RetentionWindow { get; init; } + public ulong? RetentionWindow { get; init; } public ulong HeadNumber { get; init; } = 1000; public long? OldestStateBlock { get; init; } public ulong? LowestInsertedBody { get; init; } @@ -223,7 +223,7 @@ private static IEnumerable CapabilitiesScenarios() Name: "memory_pruning_window_dominates_old_floor", ExpectedState: memoryPruned, ExpectedStateproofs: memoryPruned, ExpectedReceipts: Available, ExpectedBlocks: Available) - { RetentionWindow = retention, HeadNumber = memoryHead, OldestStateBlock = 0, SyncConfig = fullSync }; + { RetentionWindow = (ulong)retention, HeadNumber = memoryHead, OldestStateBlock = 0, SyncConfig = fullSync }; // Floor dominates window — DeleteStrategy is suppressed so oldestBlock and head-retentionBlocks stay consistent. const long recentPivot = 950; @@ -232,7 +232,7 @@ private static IEnumerable CapabilitiesScenarios() Name: "memory_pruning_floor_dominates_window", ExpectedState: postSyncMemory, ExpectedStateproofs: postSyncMemory, ExpectedReceipts: Available, ExpectedBlocks: Available) - { RetentionWindow = retention, HeadNumber = memoryHead, OldestStateBlock = recentPivot, SyncConfig = fullSync }; + { RetentionWindow = (ulong)retention, HeadNumber = memoryHead, OldestStateBlock = recentPivot, SyncConfig = fullSync }; yield return new CapabilitiesScenario( Name: "fast_sync_no_receipts_disables_tx_logs_receipts", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs index ba9a0e1fa37b..ca858daf9661 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs @@ -67,11 +67,11 @@ private ResourceAvailability BuildState(BlockHeader head, bool fastSyncing) if (stateBoundary.RetentionWindowBlocks is not { } retention) return new ResourceAvailability(Disabled: false, OldestBlock: stateFloor, DeleteStrategy: null); - long windowOldest = head.Number >= (ulong)retention ? (long)(head.Number - (ulong)retention) : 0L; + long windowOldest = head.Number >= retention ? (long)(head.Number - retention) : 0L; long stateOldest = Math.Max(stateFloor, windowOldest); // Emit the window only when it's the binding constraint, and report the configured // retention so the value stays accurate before head reaches it. - DeleteStrategy? window = windowOldest >= stateFloor ? BuildWindow(retention) : null; + DeleteStrategy? window = windowOldest >= stateFloor ? BuildWindow((long)retention) : null; return new ResourceAvailability(Disabled: false, OldestBlock: stateOldest, DeleteStrategy: window); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index f623300051e9..e5ec3fcd7917 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -156,16 +156,18 @@ public override ResultWrapper>> Execut if (blockToSimulate.BlockOverrides.Time is not null) { - if (blockToSimulate.BlockOverrides.Time <= lastBlockTime) + ulong blockTime = (ulong)blockToSimulate.BlockOverrides.Time; + if (blockTime <= lastBlockTime) { return ResultWrapper>>.Fail($"Block timestamp out of order {blockToSimulate.BlockOverrides.Time} is <= than given base timestamp of {lastBlockTime}!", ErrorCodes.BlockTimestampNotIncreased); } - lastBlockTime = (ulong)blockToSimulate.BlockOverrides.Time; + lastBlockTime = blockTime; } else { - blockToSimulate.BlockOverrides.Time = lastBlockTime + _secondsPerSlot; - lastBlockTime = (ulong)blockToSimulate.BlockOverrides.Time; + ulong blockTime = lastBlockTime + _secondsPerSlot; + blockToSimulate.BlockOverrides.Time = blockTime; + lastBlockTime = blockTime; } lastBlockNumber = givenNumber; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs index 0ed137dc3df5..a324fc04e332 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/LogIndex/LogIndexRpcModule.cs @@ -24,7 +24,7 @@ public ResultWrapper> logIndex_blockNumbers(Filter filter) if (GetBlockNumber(logFilter.ToBlock) is not { } to) return ResultWrapper>.Fail($"Block {logFilter.ToBlock} is not found.", ErrorCodes.UnknownBlockError); - return ResultWrapper>.Success(storage.EnumerateBlockNumbersFor(logFilter, from, to)); + return ResultWrapper>.Success(storage.EnumerateBlockNumbersFor(logFilter, (ulong)from, (ulong)to)); } public ResultWrapper logIndex_status() => ResultWrapper.Success(new() diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs index ce15424a7741..202b352add64 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs @@ -199,7 +199,7 @@ public virtual async Task Should_process_block_as_expected_V6( } - [TestCase("0x0981253ff1b66ee40650f7fa7efe53f772bc11bd4fef3a3574cf91495a1533dd", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0x42a80ba6d5783c392ffcc6b3c15d7ef06be8ae71c2ff5f42377acdec67a5766c", false, false)] + [TestCase("0x6b27ccfc34cb820499507cdb9a995b99076530865f8fa3f566bef04616696717", "0xac3989a5349b5efc7f2f6847e76c4d6d4c5fcbf54939c80b05b57142ae1236fb", "0x037cf8a53c12d06101bdca6d35e8541f5160a481f79f7bfacc7e9db5efe29a48", false, false)] [TestCase(null, null, null, false, true)] [TestCase("0xc7ca0c8c9d0b29e9c432d34bcc6b0dd5adef6732ed94096465847ade2da72aae", "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "0xfad798172a2bbd423c90a023d345c7a7812e067918edb7630c2388736f197f29", true, false)] [TestCase("0xc7ca0c8c9d0b29e9c432d34bcc6b0dd5adef6732ed94096465847ade2da72aae", "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "0xfad798172a2bbd423c90a023d345c7a7812e067918edb7630c2388736f197f29", true, true)] @@ -306,10 +306,10 @@ protected static IEnumerable InvalidBalEarlyTestCases() { (string blockHash, BalErrorKind errorKind)[] perKindCases = [ - ("0x2753a5a3fe321381e637a7c0d7673b61555a366bdf75359616b0035f9b405fab", BalErrorKind.IncorrectChange), - ("0x9f19c60fe32bb002e4b959abddd1ebfd396ddae2e65e9ff87b1c4a0715ade9ad", BalErrorKind.MissingChange), - ("0x383a5a61b956150bc79762844dc40395c9f85e9caae8930a0de2b9e687902eae", BalErrorKind.SurplusChange), - ("0x66478724575325c99be695cc33d2698b6c87bdc7fe4ee0a54813de367f2bf037", BalErrorKind.SurplusReads), + ("0x156c33a4bbaaf1897ca35e10da9ad62eb3f17916de93faf8978de3f8e825c82c", BalErrorKind.IncorrectChange), + ("0xd8438b041f741b31cf32f22fa1b260873d6705fef298766d3a8b7a56dd2d1aea", BalErrorKind.MissingChange), + ("0xdb032fbc4d225916a9bd8707ead4bb0d1d440dc08c87d67fb4e8ae3a2ed52b15", BalErrorKind.SurplusChange), + ("0xbdf40c921b753e220ff3075e10f62c0abc1b9462a2dd842b103b6807e3060b9e", BalErrorKind.SurplusReads), ]; foreach ((string blockHash, BalErrorKind errorKind) in perKindCases) @@ -551,8 +551,8 @@ protected async Task NewPayloadV5_via_manual_block( using MergeTestBlockchain chain = await CreateBlockchain(Amsterdam.NoEip8037Instance); IEngineRpcModule rpc = chain.EngineRpcModule; - const long gasUsed = 167340; - const long gasUsedBeforeFinal = 92100; + const long gasUsed = 167352; + const long gasUsedBeforeFinal = 92112; const ulong gasPrice = 2; const long gasLimit = 100000; const ulong timestamp = 1000000; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs index d8b3c05819f0..465729fe7421 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs @@ -291,7 +291,7 @@ public void Feed_connect_invalid_chain() syncedBlockTree.FindHeader(99, BlockTreeLookupOptions.None)); ctx.Feed.InitializeFeed(); using HeadersSyncBatch batch = ctx.Feed.PrepareRequest().Result!; - batch.Response = syncedBlockTree.FindHeaders(syncedBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; + batch.Response = syncedBlockTree.FindHeaders(syncedBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; ctx.Feed.HandleResponse(batch); Hash256 lastHeader = syncedBlockTree.FindHeader(batch.EndNumber, BlockTreeLookupOptions.None)!.GetOrCalculateHash(); @@ -370,9 +370,9 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n // First batch, should be enough to merge chain HeadersSyncBatch? request = await ctx.Feed.PrepareRequest(); Assert.That(request!, Is.Not.Null); - request!.Response = ULongRange(request.StartNumber, request.RequestSize) + request!.Response = ULongRange(request.StartNumber, (int)request.RequestSize) .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) - .ToPooledList(request.RequestSize); + .ToPooledList((int)request.RequestSize); ctx.Feed.HandleResponse(request); @@ -386,9 +386,9 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n Assert.That(request, Is.Not.Null); // We respond it again - request!.Response = ULongRange(request.StartNumber, request.RequestSize) + request!.Response = ULongRange(request.StartNumber, (int)request.RequestSize) .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) - .ToPooledList(request.RequestSize); + .ToPooledList((int)request.RequestSize); ctx.Feed.HandleResponse(request); request.Dispose(); @@ -468,7 +468,7 @@ private static void BuildHeadersSyncBatchResponse(HeadersSyncBatch? batch, IBloc return; } - using IOwnedReadOnlyList headers = blockTree.FindHeaders(startHeader.Hash!, batch.RequestSize, 0, false); + using IOwnedReadOnlyList headers = blockTree.FindHeaders(startHeader.Hash!, (int)batch.RequestSize, 0, false); batch.Response = new ArrayPoolList(headers.Count, headers); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index 034a9bc41fc5..5f44962b43fd 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs @@ -86,7 +86,7 @@ public ulong PivotDestinationNumber { // However, the head may not be canon, so the destination need to be before that. ulong safeNumber = _blockTree.Head!.Number - Reorganization.MaxDepth + 1; - return (ulong)Math.Max(1, safeNumber); + return Math.Max(1, safeNumber); } return _blockTree.SyncPivot.BlockNumber + 1; diff --git a/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs index c798000e2dea..ebb52115acae 100644 --- a/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/GasLimitCalculatorTests.cs @@ -13,12 +13,12 @@ namespace Nethermind.Mining.Test [TestFixture] public class GasLimitCalculatorTests { - [TestCase(1000000UL, 2000000L, 1000975UL)] - [TestCase(1999999UL, 2000000L, 2000000UL)] - [TestCase(2000000UL, 2000000L, 2000000UL)] - [TestCase(2000001UL, 2000000L, 2000000UL)] - [TestCase(3000000UL, 2000000L, 2997072UL)] - public void Test(ulong current, long target, ulong expected) + [TestCase(1000000UL, 2000000UL, 1000975UL)] + [TestCase(1999999UL, 2000000UL, 2000000UL)] + [TestCase(2000000UL, 2000000UL, 2000000UL)] + [TestCase(2000001UL, 2000000UL, 2000000UL)] + [TestCase(3000000UL, 2000000UL, 2997072UL)] + public void Test(ulong current, ulong target, ulong expected) { BlocksConfig blocksConfig = new(); blocksConfig.TargetBlockGasLimit = target; diff --git a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs index 61789ac80536..1cbb4b47f6f4 100644 --- a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs @@ -61,11 +61,11 @@ public void Sync_hint_and_get() [Test] public async Task Many_threads() { - int range = 10000000; + ulong range = 10000000UL; HintBasedCache hintBasedCache = new(e => new NullDataSet(), LimboLogs.Instance); - void KeepHinting(Guid guid, int start) + void KeepHinting(Guid guid, ulong start) { - for (int i = start; i <= range; i++) + for (ulong i = start; i <= range; i++) { hintBasedCache.Hint(guid, i, i + 120000); } @@ -82,7 +82,7 @@ void KeepHinting(Guid guid, int start) await Task.WhenAll(a, b, c); Assert.That(hintBasedCache.CachedEpochsCount, Is.EqualTo(5)); - for (uint i = (uint)((ulong)range / Ethash.EpochLength); i < (uint)((ulong)(range + 120000) / Ethash.EpochLength); i++) + for (uint i = (uint)(range / Ethash.EpochLength); i < (uint)((range + 120000) / Ethash.EpochLength); i++) { Assert.That(hintBasedCache.Get(i), Is.Not.Null); } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs index 51c534b7a8a9..14ef4ef52981 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs @@ -217,7 +217,7 @@ private void Handle(StatusMessage status) SyncPeerProtocolInitializedEventArgs eventArgs = new(this) { - NetworkId = (ulong)status.NetworkId, + NetworkId = status.NetworkId, BestHash = status.BestHash, GenesisHash = status.GenesisHash, Protocol = status.Protocol, @@ -226,7 +226,7 @@ private void Handle(StatusMessage status) TotalDifficulty = status.TotalDifficulty }; - Session.IsNetworkIdMatched = SyncServer.NetworkId == (ulong)status.NetworkId; + Session.IsNetworkIdMatched = SyncServer.NetworkId == status.NetworkId; HeadHash = status.BestHash; TotalDifficulty = status.TotalDifficulty; NotifyProtocolInitialized(eventArgs); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs index a22ec1806946..84922991be6e 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/NewBlockHashesMessageSerializer.cs @@ -52,7 +52,7 @@ private static NewBlockHashesMessage Deserialize(ref Rlp.ValueDecoderContext ctx int length = c.ReadSequenceLength(); int checkPosition = c.Position + length; - (Hash256, ulong) result = (c.DecodeKeccak(), (ulong)c.DecodeUInt256()); + (Hash256, ulong) result = (c.DecodeKeccak(), c.DecodeULong()); c.Check(checkPosition); return result; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessage.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessage.cs index d2b6f55a14a8..f8f512eb1e70 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessage.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessage.cs @@ -10,7 +10,7 @@ namespace Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages public class StatusMessage : P2PMessage { public byte ProtocolVersion { get; set; } - public UInt256 NetworkId { get; set; } + public ulong NetworkId { get; set; } public UInt256 TotalDifficulty { get; set; } public Hash256? BestHash { get; set; } public Hash256? GenesisHash { get; set; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessageSerializer.cs index 6657793bb577..72aeac337d69 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Messages/StatusMessageSerializer.cs @@ -68,7 +68,7 @@ private static StatusMessage Deserialize(ref Rlp.ValueDecoderContext ctx) StatusMessage statusMessage = new(); ctx.ReadSequenceLength(); statusMessage.ProtocolVersion = ctx.DecodeByte(); - statusMessage.NetworkId = ctx.DecodeUInt256(); + statusMessage.NetworkId = ctx.DecodeULong(); statusMessage.TotalDifficulty = ctx.DecodeUInt256(); statusMessage.BestHash = ctx.DecodeKeccak(); statusMessage.GenesisHash = ctx.DecodeKeccak(); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandler.cs index 8169331d141a..6462e936d10c 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Eth69ProtocolHandler.cs @@ -100,7 +100,7 @@ private void Handle(StatusMessage69 status) SyncPeerProtocolInitializedEventArgs eventArgs = new(this) { - NetworkId = (ulong)status.NetworkId, + NetworkId = status.NetworkId, BestHash = status.LatestBlockHash, GenesisHash = status.GenesisHash, Protocol = status.Protocol, @@ -108,7 +108,7 @@ private void Handle(StatusMessage69 status) ForkId = status.ForkId }; - Session.IsNetworkIdMatched = SyncServer.NetworkId == (ulong)status.NetworkId; + Session.IsNetworkIdMatched = SyncServer.NetworkId == status.NetworkId; HeadNumber = status.LatestBlock; HeadHash = status.LatestBlockHash; NotifyProtocolInitialized(eventArgs); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs index e2e48a8685ae..9eac5e4a6e60 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs @@ -11,7 +11,7 @@ namespace Nethermind.Network.P2P.Subprotocols.Eth.V69.Messages; public class StatusMessage69 : P2PMessage { public byte ProtocolVersion { get; set; } - public UInt256 NetworkId { get; set; } + public ulong NetworkId { get; set; } public required Hash256 GenesisHash { get; set; } public ForkId ForkId { get; set; } public ulong EarliestBlock { get; set; } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs index edfe3cd88c5c..8a59179c63c7 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessageSerializer69.cs @@ -53,7 +53,7 @@ private static StatusMessage69 Deserialize(ref Rlp.ValueDecoderContext ctx) return new StatusMessage69 { ProtocolVersion = ctx.DecodeByte(), - NetworkId = ctx.DecodeUInt256(), + NetworkId = ctx.DecodeULong(), GenesisHash = ctx.DecodeKeccak() ?? Hash256.Zero, ForkId = DecodeForkId(ref ctx), EarliestBlock = ctx.DecodeULong(), diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs index 687f8b37f1fe..3ddbfae9d508 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs @@ -113,7 +113,7 @@ private ReceiptsResponse FulfillReceiptsRequest(GetReceiptsMessage70 getReceipts long requestedStartIndex = blockIndex == 0 ? getReceiptsMessage.FirstBlockReceiptIndex : 0; // ulong (not uint) so an adversarial negative long isn't truncated. - if ((ulong)requestedStartIndex > (ulong)(uint)receipts.Length) + if ((ulong)requestedStartIndex > (uint)receipts.Length) { throw new SubprotocolException($"Invalid firstBlockReceiptIndex {requestedStartIndex} for block receipts length {receipts.Length}"); } diff --git a/src/Nethermind/Nethermind.Optimism.Test/OptimismPayloadPreparationServiceTests.cs b/src/Nethermind/Nethermind.Optimism.Test/OptimismPayloadPreparationServiceTests.cs index 6f4b6eb48f2b..340813342e37 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/OptimismPayloadPreparationServiceTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/OptimismPayloadPreparationServiceTests.cs @@ -57,7 +57,7 @@ public async Task Writes_EIP1559Params_Into_HeaderExtraData((OptimismPayloadAttr IReleaseSpec releaseSpec = ReleaseSpecSubstitute.Create(); releaseSpec.IsOpHoloceneEnabled.Returns(true); releaseSpec.BaseFeeMaxChangeDenominator.Returns((UInt256)250); - releaseSpec.ElasticityMultiplier.Returns(6); + releaseSpec.ElasticityMultiplier.Returns(6UL); ISpecProvider? specProvider = Substitute.For(); specProvider.GetSpec(parent).Returns(releaseSpec); diff --git a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs index 6f19684bdd40..646ca40a48a9 100644 --- a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs @@ -334,15 +334,15 @@ public void Chiado_archive_uses_regular_chiado_genesis_hash() [TestCase("*")] public void Arena_order_is_default(string configWildcard) => Test(configWildcard, static c => c.NettyArenaOrder, -1); - [TestCase("chiado", 17_000_000L, 5UL, 3000)] - [TestCase("gnosis", 17_000_000L, 5UL, 3000)] - [TestCase("mainnet", 60_000_000L)] - [TestCase("sepolia", 60_000_000L)] - [TestCase("hoodi", 60_000_000L)] + [TestCase("chiado", 17_000_000UL, 5UL, 3000)] + [TestCase("gnosis", 17_000_000UL, 5UL, 3000)] + [TestCase("mainnet", 60_000_000UL)] + [TestCase("sepolia", 60_000_000UL)] + [TestCase("hoodi", 60_000_000UL)] [TestCase("^chiado ^gnosis ^mainnet ^sepolia ^hoodi")] - public void Blocks_defaults_are_correct(string configWildcard, long? targetBlockGasLimit = null, ulong secondsPerSlot = 12, int blockProductionTimeout = 4000) + public void Blocks_defaults_are_correct(string configWildcard, ulong? targetBlockGasLimit = null, ulong secondsPerSlot = 12, int blockProductionTimeout = 4000) { - Test(configWildcard, static c => c.TargetBlockGasLimit, targetBlockGasLimit); + Test(configWildcard, static c => c.TargetBlockGasLimit, targetBlockGasLimit); Test(configWildcard, static c => c.SecondsPerSlot, secondsPerSlot); Test(configWildcard, static c => c.BlockProductionTimeoutMs, blockProductionTimeout); diff --git a/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs b/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs index 262538109297..8501a5196276 100755 --- a/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs @@ -90,8 +90,8 @@ public void Db_size_are_computed_correctly( SyncConfig syncConfig = new(); syncConfig.FastSync = fastSync; - Assert.That(_memoryHintMan.DbMemory, Is.GreaterThan((long)((memoryHint - 100.MB) * 0.5))); - Assert.That(_memoryHintMan.DbMemory, Is.LessThan((long)((memoryHint - 100.MB) * 0.9))); + Assert.That(_memoryHintMan.DbMemory, Is.GreaterThan((ulong)((memoryHint - 100.MB) * 0.5))); + Assert.That(_memoryHintMan.DbMemory, Is.LessThan((ulong)((memoryHint - 100.MB) * 0.9))); } [TestCase(100 * GB, 16u, -1)] diff --git a/src/Nethermind/Nethermind.Runner.Test/Module/FlatRocksDbConfigAdjusterTests.cs b/src/Nethermind/Nethermind.Runner.Test/Module/FlatRocksDbConfigAdjusterTests.cs index 3f8cf25c670c..974f164ee8e0 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Module/FlatRocksDbConfigAdjusterTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Module/FlatRocksDbConfigAdjusterTests.cs @@ -39,7 +39,7 @@ public void SetUp() public void NonFlatDatabase_ReturnsBaseConfig() { _flatDbConfig.Layout.Returns(FlatLayout.Flat); - _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000L); + _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000UL); FlatRocksDbConfigAdjuster adjuster = new(_baseFactory, _flatDbConfig, _disposeStack, LimboLogs.Instance); @@ -52,7 +52,7 @@ public void NonFlatDatabase_ReturnsBaseConfig() public void FlatDatabase_WithFlatLayout_DoesNotAddPartitionedIndexOptions() { _flatDbConfig.Layout.Returns(FlatLayout.Flat); - _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000L); + _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000UL); FlatRocksDbConfigAdjuster adjuster = new(_baseFactory, _flatDbConfig, _disposeStack, LimboLogs.Instance); @@ -67,7 +67,7 @@ public void FlatDatabase_WithFlatLayout_DoesNotAddPartitionedIndexOptions() public void FlatDatabase_WithFlatInTrieLayout_AddsPartitionedIndexOptions() { _flatDbConfig.Layout.Returns(FlatLayout.FlatInTrie); - _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000L); + _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000UL); FlatRocksDbConfigAdjuster adjuster = new(_baseFactory, _flatDbConfig, _disposeStack, LimboLogs.Instance); @@ -82,7 +82,7 @@ public void FlatDatabase_WithFlatInTrieLayout_AddsPartitionedIndexOptions() public void FlatDatabase_DelegatesToBaseFactoryWithCorrectParameters() { _flatDbConfig.Layout.Returns(FlatLayout.Flat); - _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000L); + _flatDbConfig.BlockCacheSizeBudget.Returns(1_000_000_000UL); FlatRocksDbConfigAdjuster adjuster = new(_baseFactory, _flatDbConfig, _disposeStack, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs b/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs index 9960bf611873..1c091ecaf006 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs @@ -41,3 +41,36 @@ public override void Write( } } } + +public class NullableRawULongConverter : JsonConverter +{ + private readonly ULongConverter _converter = new(); + + public override ulong? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return null; + } + + return _converter.Read(ref reader, typeToConvert, options); + } + + public override void Write( + Utf8JsonWriter writer, + ulong? value, + JsonSerializerOptions options) + { + if (!value.HasValue) + { + writer.WriteNullValue(); + } + else + { + writer.WriteNumberValue(value.GetValueOrDefault()); + } + } +} diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index dd75251bb3e0..51684d573168 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -69,7 +69,7 @@ public sealed class HeaderDecoder() : RlpDecoder, IHeaderDecoder } else { - blockHeader.AuRaStep = (long)decoderContext.DecodeUInt256(); + blockHeader.AuRaStep = (ulong)decoderContext.DecodeUInt256(); blockHeader.AuRaSignature = decoderContext.DecodeByteArray(); } diff --git a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs index d422afa7eb74..c51ca1bf62a4 100644 --- a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs @@ -249,7 +249,7 @@ private static void VerifyCancunSpecificsForMainnetAndSepolia(IReleaseSpec spec) { using (Assert.EnterMultipleScope()) { - Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)3338477)); + Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo(3338477UL)); Assert.That(spec.GasCosts.MaxBlobGasPerBlock, Is.EqualTo(786432)); Assert.That(Eip4844Constants.MinBlobGasPrice, Is.EqualTo(1.Wei)); Assert.That(spec.GasCosts.TargetBlobGasPerBlock, Is.EqualTo(393216)); @@ -260,7 +260,7 @@ private static void VerifyPragueSpecificsForMainnetHoodiAndSepolia(ulong chainId { using (Assert.EnterMultipleScope()) { - Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)5007716)); + Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo(5007716UL)); Assert.That(spec.MaxBlobCount, Is.EqualTo(9)); Assert.That(spec.TargetBlobCount, Is.EqualTo(6)); Assert.That(spec.Eip2935ContractAddress, Is.EqualTo(Eip2935Constants.BlockHashHistoryAddress)); @@ -294,10 +294,10 @@ private static void VerifyOsakaSpecificsForMainnetHoleskyHoodiAndSepolia(ulong c VerifyPragueSpecificsForMainnetHoodiAndSepolia(chainId, postOsakaSpec); using (Assert.EnterMultipleScope()) { - Assert.That(postBPO1Spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)8346193)); + Assert.That(postBPO1Spec.BlobBaseFeeUpdateFraction, Is.EqualTo(8346193UL)); Assert.That(postBPO1Spec.MaxBlobCount, Is.EqualTo(15)); Assert.That(postBPO1Spec.TargetBlobCount, Is.EqualTo(10)); - Assert.That(postBPO2Spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)11684671)); + Assert.That(postBPO2Spec.BlobBaseFeeUpdateFraction, Is.EqualTo(11684671UL)); Assert.That(postBPO2Spec.MaxBlobCount, Is.EqualTo(21)); Assert.That(postBPO2Spec.TargetBlobCount, Is.EqualTo(14)); } @@ -522,7 +522,7 @@ private static void VerifyGnosisCancunSpecifics(IReleaseSpec spec) { using (Assert.EnterMultipleScope()) { - Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)1112826)); + Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo(1112826UL)); Assert.That(spec.GasCosts.MaxBlobGasPerBlock, Is.EqualTo(262144)); Assert.That(Eip4844Constants.MinBlobGasPrice, Is.EqualTo(1.GWei)); Assert.That(spec.GasCosts.TargetBlobGasPerBlock, Is.EqualTo(131072)); @@ -1161,7 +1161,7 @@ public void Geth_genesis_blob_schedule_uses_latest_fork_settings_when_multiple_f { Assert.That(provider.GenesisSpec.TargetBlobCount, Is.EqualTo(expectedTargetBlobs)); Assert.That(provider.GenesisSpec.MaxBlobCount, Is.EqualTo(expectedMaxBlobs)); - Assert.That(provider.GenesisSpec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)expectedBlobBaseFeeUpdateFraction)); + Assert.That(provider.GenesisSpec.BlobBaseFeeUpdateFraction, Is.EqualTo(expectedBlobBaseFeeUpdateFraction)); } } diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index 74c2672d7a03..7622a25f3957 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -88,7 +88,7 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public ulong TargetBlobCount { get; set; } = spec.TargetBlobCount; public ulong MaxBlobCount { get; set; } = spec.MaxBlobCount; public ulong MaxBlobsPerTx { get; set; } = spec.MaxBlobsPerTx; - public UInt256 BlobBaseFeeUpdateFraction { get; set; } = spec.BlobBaseFeeUpdateFraction; + public ulong BlobBaseFeeUpdateFraction { get; set; } = spec.BlobBaseFeeUpdateFraction; public bool IsEip1153Enabled { get; set; } = spec.IsEip1153Enabled; public bool IsEip3651Enabled { get; set; } = spec.IsEip3651Enabled; public bool IsEip3855Enabled { get; set; } = spec.IsEip3855Enabled; @@ -113,7 +113,7 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public bool IsEip7825Enabled { get; set; } = spec.IsEip7825Enabled; public UInt256 ForkBaseFee { get; set; } = spec.ForkBaseFee; public UInt256 BaseFeeMaxChangeDenominator { get; set; } = spec.BaseFeeMaxChangeDenominator; - public long ElasticityMultiplier { get; set; } = spec.ElasticityMultiplier; + public ulong ElasticityMultiplier { get; set; } = spec.ElasticityMultiplier; public IBaseFeeCalculator BaseFeeCalculator { get; set; } = spec.BaseFeeCalculator; public bool IsEip8024Enabled { get; set; } = spec.IsEip8024Enabled; public bool IsEip6110Enabled { get; set; } = spec.IsEip6110Enabled; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs index cd61ee71558f..5c09f88f924b 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs @@ -62,7 +62,7 @@ public class ChainParameters public UInt256? Eip1559BaseFeeMaxChangeDenominator { get; set; } - public long? Eip1559ElasticityMultiplier { get; set; } + public ulong? Eip1559ElasticityMultiplier { get; set; } /// /// Transaction permission managing contract address. @@ -165,7 +165,7 @@ public class ChainParameters /// Gets or sets the BLOB_GASPRICE_UPDATE_FRACTION parameter defined in /// EIP-4844. /// - public UInt256? Eip4844BlobGasPriceUpdateFraction { get; set; } + public ulong? Eip4844BlobGasPriceUpdateFraction { get; set; } /// /// Gets or sets the MIN_BLOB_GASPRICE parameter, in wei, defined in diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs index 5f81e523ed12..82655f410b7d 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs @@ -338,7 +338,7 @@ private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec Hash256 mixHash = chainSpecJson.Genesis.Seal?.Ethereum?.MixHash ?? Keccak.Zero; byte[] auRaSignature = chainSpecJson.Genesis.Seal?.AuthorityRound?.Signature; - long? step = chainSpecJson.Genesis.Seal?.AuthorityRound?.Step; + ulong? step = chainSpecJson.Genesis.Seal?.AuthorityRound?.Step; Hash256 parentHash = chainSpecJson.Genesis.ParentHash ?? Keccak.Zero; ulong timestamp = chainSpecJson.Genesis.Timestamp; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecAuRaSealJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecAuRaSealJson.cs index f63b86612a3b..2628e6275e41 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecAuRaSealJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecAuRaSealJson.cs @@ -5,7 +5,7 @@ namespace Nethermind.Specs.ChainSpecStyle.Json { public class ChainSpecAuRaSealJson { - public long Step { get; set; } + public ulong Step { get; set; } public byte[] Signature { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs index 4fc3ef8a19ba..6a82be19ce55 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs @@ -114,7 +114,7 @@ public class ChainSpecParamsJson : IHasNamedForks public UInt256? Eip1559BaseFeeMaxChangeDenominator { get; set; } - public long? Eip1559ElasticityMultiplier { get; set; } + public ulong? Eip1559ElasticityMultiplier { get; set; } public Address TransactionPermissionContract { get; set; } @@ -160,7 +160,7 @@ public class ChainSpecParamsJson : IHasNamedForks public ulong? Eip2935TransitionTimestamp { get; set; } public Address Eip2935ContractAddress { get; set; } public ulong? Eip2935RingBufferSize { get; set; } - public UInt256? Eip4844BlobGasPriceUpdateFraction { get; set; } + public ulong? Eip4844BlobGasPriceUpdateFraction { get; set; } public UInt256? Eip4844MinBlobGasPrice { get; set; } public ulong? Eip4844FeeCollectorTransitionTimestamp { get; set; } public ulong? Eip6110TransitionTimestamp { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs index 314a3c2d9ffc..147dc6caf487 100644 --- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs @@ -73,7 +73,7 @@ public class ReleaseSpec : IReleaseSpec public UInt256? Eip1559BaseFeeMinValue { get; set; } public UInt256 ForkBaseFee { get; set; } = Eip1559Constants.DefaultForkBaseFee; public UInt256 BaseFeeMaxChangeDenominator { get; set; } = Eip1559Constants.DefaultBaseFeeMaxChangeDenominator; - public long ElasticityMultiplier { get; set; } = Eip1559Constants.DefaultElasticityMultiplier; + public ulong ElasticityMultiplier { get; set; } = Eip1559Constants.DefaultElasticityMultiplier; public IBaseFeeCalculator BaseFeeCalculator { get; set; } = new DefaultBaseFeeCalculator(); public bool IsEip1153Enabled { get; set; } public bool IsEip3651Enabled { get; set; } @@ -106,7 +106,7 @@ public class ReleaseSpec : IReleaseSpec public ulong TargetBlobCount { get; set; } public ulong MaxBlobCount { get; set; } public ulong MaxBlobsPerTx => IsEip7594Enabled ? Math.Min(Eip7594Constants.MaxBlobsPerTx, MaxBlobCount) : MaxBlobCount; - public UInt256 BlobBaseFeeUpdateFraction { get; set; } + public ulong BlobBaseFeeUpdateFraction { get; set; } [MemberNotNullWhen(true, nameof(IsEip7251Enabled))] public Address? Eip7251ContractAddress { get => IsEip7251Enabled ? field : null; set; } [MemberNotNullWhen(true, nameof(Eip7002ContractAddress))] diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index 4ecb7f5e2fa5..ca049c7568d7 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -11,7 +11,7 @@ namespace Nethermind.State.Flat; public sealed class CompactionSchedule : ICompactionSchedule { - private readonly int _compactSize; + private readonly ulong _compactSize; private readonly ulong _offset; public CompactionSchedule( @@ -19,18 +19,18 @@ public CompactionSchedule( IFlatDbConfig config, ILogManager logManager) { - if (config.CompactSize > 1 && (config.CompactSize & (config.CompactSize - 1)) != 0) + // Validate using the raw int value before storing. + int cs = config.CompactSize; + if (cs > 1 && (cs & (cs - 1)) != 0) throw new ArgumentException("Compact size must be a power of 2"); - _compactSize = config.CompactSize; + // Safe: validated above — cs is 1 or a small positive power-of-2. + _compactSize = (ulong)cs; ILogger logger = logManager.GetClassLogger(); _offset = ResolveOffset(metadataDb, config, logger); } - // Changed from long → ulong to match the backing field type. - // Callers that previously compared this to a long block-number should - // now compare against a ulong block-number (BlockHeader.Number is ulong). public ulong Offset => _offset; public int GetCompactSize(ulong blockNumber) @@ -38,42 +38,29 @@ public int GetCompactSize(ulong blockNumber) if (_compactSize <= 1 || blockNumber == 0) return 1; ulong shifted = blockNumber + _offset; - // C# has no unary minus for ulong, so we use the two's-complement - // identity x & -x ≡ x & (~x + 1) to isolate the lowest set bit. - // No overflow risk: if shifted == 0 the guard above already returned. + // Isolate the lowest set bit via two's-complement identity: x & (~x + 1). + // No overflow risk: shifted == 0 is excluded by the guard above. ulong lowestBit = shifted & (~shifted + 1UL); - // Cast to int is safe: _compactSize is a power-of-2 int, so - // Math.Min can never return a value larger than int.MaxValue. - return (int)Math.Min(lowestBit, (ulong)_compactSize); + // _compactSize is a small power-of-2 (≤ int.MaxValue by construction), + // so Math.Min never returns a value that overflows int. + return (int)Math.Min(lowestBit, _compactSize); } - // Changed return type from long → ulong. - // The sentinel "no compaction needed" value is now ulong.MaxValue instead - // of long.MaxValue; callers should be updated accordingly. public ulong NextFullCompactionAfter(ulong from) { if (_compactSize <= 1) return ulong.MaxValue; - if (from == ulong.MaxValue) - { - long fromSigned = -1; - long offsetSigned = (long)_offset; - long sizeSigned = (long)_compactSize; - long modSigned = (fromSigned + offsetSigned) % sizeSigned; - long distanceSigned = modSigned == 0 ? sizeSigned : sizeSigned - modSigned; - return (ulong)(fromSigned + distanceSigned); - } + // Sentinel: caller has no meaningful "from" block; no next compaction + // can be computed, so propagate the sentinel rather than wrapping into + // broken signed arithmetic. + if (from == ulong.MaxValue) return ulong.MaxValue; - ulong size = (ulong)_compactSize; // _compactSize is a small power-of-2, always fits - ulong mod = (from + _offset) % size; // all operands are ulong — no ambiguity - ulong distance = mod == 0 ? size : size - mod; + ulong mod = (from + _offset) % _compactSize; + ulong distance = mod == 0 ? _compactSize : _compactSize - mod; return from + distance; } - // Changed return type from long → ulong so that _offset can be assigned - // without a cast. The on-disk RLP format is still encoded as long for - // backward-compatibility with existing databases. private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) { if (_compactSize <= 1) return 0; @@ -93,8 +80,8 @@ private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger return generated; } - // The persisted value was written as a long (see GenerateAndPersist). - // Decode it as long first so we can detect corruption (negative values). + // Boundary cast — on-disk RLP format uses long for backward-compatibility. + // Decode as long first so we can detect DB corruption (negative values). long decoded = stored.AsRlpValueContext().DecodeLong(); if (decoded < 0) { @@ -103,20 +90,20 @@ private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger } if (logger.IsInfo) logger.Info($"Loaded FlatDb compaction offset {decoded}"); - // Safe cast: we verified decoded >= 0 immediately above. + // Boundary cast — safe: negativity excluded by the guard immediately above. return (ulong)decoded; } private ulong GenerateAndPersist(IDb metadataDb) { - // Generate in the range [0, int.MaxValue) so the value fits in a - // non-negative long AND the resulting ulong is well within range. + // Generate in [0, int.MaxValue) so the value encodes cleanly as a + // non-negative long in the on-disk RLP format. long offset = Random.Shared.NextInt64(0, int.MaxValue); // Keep the on-disk encoding as long (RLP) for database compatibility. metadataDb.Set(MetadataDbKeys.FlatDbCompactionOffset, Rlp.Encode(offset).Bytes); - // Safe cast: NextInt64(0, int.MaxValue) is always in [0, 2^31 − 1]. + // Boundary cast — safe: NextInt64(0, int.MaxValue) is always in [0, 2³¹ − 1]. return (ulong)offset; } } diff --git a/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs b/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs index d301425d1d14..a411cdd11412 100644 --- a/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/FlatDbManager.cs @@ -162,7 +162,7 @@ private void PersistIfNeeded(in StateId latestSnapshot) _snapshotRepository.RemoveStatesUntil(currentPersistedStateId); ClearReadOnlyBundleCache(); - ReorgBoundaryReached?.Invoke(this, new ReorgBoundaryReached((ulong)currentPersistedStateId.BlockNumber)); // Safe: PreGenesis (-1) is filtered above + ReorgBoundaryReached?.Invoke(this, new ReorgBoundaryReached(currentPersistedStateId.BlockNumber)); } private async Task RunTrieCachePopulator(CancellationToken cancellationToken) diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs index 920de308f9d4..b3da18c8d093 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs @@ -48,7 +48,7 @@ public class FlatWorldStateManager( logManager); public IReadOnlyKeyValueStore? HashServer => null; - public long? RetentionWindowBlocks => null; + public ulong? RetentionWindowBlocks => null; public long? OldestStateBlock { diff --git a/src/Nethermind/Nethermind.State.Flat/TrieNodeCache.cs b/src/Nethermind/Nethermind.State.Flat/TrieNodeCache.cs index 196de994b8f8..70e2c3a097ed 100644 --- a/src/Nethermind/Nethermind.State.Flat/TrieNodeCache.cs +++ b/src/Nethermind/Nethermind.State.Flat/TrieNodeCache.cs @@ -37,7 +37,7 @@ public TrieNodeCache(IFlatDbConfig flatDbConfig, ILogManager logManager) { _logger = logManager.GetClassLogger(); - long maxCacheMemoryThreshold = flatDbConfig.TrieCacheMemoryBudget; + long maxCacheMemoryThreshold = (long)flatDbConfig.TrieCacheMemoryBudget; long totalNodeCount = (maxCacheMemoryThreshold / EstimatedSizePerNode); int targetBucketSize = (int)((totalNodeCount / UtilRatio) / ShardCount); diff --git a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs index 41d0f3bfff1b..478f6354f7fb 100644 --- a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs @@ -82,10 +82,10 @@ public void ShouldAnnounceReorgOnDispose() IConfigProvider configProvider = new ConfigProvider(); // Asserts the pruning trie store's BestPersistedState reorg announcement; a patricia-only concept. configProvider.GetConfig().Enabled = false; - int reorgDepth = configProvider.GetConfig().SnapServingMaxDepth; + ulong reorgDepth = configProvider.GetConfig().SnapServingMaxDepth; IFinalizedStateProvider manualFinalizedStateProvider = Substitute.For(); - manualFinalizedStateProvider.FinalizedBlockNumber.Returns((ulong)(lastBlock - reorgDepth)); - manualFinalizedStateProvider.GetFinalizedStateRootAt((ulong)(lastBlock - reorgDepth)) + manualFinalizedStateProvider.FinalizedBlockNumber.Returns((ulong)lastBlock - reorgDepth); + manualFinalizedStateProvider.GetFinalizedStateRootAt((ulong)lastBlock - reorgDepth) .Returns(new Hash256("0xec6063a04d48f4b2258f36efaef76a23ba61875f5303fcf8ede2f5d160def35d")); { @@ -126,7 +126,7 @@ public void ShouldAnnounceReorgOnDispose() } } - blockTree.Received().BestPersistedState = (ulong?)(lastBlock - reorgDepth); + blockTree.Received().BestPersistedState = (ulong)lastBlock - reorgDepth; } [Test] diff --git a/src/Nethermind/Nethermind.State/IStateBoundary.cs b/src/Nethermind/Nethermind.State/IStateBoundary.cs index 42abed6ba035..d218ebce5957 100644 --- a/src/Nethermind/Nethermind.State/IStateBoundary.cs +++ b/src/Nethermind/Nethermind.State/IStateBoundary.cs @@ -22,7 +22,7 @@ public interface IStateBoundary /// there is no rolling window (archive, full pruning, flat storage); the absolute floor /// is reported via instead. /// - long? RetentionWindowBlocks { get; } + ulong? RetentionWindowBlocks { get; } } /// diff --git a/src/Nethermind/Nethermind.State/WorldStateManager.cs b/src/Nethermind/Nethermind.State/WorldStateManager.cs index c9a0549431bb..08b7370fc830 100644 --- a/src/Nethermind/Nethermind.State/WorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/WorldStateManager.cs @@ -49,10 +49,10 @@ public WorldStateManager( ? NoopSnapServer.Instance : new SnapServer.SnapServer(_readOnlyTrieStore, _readaOnlyCodeCb, _logManager, _lastNStateRootTracker); - RetentionWindowBlocks = pruningConfig.Mode.IsMemory() ? pruningConfig.PruningBoundary : null; + RetentionWindowBlocks = pruningConfig.Mode.IsMemory() ? pruningConfig.PruningBoundary : (ulong?)null; } - public long? RetentionWindowBlocks { get; } + public ulong? RetentionWindowBlocks { get; } public long? OldestStateBlock { diff --git a/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs b/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs index c200b01e994a..1c620e6a6596 100644 --- a/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs +++ b/src/Nethermind/Nethermind.Stateless.Executor/IO/SszForkActivation.cs @@ -17,7 +17,7 @@ public partial struct SszForkActivation public static SszForkActivation From(ForkActivation forkActivation) => new() { - BlockNumber = [(ulong)forkActivation.BlockNumber], + BlockNumber = [forkActivation.BlockNumber], Timestamp = [forkActivation.Timestamp ?? 0ul] }; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs index 9ee3096d1b3e..a0645a5365f1 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs @@ -30,6 +30,11 @@ namespace Nethermind.Synchronization.Test; public partial class BlockDownloaderTests { + // BCL Math.Min/Math.Max have no ulong overloads; use these helpers to avoid + // boundary casts and the unsafe negative-then-cast-to-ulong pattern. + private static ulong ULongMin(ulong a, ulong b) => a < b ? a : b; + private static ulong ULongMax(ulong a, ulong b) => a > b ? a : b; + [TestCase(16UL, 32UL, false, 32, 32UL)] [TestCase(16UL, 32UL, false, 32, 29UL)] [TestCase(16UL, 32UL, true, 0, 32UL)] @@ -39,14 +44,14 @@ public partial class BlockDownloaderTests public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool enableFastSync, int fastSyncLag, ulong insertedBeaconBlocks) { bool withReceipts = enableFastSync; - int notSyncedTreeStartingBlockNumber = 3; + ulong notSyncedTreeStartingBlockNumber = 3; InMemoryReceiptStorage? receiptStorage = withReceipts ? new InMemoryReceiptStorage() : null; BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() - .WithBlockTrees(notSyncedTreeStartingBlockNumber + 1, (int)headNumber + 1, receiptStorage: receiptStorage) + .WithBlockTrees((int)notSyncedTreeStartingBlockNumber + 1, (int)headNumber + 1, receiptStorage: receiptStorage) .InsertBeaconPivot(beaconPivot) - .InsertBeaconHeaders((ulong)(notSyncedTreeStartingBlockNumber + 1), beaconPivot - 1) + .InsertBeaconHeaders(notSyncedTreeStartingBlockNumber + 1, beaconPivot - 1) .InsertBeaconBlocks(beaconPivot + 1, insertedBeaconBlocks, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); BlockTree syncedTree = blockTrees.SyncedTree; @@ -54,7 +59,7 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena new SyncConfig() { FastSync = enableFastSync, - StateMinDistanceFromHead = fastSyncLag + StateMinDistanceFromHead = (ulong)fastSyncLag }, new MergeConfig() { @@ -62,6 +67,7 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena }); PostMergeContext ctx = container.Resolve(); + // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(beaconPivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(beaconPivot, BlockTreeLookupOptions.None); @@ -77,14 +83,16 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena if (enableFastSync) { await ctx.FastSyncUntilNoRequest(peerInfo); - long expectedDownloadStart = notSyncedTreeStartingBlockNumber; - long expectedDownloadEnd = Math.Min((long)headNumber, (long)insertedBeaconBlocks - fastSyncLag); + ulong expectedDownloadStart = notSyncedTreeStartingBlockNumber; + // fastSyncLag is a non-negative int test parameter; cast to ulong is safe. + // ULongMin avoids the old pattern of (long) subtraction → negative → cast-to-ulong wrap-around. + ulong expectedDownloadEnd = ULongMin(headNumber, insertedBeaconBlocks - (ulong)fastSyncLag); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max((ulong)notSyncedTreeStartingBlockNumber, (ulong)expectedDownloadEnd))); - Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(Math.Max((ulong)notSyncedTreeStartingBlockNumber, (ulong)expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(ULongMax(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(ULongMax(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); - int receiptCount = 0; - for (long i = expectedDownloadStart; i < expectedDownloadEnd; i++) + ulong receiptCount = 0; + for (ulong i = expectedDownloadStart; i < expectedDownloadEnd; i++) { if (i % 3 == 0) { @@ -92,8 +100,8 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena } } - Assert.That(ctx.ReceiptStorage.Count, Is.EqualTo(withReceipts ? receiptCount : 0)); - Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(Math.Max(insertedBeaconBlocks - (ulong)fastSyncLag, beaconPivot))); + Assert.That(ctx.ReceiptStorage.Count, Is.EqualTo(withReceipts ? (int)receiptCount : 0)); + Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(ULongMax(insertedBeaconBlocks - (ulong)fastSyncLag, beaconPivot))); } await ctx.FullSyncUntilNoRequest(peerInfo); @@ -120,7 +128,8 @@ public async Task Can_reach_terminal_block(long headNumber, int options, int thr PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); + // BOUNDARY CAST: FindHeader overload takes `long`; safe while block numbers < long.MaxValue + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16L, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -155,7 +164,8 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(ulong headNumber, int ttdBlock, PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); + // BOUNDARY CAST: FindHeader overload takes `long`; safe while block numbers < long.MaxValue + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16L, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -178,10 +188,11 @@ public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int bloc await using IContainer container = CreateMergeNode(blockTrees, new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = blocksToIgnore + StateMinDistanceFromHead = (ulong)blocksToIgnore }); PostMergeContext ctx = container.Resolve(); + // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None); @@ -262,7 +273,7 @@ public async Task BlockDownloader_works_correctly_with_withdrawals() }, new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = fastSyncLag, + StateMinDistanceFromHead = (ulong)fastSyncLag, }); PostMergeContext ctx = container.Resolve(); @@ -292,7 +303,8 @@ public async Task BlockDownloader_works_correctly_with_withdrawals() PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); await ctx.FastSyncUntilNoRequest(peerInfo); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0, Math.Min(headNumber, headNumber - fastSyncLag)))); + // fastSyncLag is non-negative; subtraction is safe as headNumber > fastSyncLag in this test + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)Math.Max(0, Math.Min(headNumber, headNumber - fastSyncLag)))); syncPeerInternal.ExtendTree(chainLength * 2); await ctx.FullSyncUntilNoRequest(peerInfo); @@ -318,6 +330,7 @@ public void BlockDownloader_does_not_stop_processing_when_main_chain_is_unknown( }); PostMergeContext ctx = container.Resolve(); + // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index 707eed9a1671..3cc51ecc66cc 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -80,7 +80,7 @@ public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSync await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = enableFastSync, - StateMinDistanceFromHead = fastSynclag + StateMinDistanceFromHead = (ulong)fastSynclag })); Context ctx = node.Resolve(); bool withReceipts = enableFastSync; @@ -140,7 +140,7 @@ public async Task Invoke_UpdateMainChain_Once() await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = fastSyncLag, + StateMinDistanceFromHead = (ulong)fastSyncLag, })); Context ctx = node.Resolve(); @@ -175,7 +175,7 @@ public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion( await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = fastSyncLag, + StateMinDistanceFromHead = (ulong)fastSyncLag, }), configurer: (builder) => builder.AddSingleton(mockForwardHeaderProvider)); @@ -587,7 +587,7 @@ public async Task Can_DownloadBlockOutOfOrder(bool isMerge) ISyncConfig syncConfig = new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = (int)fastSyncLag, + StateMinDistanceFromHead = fastSyncLag, PivotNumber = syncPivot.Number, PivotHash = syncPivot.Hash!.ToString(), }; @@ -840,7 +840,7 @@ private IContainer CreateFastSyncNode(int fastSyncLag = 1) => CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = fastSyncLag, + StateMinDistanceFromHead = (ulong)fastSyncLag, })); private IContainer CreateNode(Action? configurer = null, IConfigProvider? configProvider = null) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs index 1ff63a11e435..2e15d0e64bc7 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs @@ -155,7 +155,7 @@ public async Task Can_handle_forks_with_persisted_headers() HeadersSyncBatch? batch = await feed.PrepareRequest(); if (batch is null) break; batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash!, batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash!, (int)batch.RequestSize, 0, false)!; feed.HandleResponse(batch); } @@ -196,7 +196,7 @@ public async Task When_next_header_hash_update_is_delayed_do_not_drop_peer() void FulfillBatch(HeadersSyncBatch batch) { batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; batch.ResponseSourcePeer = peerInfo; } @@ -251,7 +251,7 @@ public async Task Can_prepare_several_request_and_ignore_request_from_previous_s void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; using HeadersSyncBatch? r = await feed.PrepareRequest(); @@ -298,7 +298,7 @@ public async Task Will_dispatch_when_only_partially_processed_dependency() void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; // First batch need to be handled first before handle dependencies can do anything @@ -369,7 +369,7 @@ public async Task Can_reset_and_not_hang_when_a_batch_is_processing() void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; using HeadersSyncBatch batch1 = (await feed.PrepareRequest())!; @@ -578,9 +578,9 @@ public async Task Can_insert_all_good_headers_from_dependent_batch_with_missing_ void FillBatch(HeadersSyncBatch batch, ulong start, bool applyNulls) { int c = count; - List list = new(batch.RequestSize); + List list = new((int)batch.RequestSize); ulong current = start; - for (int j = 0; j < batch.RequestSize; j++, current++) + for (int j = 0; j < (int)batch.RequestSize; j++, current++) { list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); } @@ -639,9 +639,9 @@ public async Task Does_not_download_persisted_header() void FillBatch(HeadersSyncBatch batch) { - List list = new(batch.RequestSize); + List list = new((int)batch.RequestSize); ulong current = batch.StartNumber; - for (int j = 0; j < batch.RequestSize; j++, current++) + for (int j = 0; j < (int)batch.RequestSize; j++, current++) { list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs index e80e8928a41e..34981e8cb6f9 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTestsBase.cs @@ -266,7 +266,7 @@ public SyncPeerMock( _maxRandomizedLatencyMs = maxRandomizedLatencyMs ?? 0; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider testFinalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider testFinalizedStateProvider = new(pruningConfig.PruningBoundary); TrieStore trieStore = new(new NodeStorage(stateDb), Nethermind.Trie.Pruning.No.Pruning, Persist.EveryBlock, testFinalizedStateProvider, pruningConfig, LimboLogs.Instance); _stateDb = trieStore.TrieNodeRlpStore; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs index 547776eb666c..c3bd0870c904 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs @@ -638,7 +638,7 @@ public ScenarioBuilder WhenThisNodeIsLoadingBlocksFromDb() public ScenarioBuilder WhenStateAndBestHeaderCanBeBeDifferent(int maxBlockDiff) { - _overwrites.Add(() => SyncConfig.HeaderStateDistance = maxBlockDiff); + _overwrites.Add(() => SyncConfig.HeaderStateDistance = (ulong)maxBlockDiff); return this; } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs index a55aaa85ade0..c98346b78799 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs @@ -35,7 +35,7 @@ int syncPivot { PivotNumber = (ulong)syncPivot, FastSync = true, - StateMinDistanceFromHead = minDistance, + StateMinDistanceFromHead = (ulong)minDistance, StateMaxDistanceFromHead = maxDistance, }, LimboLogs.Instance); blockTree.SyncPivot = ((ulong)syncPivot, Keccak.Zero); diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs index 789a38f74c56..cf97a3a89b6f 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs @@ -16,7 +16,7 @@ public class FastSyncFeed(IForwardSyncController forwardSyncController, ISyncCon private DownloaderOptions BuildOptions() => DownloaderOptions.Insert | DownloaderOptions.WithReceipts; - public override Task PrepareRequest(CancellationToken token = default) => forwardSyncController.PrepareRequest(BuildOptions(), syncConfig.StateMinDistanceFromHead, token); + public override Task PrepareRequest(CancellationToken token = default) => forwardSyncController.PrepareRequest(BuildOptions(), (int)syncConfig.StateMinDistanceFromHead, token); public override SyncResponseHandlingResult HandleResponse(BlocksRequest response, PeerInfo peer = null) => forwardSyncController.HandleResponse(response, peer); diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs index b75beaff73fb..fa4fa37abd9f 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs @@ -230,7 +230,8 @@ private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, r private async Task> RequestHeaders(PeerInfo peer, CancellationToken cancellation, ulong currentNumber, int headersToRequest) { - sealValidator.HintValidationRange(_sealValidatorUserGuid, (long)currentNumber - 1028, (long)currentNumber + 30000); + ulong start = currentNumber >= 1028 ? currentNumber - 1028 : 0UL; + sealValidator.HintValidationRange(_sealValidatorUserGuid, start, currentNumber + 30000); IOwnedReadOnlyList headers = await peer.SyncPeer.GetBlockHeaders(currentNumber, headersToRequest, 0, cancellation); cancellation.ThrowIfCancellationRequested(); diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs index 26d2f73f257a..2703af99973d 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BlockAccessListsSyncFeed.cs @@ -29,7 +29,7 @@ public class BlockAccessListsSyncFeed : BarrierSyncFeed _syncPointers.LowestInsertedBlockAccessListBlockNumber; protected override int BarrierWhenStartedMetadataDbKey => MetadataDbKeys.BlockAccessListsBarrierWhenStarted; - protected override ulong SyncConfigBarrierCalc => (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc; + protected override ulong SyncConfigBarrierCalc => _syncConfig.AncientBlockAccessListsBarrierCalc; protected override Func HasPivot => () => { @@ -89,16 +89,16 @@ public BlockAccessListsSyncFeed( public override void InitializeFeed() { - if (_pivotNumber != _blockTree.SyncPivot.BlockNumber || _barrier != (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc) + if (_pivotNumber != _blockTree.SyncPivot.BlockNumber || _barrier != _syncConfig.AncientBlockAccessListsBarrierCalc) { _pivotNumber = _blockTree.SyncPivot.BlockNumber; - _barrier = (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc; + _barrier = _syncConfig.AncientBlockAccessListsBarrierCalc; if (_logger.IsInfo) _logger.Info($"Changed pivot in block access lists sync. Now using pivot {_pivotNumber} and barrier {_barrier}"); ResetSyncStatusList(); InitializeMetadataDb(); } base.InitializeFeed(); - _syncReport.FastBlockAccessLists.Reset(0, _pivotNumber - (ulong)_syncConfig.AncientBlockAccessListsBarrierCalc); + _syncReport.FastBlockAccessLists.Reset(0, _pivotNumber - _syncConfig.AncientBlockAccessListsBarrierCalc); } private void ResetSyncStatusList() => @@ -106,7 +106,7 @@ private void ResetSyncStatusList() => _blockTree, _pivotNumber, _syncPointers.LowestInsertedBlockAccessListBlockNumber, - (ulong)_syncConfig.AncientBlockAccessListsBarrier); + _syncConfig.AncientBlockAccessListsBarrier); protected override SyncMode ActivationSyncModes { get; } = SyncMode.FastBlockAccessLists & ~SyncMode.FastBlocks; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 4eb86aae4597..4afe09a665b6 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -30,7 +30,7 @@ public class BodiesSyncFeed : BarrierSyncFeed private ulong ComputeBarrier(ulong pivotNumber) { - ulong clamped = Math.Max(1UL, Math.Min(pivotNumber, (ulong)_syncConfig.AncientBodiesBarrier)); + ulong clamped = Math.Max(1UL, Math.Min(pivotNumber, _syncConfig.AncientBodiesBarrier)); ulong? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; return cutoffBlockNumber is null ? clamped : ulong.Max(clamped, cutoffBlockNumber.Value); } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs index 117ddfa95cdd..a5ef7e9cdca0 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs @@ -9,8 +9,8 @@ namespace Nethermind.Synchronization.FastBlocks public class HeadersSyncBatch : FastBlocksBatch { public ulong StartNumber { get; set; } - public ulong EndNumber => StartNumber + (ulong)RequestSize - 1; - public int RequestSize { get; set; } + public ulong EndNumber => StartNumber + RequestSize - 1; + public ulong RequestSize { get; set; } public long ResponseSizeEstimate { get; private set; } private IOwnedReadOnlyList? _response; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs index 137e3e76aece..9f3232f87d59 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs @@ -26,7 +26,7 @@ async Task ISyncDownloader.Dispatch( try { - batch.Response = await peer.GetBlockHeaders(batch.StartNumber, batch.RequestSize, 0, cancellationToken); + batch.Response = await peer.GetBlockHeaders(batch.StartNumber, (int)batch.RequestSize, 0, cancellationToken); } catch (TimeoutException) { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs index df9e73936c49..eeab94cc0ec7 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs @@ -238,7 +238,7 @@ protected virtual void ResetPivot() private UInt256 TryGetPivotTotalDifficulty(Hash256 headerHash) { - if (_pivotNumber == (ulong)_syncConfig.PivotNumber) + if (_pivotNumber == _syncConfig.PivotNumber) return _syncConfig.PivotTotalDifficultyParsed; // Pivot is the same as in config // Got from header @@ -426,7 +426,7 @@ private bool HasDependencyToProcess HeadersSyncBatch batch = new(); ulong requestSizeU = (ulong)requestSize; batch.StartNumber = Math.Max(HeadersDestinationNumber, _lowestRequestedHeaderNumber >= requestSizeU ? _lowestRequestedHeaderNumber - requestSizeU : 0UL); - batch.RequestSize = (int)Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, (ulong)requestSize); + batch.RequestSize = Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, requestSizeU); _lowestRequestedHeaderNumber = batch.StartNumber; return batch; } @@ -526,7 +526,7 @@ private static HeadersSyncBatch BuildRightFiller(HeadersSyncBatch batch, int rig rightFiller.StartNumber = batch.EndNumber >= (ulong)(rightFillerSize - 1) ? batch.EndNumber - (ulong)(rightFillerSize - 1) : 0UL; - rightFiller.RequestSize = rightFillerSize; + rightFiller.RequestSize = (ulong)rightFillerSize; return rightFiller; } @@ -534,7 +534,7 @@ private static HeadersSyncBatch BuildLeftFiller(HeadersSyncBatch batch, int left { HeadersSyncBatch leftFiller = new(); leftFiller.StartNumber = batch.StartNumber; - leftFiller.RequestSize = leftFillerSize; + leftFiller.RequestSize = (ulong)leftFillerSize; return leftFiller; } @@ -542,10 +542,10 @@ private static HeadersSyncBatch BuildDependentBatch(HeadersSyncBatch batch, ulon { HeadersSyncBatch dependentBatch = new(); dependentBatch.StartNumber = addedEarliest; - int count = (int)(addedLast - addedEarliest + 1); + ulong count = addedLast - addedEarliest + 1; ReadOnlySpan response = batch.Response!.AsSpan(); dependentBatch.RequestSize = count; - dependentBatch.Response = response.Slice((int)(addedEarliest - batch.StartNumber), count).ToPooledList(); + dependentBatch.Response = response.Slice((int)(addedEarliest - batch.StartNumber), (int)count).ToPooledList(); dependentBatch.ResponseSourcePeer = batch.ResponseSourcePeer; return dependentBatch; } @@ -574,22 +574,22 @@ private void EnqueueBatch(HeadersSyncBatch batch, bool skipPersisted = false) if (seedHash is null) return batch; using IOwnedReadOnlyList headers = - _headerStore.FindReversedHeaders(batch.EndNumber, seedHash, batch.RequestSize); + _headerStore.FindReversedHeaders(batch.EndNumber, seedHash, (int)batch.RequestSize); if (headers.Count == 0) return batch; - int newRequestSize = batch.RequestSize - headers.Count; + ulong newRequestSize = batch.RequestSize - (ulong)headers.Count; ReadOnlySpan headersSpan = headers.AsSpan(); using HeadersSyncBatch newBatchToProcess = new(); // headersSpan[0].Number and StartNumber are both ulong — no cast needed. newBatchToProcess.StartNumber = headersSpan[0].Number; - newBatchToProcess.RequestSize = headersSpan.Length; + newBatchToProcess.RequestSize = (ulong)headersSpan.Length; newBatchToProcess.Response = headers; if (_logger.IsDebug) _logger.Debug($"Handling header portion {newBatchToProcess.StartNumber} to {newBatchToProcess.EndNumber} with persisted headers."); InsertHeaders(newBatchToProcess); MarkDirty(); HeadersSyncProgressLoggerReport.CurrentQueued = HeadersInQueue; - HeadersSyncProgressLoggerReport.IncrementSkipped(newBatchToProcess.RequestSize); + HeadersSyncProgressLoggerReport.IncrementSkipped((int)newBatchToProcess.RequestSize); if (newRequestSize == 0) return null; @@ -605,7 +605,7 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) } ReadOnlySpan response = batch.Response.AsSpan(); - if (response.Length > batch.RequestSize) + if ((ulong)response.Length > batch.RequestSize) { if (_logger.IsDebug) _logger.Debug($"Peer sent too long response ({response.Length}) to {batch}"); @@ -707,10 +707,10 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) else { added = 0; - leftFillerSize = batch.RequestSize; + leftFillerSize = (int)batch.RequestSize; rightFillerSize = 0; } - if (added + leftFillerSize + rightFillerSize != batch.RequestSize) + if ((ulong)(added + leftFillerSize + rightFillerSize) != batch.RequestSize) { throw new Exception($"Added {added} + left {leftFillerSize} + right {rightFillerSize} != request size {batch.RequestSize} in {batch}"); } @@ -724,7 +724,7 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) added = Math.Max(0, added); - if (added < batch.RequestSize) + if ((ulong)added < batch.RequestSize) { if (added <= 0) { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs index 96ecad8f430c..a77226b85880 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs @@ -36,7 +36,7 @@ public class ReceiptsSyncFeed : BarrierSyncFeed private ulong ComputeBarrier(ulong pivotNumber) { - ulong requested = Math.Max((ulong)_syncConfig.AncientBodiesBarrier, (ulong)_syncConfig.AncientReceiptsBarrier); + ulong requested = Math.Max(_syncConfig.AncientBodiesBarrier, _syncConfig.AncientReceiptsBarrier); ulong clamped = Math.Max(1UL, Math.Min(pivotNumber, requested)); ulong? cutoffBlockNumber = _historyPruner.CutoffBlockNumber; return cutoffBlockNumber is null ? clamped : ulong.Max(clamped, cutoffBlockNumber.Value); diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs index a35eda6d68cd..f2099998ed9e 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs @@ -21,9 +21,9 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa public BlockHeader? GetPivotHeader() { - // BestSuggestedHeader.Number is ulong; StateMinDistanceFromHead/StateMaxDistanceFromHead are long. + // BestSuggestedHeader.Number is ulong; StateMinDistanceFromHead is ulong. // Cast to long for arithmetic; safe for realistic chain heights. - if (_bestHeader is null || ((long)(blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) - (long)_bestHeader.Number >= syncConfig.StateMaxDistanceFromHead) + if (_bestHeader is null || (long)((blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) - (long)_bestHeader.Number >= syncConfig.StateMaxDistanceFromHead) { TrySetNewBestHeader($"distance from HEAD:{Diff}"); } @@ -33,7 +33,7 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa public void UpdateHeaderForcefully() { - if (_bestHeader is null || ((long)(blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) > (long)_bestHeader.Number) + if (_bestHeader is null || (long)((blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) > (long)_bestHeader.Number) { TrySetNewBestHeader("too many empty responses"); } diff --git a/src/Nethermind/Nethermind.Synchronization/Sync.cs b/src/Nethermind/Nethermind.Synchronization/Sync.cs index cb66dbc63b39..d6be8cd6d8ba 100644 --- a/src/Nethermind/Nethermind.Synchronization/Sync.cs +++ b/src/Nethermind/Nethermind.Synchronization/Sync.cs @@ -5,6 +5,6 @@ namespace Nethermind.Synchronization { public static class Sync { - public static long MaxReorgLength = 512; + public static ulong MaxReorgLength = 512; } } diff --git a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs index 4cedc2dd3e7b..c7c0f1e6b831 100644 --- a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs @@ -174,9 +174,9 @@ public void AddNewBlock(Block block, ISyncPeer nodeWhoSentTheBlock) bool isBlockBeforeTheSyncPivot = block.Number < _pivotNumber; ulong headNumber = _blockTree.Head?.Number ?? 0UL; - // Guard against underflow: MaxReorgLength is long but subtraction is on ulong. - bool isBlockOlderThanMaxReorgAllows = headNumber > (ulong)Sync.MaxReorgLength && - block.Number < headNumber - (ulong)Sync.MaxReorgLength; + // Guard against underflow + bool isBlockOlderThanMaxReorgAllows = headNumber > Sync.MaxReorgLength && + block.Number < headNumber - Sync.MaxReorgLength; // We skip blocks that are old if (isBlockBeforeTheSyncPivot || isBlockOlderThanMaxReorgAllows) @@ -255,8 +255,8 @@ private bool ValidateSeal(Block block, ISyncPeer syncPeer) // It is important that we only do that here, after we ensured that the block is // in the range of [Head - MaxReorganizationLength, Head]. // Otherwise we could hint incorrect ranges and cause expensive cache recalculations. - // HintValidationRange takes long; cast is safe for realistic block heights. - _sealValidator.HintValidationRange(_sealValidatorUserGuid, (long)block.Number - 128, (long)block.Number + 1024); + ulong start = block.Number >= 128 ? block.Number - 128 : 0UL; + _sealValidator.HintValidationRange(_sealValidatorUserGuid, start, block.Number + 1024); return _sealValidator.ValidateSeal(block.Header, true); } diff --git a/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs b/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs index 7ac122419a94..a61b5adfaeff 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs @@ -60,8 +60,8 @@ public void DataGasCost_With_Variable_Calldata_Should_Include_PerByte() byte[] calldata = [0xAA, 0xBB, 0xCC, 0xDD]; byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)100, calldata); - long expected = L1PrecompileConstants.L1StaticCallPerCallOverhead - + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * 4; // 10000 + 64 + ulong expected = L1PrecompileConstants.L1StaticCallPerCallOverhead + + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * 4UL; // 10000 + 64 Assert.That(_precompile.DataGasCost(input, _spec), Is.EqualTo(expected)); } @@ -205,9 +205,9 @@ public void DataGasCost_Then_Run_EndToEnd() byte[] input = CreateValidInput(Address.FromNumber(99), (UInt256)500, calldata); // DataGasCost returns only static overhead - long gasCost = _precompile.DataGasCost(input, _spec); - long expectedStaticGas = L1PrecompileConstants.L1StaticCallPerCallOverhead - + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * 4; // 10000 + 64 + ulong gasCost = _precompile.DataGasCost(input, _spec); + ulong expectedStaticGas = L1PrecompileConstants.L1StaticCallPerCallOverhead + + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * 4UL; // 10000 + 64 Assert.That(gasCost, Is.EqualTo(expectedStaticGas)); // Run returns result + actual L1 gas consumed diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/L1PrecompileConstants.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/L1PrecompileConstants.cs index b82bc5ff4278..b778b52de234 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/L1PrecompileConstants.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/L1PrecompileConstants.cs @@ -31,21 +31,21 @@ public static class L1PrecompileConstants public const int L1SloadStorageKeyBytes = 32; public const int L1SloadExpectedInputLength = Address.Size + L1SloadStorageKeyBytes + BlockNumberBytes; - public const long L1SloadFixedGasCost = 2000L; - public const long L1SloadPerLoadGasCost = 2000L; + public const ulong L1SloadFixedGasCost = 2000UL; + public const ulong L1SloadPerLoadGasCost = 2000UL; // --- L1STATICCALL constants (Surge precompile spec) --- public const int L1StaticCallMinInputLength = Address.Size + BlockNumberBytes; - public const long L1StaticCallFixedGasCost = 2000L; + public const ulong L1StaticCallFixedGasCost = 2000UL; /// /// Per-call overhead covering L1 RPC round-trip and call execution. /// - public const long L1StaticCallPerCallOverhead = 10000L; + public const ulong L1StaticCallPerCallOverhead = 10000UL; /// /// Per-byte calldata cost matching EVM CALLDATACOPY (16 gas/byte, EIP-2028). /// - public const long L1StaticCallPerByteCalldataCost = 16L; + public const ulong L1StaticCallPerByteCalldataCost = 16UL; /// /// Maximum return data size (24 KB, matches MAX_CODE_SIZE per EIP-170). /// diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs index 670018563897..802ed60a3579 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs @@ -39,10 +39,10 @@ private L1SloadPrecompile() public static IL1StorageProvider? L1StorageProvider { get; set; } public static ILogger Logger { get; set; } - public long BaseGasCost(IReleaseSpec releaseSpec) => L1PrecompileConstants.L1SloadFixedGasCost; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => L1PrecompileConstants.L1SloadFixedGasCost; - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => - inputData.Length != L1PrecompileConstants.L1SloadExpectedInputLength ? 0L : L1PrecompileConstants.L1SloadPerLoadGasCost; + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + inputData.Length != L1PrecompileConstants.L1SloadExpectedInputLength ? 0UL : L1PrecompileConstants.L1SloadPerLoadGasCost; /// /// Non-context-aware fallback. Used by callers outside the Taiko VM (caching layer, tooling) diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs index 91a45c0d5f74..1445374bec4a 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs @@ -49,20 +49,20 @@ private L1StaticCallPrecompile() public static ILogger Logger { get; set; } public static long GasCap => L1PrecompileConstants.L1CallMaxGasCap; - public long BaseGasCost(IReleaseSpec releaseSpec) => L1PrecompileConstants.L1StaticCallFixedGasCost; + public ulong BaseGasCost(IReleaseSpec releaseSpec) => L1PrecompileConstants.L1StaticCallFixedGasCost; /// /// Returns the static overhead cost: per-call overhead + per-byte calldata cost. /// The dynamic L1 gas cost is handled by . /// - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { if (inputData.Length < L1PrecompileConstants.L1StaticCallMinInputLength) - return 0L; + return 0UL; int calldataLength = inputData.Length - L1PrecompileConstants.L1StaticCallMinInputLength; return L1PrecompileConstants.L1StaticCallPerCallOverhead - + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * calldataLength; + + L1PrecompileConstants.L1StaticCallPerByteCalldataCost * (ulong)calldataLength; } /// diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs index adcdb28a5085..83e8e7a6860c 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs @@ -51,7 +51,7 @@ private TrieStore CreateTrieStore( TrackPastKeys = false // Default disable }; - finalizedStateProvider ??= new TestFinalizedStateProvider((ulong)pruningConfig.PruningBoundary); + finalizedStateProvider ??= new TestFinalizedStateProvider(pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(kvStore, scheme, requirePath: scheme == INodeStorage.KeyScheme.HalfPath), pruningStrategy, @@ -343,13 +343,13 @@ public void Dispatcher_will_always_try_to_clear_memory() { TrieStore fullTrieStore = CreateTrieStore(pruningStrategy: new MemoryLimit(512)); TreePath emptyPath = TreePath.Empty; - for (int i = 0; i < 1024; i++) + for (ulong i = 0; i < 1024; i++) { TrieNode fakeRoot = new(NodeType.Leaf, []); // 192B fakeRoot.ResolveKey(NullTrieNodeResolver.Instance, ref emptyPath); - using (ICommitter committer = fullTrieStore.BeginStateBlockCommit((ulong)i, fakeRoot)) + using (ICommitter committer = fullTrieStore.BeginStateBlockCommit(i, fakeRoot)) { - for (int j = 0; j < 1 + i % 3; j++) + for (ulong j = 0; j < 1 + i % 3; j++) { TrieNode trieNode = new(NodeType.Leaf, []); // 192B trieNode.ResolveKey(NullTrieNodeResolver.Instance, ref emptyPath); @@ -904,7 +904,7 @@ public void After_commit_should_have_has_root() [Test] public void HasRoot_with_block_number_rejects_pruned_state() { - int pruningBoundary = 4; + ulong pruningBoundary = 4; TestPruningStrategy testPruningStrategy = new(shouldPrune: false); TrieStore trieStore = CreateTrieStore( @@ -922,9 +922,10 @@ public void HasRoot_with_block_number_rejects_pruned_state() Hash256[] rootHashes = new Hash256[10]; for (int i = 0; i < 10; i++) { - using (trieStore.BeginBlockCommit((ulong)i)) + ulong blockNumber = (ulong)i; + using (trieStore.BeginBlockCommit(blockNumber)) { - stateTree.Set(TestItem.AddressA, new Account((ulong)(i + 1))); + stateTree.Set(TestItem.AddressA, new Account(blockNumber + 1)); stateTree.Commit(); } rootHashes[i] = stateTree.RootHash; @@ -954,7 +955,7 @@ public void HasRoot_with_block_number_rejects_pruned_state() [Test] public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] bool trackPastKeys) { - int pruningBoundary = 4; + ulong pruningBoundary = 4; // Archive mode: shouldPrune always true, deleteObsoleteKeys = false // When TrackPastKeys is false, _deleteOldNodes is always false regardless of deleteObsoleteKeys. // When TrackPastKeys is true, deleteObsoleteKeys = false still prevents node deletion. @@ -973,20 +974,21 @@ public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] // Start from block 1 (not genesis) to avoid special-casing block 0 int startBlock = 1; - int blockCount = pruningBoundary * 4; + int blockCount = (int)(pruningBoundary * 4); Hash256[] rootHashes = new Hash256[startBlock + blockCount]; for (int i = startBlock; i < startBlock + blockCount; i++) { - using (trieStore.BeginBlockCommit((ulong)i)) + ulong blockNumber = (ulong)i; + using (trieStore.BeginBlockCommit(blockNumber)) { - stateTree.Set(TestItem.AddressA, new Account((ulong)(i + 1))); + stateTree.Set(TestItem.AddressA, new Account(blockNumber + 1)); stateTree.Commit(); } rootHashes[i] = stateTree.RootHash; } trieStore.WaitForPruning(); - Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(pruningBoundary + startBlock)); + Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(pruningBoundary + (ulong)startBlock)); ulong lastPersisted = trieStore.LastPersistedBlockNumber; @@ -1466,7 +1468,7 @@ void VerifyAllTrie() [Test] public async Task Will_Persist_ReCommittedPersistedNode_FromCommitBuffer() { - int pruningBoundary = 4; + ulong pruningBoundary = 4; ManualResetEvent writeBlocker = new(true); ManualResetEventSlim writeReached = new(false); @@ -1570,7 +1572,7 @@ void WriteRandomData(int seed) fullTrieStore.FlushNonBlockingBuffer(); // Write a bit more - for (int i = 13; i < 13 + pruningBoundary; i++) + for (int i = 13; i < 13 + (int)pruningBoundary; i++) { using (fullTrieStore.BeginBlockCommit((ulong)i)) { @@ -1600,7 +1602,7 @@ public void Will_KeepAllState_IfFinalizedLagsBehind() deleteObsoleteKeys: true ); - int pruningBoundary = 4; + ulong pruningBoundary = 4; IPruningConfig pruningConfig = new PruningConfig() { PruningBoundary = pruningBoundary, @@ -1609,7 +1611,7 @@ public void Will_KeepAllState_IfFinalizedLagsBehind() TrackPastKeys = true }; - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); TrieStore fullTrieStore = CreateTrieStore( kvStore: memDb, @@ -1664,7 +1666,7 @@ void VerifyAllTrieExceptGenesis() ptree.RootHash = parentRoot; WriteRandomData(seed); rootsToTests.Add(ptree.RootHash); - if (i >= blockNum - pruningBoundary) lastNRoots++; + if (i >= blockNum - (int)pruningBoundary) lastNRoots++; } } @@ -1678,7 +1680,7 @@ void VerifyAllTrieExceptGenesis() ptree.RootHash = parentRoot; WriteRandomData(seed * 1000); rootsToTests.Add(ptree.RootHash); - if (i >= blockNum - pruningBoundary) lastNRoots++; + if (i >= blockNum - (int)pruningBoundary) lastNRoots++; } } } diff --git a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs index 9f8d17bedfbe..0dc448e147bc 100644 --- a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs @@ -227,7 +227,7 @@ private PruningContext(TestPruningStrategy pruningStrategy, IPersistenceStrategy _pruningStrategy = pruningStrategy; _pruningConfig = pruningConfig ?? new PruningConfig() { TrackPastKeys = false }; - _finalizedStateProvider = new TestFinalizedStateProvider((ulong)_pruningConfig.PruningBoundary); + _finalizedStateProvider = new TestFinalizedStateProvider(_pruningConfig.PruningBoundary); _trieStore = new TrieStore(new NodeStorage(_stateDb), _pruningStrategy, _persistenceStrategy, _finalizedStateProvider, _pruningConfig, _logManager); _finalizedStateProvider.TrieStore = _trieStore; @@ -315,7 +315,7 @@ public PruningContext SetManyAccountWithSameBalance(int startNum, int numOfAccou return this; } - public PruningContext WithMaxDepth(int maxDepth) => WithPruningConfig((cfg) => cfg.PruningBoundary = maxDepth); + public PruningContext WithMaxDepth(int maxDepth) => WithPruningConfig((cfg) => cfg.PruningBoundary = (ulong)maxDepth); public PruningContext WithPruningConfig(Action configurer) { @@ -430,7 +430,7 @@ public PruningContext DisposeAndRecreate() { _worldStateCloser!.Dispose(); _trieStore.Dispose(); - TestFinalizedStateProvider finalizedStateProvider = new((ulong)_pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(_pruningConfig.PruningBoundary); _trieStore = new TrieStore(new NodeStorage(_stateDb), _pruningStrategy, _persistenceStrategy, finalizedStateProvider, _pruningConfig, _logManager); _stateProvider = new WorldState( new TrieStoreScopeProvider(_trieStore, _codeDb, _logManager), _logManager); diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs index 79058c5a70b6..5f07a029bf3c 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs @@ -754,9 +754,9 @@ public TrieStore CreateTrieStore() IPruningConfig pruningConfig = new PruningConfig() { TrackPastKeys = TrackPastKeys, - PruningBoundary = LookupLimit, + PruningBoundary = (ulong)LookupLimit, }; - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); TrieStore trieStore = new( new NodeStorage(new MemDb()), pruneStrategy, @@ -1252,7 +1252,7 @@ public void Can_parallel_read_trees() int repetition = 100; PruningConfig pruningConfig = new(); - TestFinalizedStateProvider finalizedStateProvider = new((ulong)pruningConfig.PruningBoundary); + TestFinalizedStateProvider finalizedStateProvider = new(pruningConfig.PruningBoundary); using TrieStore trieStore = new( new NodeStorage(new MemDb()), new TestPruningStrategy(shouldPrune: true), diff --git a/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs index 88431e7ed1e5..5d875fb26171 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/MaxBlockInCachePruneStrategy.cs @@ -3,15 +3,15 @@ namespace Nethermind.Trie.Pruning; -public class MaxBlockInCachePruneStrategy(IPruningStrategy baseStrategy, long maxBlockFromPersisted, long pruneBoundary) : IPruningStrategy +public class MaxBlockInCachePruneStrategy(IPruningStrategy baseStrategy, ulong maxBlockFromPersisted, ulong pruneBoundary) : IPruningStrategy { public bool DeleteObsoleteKeys => baseStrategy.DeleteObsoleteKeys; public bool ShouldPruneDirtyNode(TrieStoreState state) { - ulong reorgBoundary = state.LatestCommittedBlock - (ulong)pruneBoundary; + ulong reorgBoundary = state.LatestCommittedBlock - pruneBoundary; // Persist snapshot if the last persisted block is too old. Prevent very long memory prune - if (reorgBoundary - state.LastPersistedBlock >= (ulong)maxBlockFromPersisted) return true; + if (reorgBoundary - state.LastPersistedBlock >= maxBlockFromPersisted) return true; return baseStrategy.ShouldPruneDirtyNode(state); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs index fc1149623780..d1b80ae9463b 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/MinBlockInCachePruneStrategy.cs @@ -3,15 +3,15 @@ namespace Nethermind.Trie.Pruning; -public class MinBlockInCachePruneStrategy(IPruningStrategy baseStrategy, long minBlockFromPersisted, long pruneBoundary) : IPruningStrategy +public class MinBlockInCachePruneStrategy(IPruningStrategy baseStrategy, ulong minBlockFromPersisted, ulong pruneBoundary) : IPruningStrategy { public bool DeleteObsoleteKeys => baseStrategy.DeleteObsoleteKeys; public bool ShouldPruneDirtyNode(TrieStoreState state) { - ulong reorgBoundary = state.LatestCommittedBlock - (ulong)pruneBoundary; + ulong reorgBoundary = state.LatestCommittedBlock - pruneBoundary; // Never persist snapshot if too little block in cache. Prevent taking snapshot too often. - if (reorgBoundary - state.LastPersistedBlock < (ulong)minBlockFromPersisted) return false; + if (reorgBoundary - state.LastPersistedBlock < minBlockFromPersisted) return false; return baseStrategy.ShouldPruneDirtyNode(state); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/Prune.cs b/src/Nethermind/Nethermind.Trie/Pruning/Prune.cs index 179611acff2f..fd143c83df46 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/Prune.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/Prune.cs @@ -14,10 +14,10 @@ public static IPruningStrategy WhenPersistedCacheReaches(this IPruningStrategy b public static IPruningStrategy DontDeleteObsoleteNode(this IPruningStrategy baseStrategy) => new DontDeleteObsoleteNodeStrategy(baseStrategy); - public static IPruningStrategy WhenLastPersistedBlockIsTooOld(this IPruningStrategy baseStrategy, long maxBlockInCache, long pruningBoundary) + public static IPruningStrategy WhenLastPersistedBlockIsTooOld(this IPruningStrategy baseStrategy, ulong maxBlockInCache, ulong pruningBoundary) => new MaxBlockInCachePruneStrategy(baseStrategy, maxBlockInCache, pruningBoundary); - public static IPruningStrategy UnlessLastPersistedBlockIsTooNew(this IPruningStrategy baseStrategy, long minBlockInCache, long pruningBoundary) + public static IPruningStrategy UnlessLastPersistedBlockIsTooNew(this IPruningStrategy baseStrategy, ulong minBlockInCache, ulong pruningBoundary) => new MinBlockInCachePruneStrategy(baseStrategy, minBlockInCache, pruningBoundary); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index 9f42ed57857c..24491f665e73 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -32,7 +32,7 @@ public sealed class TrieStore : ITrieStore, IPruningTrieStore private readonly int _shardedDirtyNodeCount = 256; private readonly int _shardBit = 8; private readonly int _maxBufferedCommitCount; - private readonly int _maxDepth; + private readonly ulong _maxDepth; private readonly double _prunePersistedNodePortion; private readonly long _prunePersistedNodeMinimumTarget; private readonly int _pruneDelayMs; @@ -771,14 +771,20 @@ private void SaveSnapshot() } ulong finalizedBlockNumber = _finalizedStateProvider.FinalizedBlockNumber; - ulong pruningBoundaryBlockNumber = _commitSetQueue.MaxBlockNumber!.Value - (ulong)_maxDepth; - ulong effectiveFinalizedBlockNumber = Math.Min(pruningBoundaryBlockNumber, Math.Max(0UL, finalizedBlockNumber)); + // SAFETY: Casting ulong block numbers to long is safe because block numbers are well within the positive range of a signed 64-bit integer, + // and we perform signed subtraction to allow negative boundary results (representing a boundary prior to block 0). + long pruningBoundaryBlock = (long)_commitSetQueue.MaxBlockNumber!.Value - (long)_maxDepth; + long effectiveFinalizedBlock = Math.Min(pruningBoundaryBlock, (long)finalizedBlockNumber); + effectiveFinalizedBlock = Math.Max(0, effectiveFinalizedBlock); + ulong effectiveFinalizedBlockNumber = (ulong)effectiveFinalizedBlock; if (effectiveFinalizedBlockNumber < _commitSetQueue.MinBlockNumber!.Value) { // Finalized block number far behind any commit. Persist everything so that it can be pruned, but not after // pruning boundary point as snap sync need it. - using ArrayPoolListRef commitSet = _commitSetQueue.GetAndDequeueCommitSetsBeforeOrAt(pruningBoundaryBlockNumber); + using ArrayPoolListRef commitSet = pruningBoundaryBlock >= 0 + ? _commitSetQueue.GetAndDequeueCommitSetsBeforeOrAt((ulong)pruningBoundaryBlock) + : new ArrayPoolListRef(); if (commitSet.Count > 0) { @@ -1219,10 +1225,18 @@ private void PersistNode(Hash256? address, in TreePath path, TrieNode currentNod // long block number now receive a ulong. The only remaining call site in this file passes // a genuine ulong block number, so no overflow is possible here. External call sites that // stored a long block number must be audited to ensure they do not pass negative values. - public bool IsNoLongerNeeded(ulong lastCommit) => - lastCommit < LastPersistedBlockNumber && - LatestCommittedBlockNumber >= (ulong)_maxDepth && - lastCommit < LatestCommittedBlockNumber - (ulong)_maxDepth; + // ulong.MaxValue is the sentinel value for no block number assigned yet (replacing previous long -1). + public bool IsNoLongerNeeded(ulong lastCommit) + { + if (lastCommit == ulong.MaxValue) + { + return LatestCommittedBlockNumber >= _maxDepth; + } + + return lastCommit < LastPersistedBlockNumber && + LatestCommittedBlockNumber >= _maxDepth && + lastCommit < LatestCommittedBlockNumber - _maxDepth; + } private void AnnounceReorgBoundaries() { @@ -1250,7 +1264,7 @@ private void AnnounceReorgBoundaries() { // even after we persist a block we do not really remember it as a safe checkpoint // until max reorgs blocks after - if (LatestCommittedBlockNumber >= LastPersistedBlockNumber + (ulong)_maxDepth) + if (LatestCommittedBlockNumber >= LastPersistedBlockNumber + _maxDepth) { shouldAnnounceReorgBoundary = true; } @@ -1442,7 +1456,7 @@ public bool HasRoot(Hash256 stateRoot, ulong blockNumber) if (_deleteOldNodes) { ulong lastPersisted = LastPersistedBlockNumber; - if (lastPersisted > 0 && blockNumber < lastPersisted - (ulong)_maxDepth) + if (lastPersisted > 0 && lastPersisted >= _maxDepth && blockNumber < lastPersisted - _maxDepth) { return false; } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs index e92b5a7f9c16..a4e6bd454234 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStoreDirtyNodesCache.cs @@ -213,11 +213,15 @@ private static NodeRecord GetOrAdd(ConcurrentDictionary [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static NodeRecord MergeRecords(NodeRecord current, NodeRecord candidate) { - // Preserve the higher LastCommit. Both are ulong; ulong.MaxValue (NoCommitSentinel) - // sorts last, which is correct — a real block number always wins over the sentinel - // because real block numbers are far below ulong.MaxValue. + // Preserve the higher LastCommit. Both are ulong; a real block number always wins + // over the sentinel (NoCommitSentinel / ulong.MaxValue). If both are real block numbers, + // the higher block number wins. ulong lastCommit = current.LastCommit; - if (candidate.LastCommit > lastCommit) + if (lastCommit == NoCommitSentinel) + { + lastCommit = candidate.LastCommit; + } + else if (candidate.LastCommit != NoCommitSentinel && candidate.LastCommit > lastCommit) { lastCommit = candidate.LastCommit; } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs index ccc640079ebe..47dfad7c4f45 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs @@ -29,6 +29,7 @@ using Nethermind.Specs.Test; using Nethermind.TxPool.Filters; using NSubstitute; +using NSubstitute.ReceivedExtensions; using NUnit.Framework; namespace Nethermind.TxPool.Test @@ -1085,15 +1086,15 @@ public void should_retrieve_added_persistent_transaction_correctly_even_if_was_e } [Test] - public void should_notify_added_peer_of_own_tx_when_we_are_synced([Values(0, 1)] int headNumber) + public void should_notify_added_peer_of_own_tx_when_we_are_synced([Values(0u, 1u)] uint headNumber) { _txPool = CreatePool(); _ = AddTransactionToPool(); ITxPoolPeer txPoolPeer = Substitute.For(); - txPoolPeer.HeadNumber.Returns((ulong)headNumber); + txPoolPeer.HeadNumber.Returns(headNumber); txPoolPeer.Id.Returns(TestItem.PublicKeyA); _txPool.AddPeer(txPoolPeer); - txPoolPeer.Received(headNumber).SendNewTransactions(Arg.Any>(), false); + txPoolPeer.Received((int)headNumber).SendNewTransactions(Arg.Any>(), false); } [Test] diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs index 9f0e5f94e239..1107ee516809 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs @@ -34,19 +34,19 @@ public class RpcModuleTests private XdcRpcModule _rpcModule; - private EpochSwitchInfo[] GenerateEpochSwitchInfos(long begin, long end, int switchEpoch, int epochLength) + private EpochSwitchInfo[] GenerateEpochSwitchInfos(ulong begin, ulong end, uint switchEpoch, uint epochLength) { List epochSwitchInfos = []; - for (long blockNum = begin; blockNum <= end; blockNum += epochLength) + for (ulong blockNum = begin; blockNum <= end; blockNum += epochLength) { - ulong epochNumber = (ulong)(blockNum / epochLength); - if (epochNumber >= (ulong)switchEpoch) + ulong epochNumber = blockNum / epochLength; + if (epochNumber >= switchEpoch) { epochSwitchInfos.Add(new EpochSwitchInfo( Array.Empty
(), Array.Empty
(), Array.Empty
(), - new BlockRoundInfo(TestItem.KeccakA, 100, (ulong)blockNum))); + new BlockRoundInfo(TestItem.KeccakA, 100, blockNum))); } } return epochSwitchInfos.ToArray(); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs index 1e8ab52ea475..80e7f1fbc060 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcGasLimitCalculatorTests.cs @@ -22,7 +22,7 @@ public void GetGasLimit_WhenDynamicGasLimitNotEnabled_ReturnsTargetBlockGasLimit ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1000UL); @@ -43,7 +43,7 @@ public void GetGasLimit_WhenDynamicGasLimitNotEnabledAndTargetBlockGasLimitIsNul // Arrange ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long?)null); + blocksConfig.TargetBlockGasLimit.Returns((ulong?)null); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1000UL); @@ -67,7 +67,7 @@ public void GetGasLimit_WhenDynamicGasLimitEnabled_UsesTargetAdjustedCalculator( ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1000UL, parentGasLimit); @@ -95,7 +95,7 @@ public void GetGasLimit_WhenDynamicGasLimitEnabled_GasLimitAdjustsTowardTarget() ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1000UL, parentGasLimit); @@ -120,7 +120,7 @@ public void GetGasLimit_AtDynamicGasLimitBlockBoundary_TransitionsToTargetAdjust const ulong targetGasLimit = 100_000_000UL; ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1UL); @@ -147,7 +147,7 @@ public void GetGasLimit_WhenParentGasLimitEqualsTarget_DynamicModeReturnsNearTar ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader parentHeader = CreateParentHeader(1000UL, targetGasLimit); @@ -172,7 +172,7 @@ public void GetGasLimit_WithGenesisBlock_HandlesCorrectly() ISpecProvider specProvider = Substitute.For(); IBlocksConfig blocksConfig = Substitute.For(); - blocksConfig.TargetBlockGasLimit.Returns((long)targetGasLimit); + blocksConfig.TargetBlockGasLimit.Returns(targetGasLimit); XdcGasLimitCalculator calculator = new(specProvider, blocksConfig); BlockHeader genesisHeader = CreateParentHeader(0UL, 5_000_000UL); diff --git a/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs b/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs index ce86b442ed84..2517daf15a2b 100644 --- a/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs +++ b/src/Nethermind/Nethermind.Xdc/QuorumCertificateManager.cs @@ -222,7 +222,7 @@ public bool VerifyCertificate(QuorumCertificate qc, XdcBlockHeader certificateTa } ulong epochSwitchNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; - ulong epochBase = epochSwitchNumber - (epochSwitchNumber % (ulong)spec.EpochLength); + ulong epochBase = epochSwitchNumber - (epochSwitchNumber % spec.EpochLength); ulong gapNumber = epochBase >= spec.Gap ? epochBase - spec.Gap : 0UL; if (gapNumber != qc.GapNumber) diff --git a/src/Nethermind/Nethermind.Xdc/RPC/RpcHelpers.cs b/src/Nethermind/Nethermind.Xdc/RPC/RpcHelpers.cs index 1abcba727873..06c642eff760 100644 --- a/src/Nethermind/Nethermind.Xdc/RPC/RpcHelpers.cs +++ b/src/Nethermind/Nethermind.Xdc/RPC/RpcHelpers.cs @@ -17,7 +17,7 @@ internal static class RpcHelpers { public static PublicApiSnapshot BuildRpcSnapshot(this Snapshot snapshot, XdcBlockHeader header) => new() { - Number = (ulong)header.Number, + Number = header.Number, Hash = header.Hash, Signers = snapshot.NextEpochCandidates.ToHashSet(), }; diff --git a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs index 50bae9d30524..b761d2af2dbe 100644 --- a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs +++ b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs @@ -26,7 +26,7 @@ public ResultWrapper GetBlockInfoByEpochNum(ulong epochNumber) { IXdcReleaseSpec spec = specProvider.GetXdcSpec(tree.Head?.Header?.Number ?? 0); - return epochNumber < (ulong)spec.SwitchEpoch ? + return epochNumber < spec.SwitchEpoch ? CalculateBlockInfoByV1EpochNum(epochNumber) : GetBlockInfoByV2EpochNum(epochNumber); } @@ -94,7 +94,7 @@ public ResultWrapper GetEpochNumbersBetween(long begin, long end) ulong[] epochSwitchNumbers = new ulong[epochSwitchInfos.Length]; for (int i = 0; i < epochSwitchInfos.Length; i++) { - epochSwitchNumbers[i] = (ulong)epochSwitchInfos[i].EpochSwitchBlockInfo.BlockNumber; + epochSwitchNumbers[i] = epochSwitchInfos[i].EpochSwitchBlockInfo.BlockNumber; } return ResultWrapper.Success(epochSwitchNumbers); @@ -208,7 +208,7 @@ public ResultWrapper GetMasternodesByNumber(BlockParameter bl ulong round = xdcHeader.ExtraConsensusData.BlockRound; IXdcReleaseSpec spec = specProvider.GetXdcSpec(xdcHeader); - ulong epochNum = (ulong)spec.SwitchEpoch + round / (ulong)spec.EpochLength; + ulong epochNum = spec.SwitchEpoch + round / spec.EpochLength; EpochSwitchInfo? epochSwitchInfo = epochSwitchManager.GetEpochSwitchInfo(xdcHeader); if (epochSwitchInfo is null) @@ -223,7 +223,7 @@ public ResultWrapper GetMasternodesByNumber(BlockParameter bl MasternodesStatus info = new() { Epoch = epochNum, - Number = (ulong)header.Number, + Number = header.Number, Round = round, MasternodesLen = masternodes.Length, Masternodes = masternodes, @@ -326,7 +326,7 @@ public ResultWrapper GetRewardByAccount(Address account, // No epoch switches in the requested range means no rewards to aggregate. foreach (EpochSwitchInfo epochSwitchInfo in epochSwitchInfos) { - ulong epochBlockNumber = (ulong)epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong epochBlockNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; if (!rewardsStore.HasEpochRewards(epochBlockNumber)) { return ResultWrapper.Fail($"Reward data not available for epoch block {epochBlockNumber}"); diff --git a/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs b/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs index 464d42e28959..4fc2479acd9c 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcGasLimitCalculator.cs @@ -19,6 +19,6 @@ public ulong GetGasLimit(BlockHeader parentHeader) { return targetAdjustedGasLimitCalculator.GetGasLimit(parentHeader); } - return (ulong)(blocksConfig.TargetBlockGasLimit ?? XdcConstants.DefaultTargetGasLimit); + return blocksConfig.TargetBlockGasLimit ?? XdcConstants.DefaultTargetGasLimit; } } diff --git a/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs b/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs index 2e5359aaef56..c14083e5234c 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcRewardCalculator.cs @@ -108,7 +108,7 @@ public BlockReward[] CalculateRewards(Block block) if (totalFoundationWalletReward > UInt256.Zero) rewards.Add(new BlockReward(foundationWalletAddr, totalFoundationWalletReward)); BlockReward[] finalRewards = rewards.ToArray(); - _rewardsStore.SaveEpochRewards((ulong)xdcHeader.Number, finalRewards); + _rewardsStore.SaveEpochRewards(xdcHeader.Number, finalRewards); return finalRewards; } diff --git a/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs b/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs index e816152e131c..39d0f3fcdf9c 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcSealValidator.cs @@ -72,7 +72,7 @@ public virtual bool ValidateParams(BlockHeader parent, BlockHeader header, [NotN throw new InvalidOperationException($"Snap shot returned no master nodes for header \n{xdcHeader}"); } - ulong currentLeaderIndex = (xdcHeader.ExtraConsensusData.BlockRound % xdcSpec.EpochLength % (ulong)masternodes.Length); + ulong currentLeaderIndex = xdcHeader.ExtraConsensusData.BlockRound % xdcSpec.EpochLength % (ulong)masternodes.Length; if (masternodes[(int)currentLeaderIndex] != header.Author) { error = $"Block proposer {header.Author} is not the current leader."; From 38a19903658f08339112b4992c5da4ad7edb3969 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Wed, 10 Jun 2026 08:10:53 +0530 Subject: [PATCH 04/60] fix(rpc): align trace tests with Prague gas specification, fix log finder underflow --- src/Nethermind/Nethermind.Facade/Find/LogFinder.cs | 5 +++++ .../Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs index 953ed3b55d35..750dc08d4b8f 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogFinder.cs @@ -131,6 +131,11 @@ static IEnumerable ReleaseLockOnDispose(IEnumerable source, bool runParall private IEnumerable FilterLogsIteratively(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, CancellationToken cancellationToken) { + if (toBlock.Number < fromBlock.Number) + { + return []; + } + static IEnumerable BlockNumbers(ulong from, ulong count) { for (ulong i = 0; i < count; i++) yield return from + i; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 35a8b0383e26..6fd3e09066ee 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -522,7 +522,7 @@ public async Task Trace_transaction_with_error_reverted() Assert.That(traces.Data.ElementAt(0).TransactionHash, Is.EqualTo(transaction2.Hash!)); string serialized = new EthereumJsonSerializer().Serialize(traces.Data); - Assert.That(serialized, Is.EqualTo("[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"gas\":\"0x9a6c\",\"init\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"value\":\"0x1\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8def\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d78\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]"), serialized.Replace("\"", "\\\"")); + Assert.That(serialized, Is.EqualTo("[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"gas\":\"0x99f4\",\"init\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"value\":\"0x1\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d79\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d02\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]"), serialized.Replace("\"", "\\\"")); } [Test] public async Task trace_timeout_is_separate_for_rpc_calls() @@ -912,7 +912,7 @@ public async Task Trace_replayBlockTransactions_transactions_deploying_contract( Assert.That(System.Linq.Enumerable.Count(traces.Data), Is.EqualTo(2)); Assert.That(traces.Data.ElementAt(0).Action!.From, Is.EqualTo(traces.Data.ElementAt(1).Action!.From)); string serialized = new EthereumJsonSerializer().Serialize(traces.Data); - Assert.That(serialized, Is.EqualTo("[{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c70\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"code\":\"0x\",\"gasUsed\":\"0x79\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x9988\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0x8513c9083ec27fa8e3ca7e3ffa732d61562e2d17e2e1af6e773bc810dc4c3452\",\"vmTrace\":null},{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c70\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"code\":\"0x\",\"gasUsed\":\"0xa3d\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x8feb\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0xa6a56c7927deae778a749bcdab7bbf409c0d8a5d2420021a3ba328240ae832d8\",\"vmTrace\":null}]")); + Assert.That(serialized, Is.EqualTo("[{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c34\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"code\":\"0x\",\"gasUsed\":\"0x79\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x994d\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0x8513c9083ec27fa8e3ca7e3ffa732d61562e2d17e2e1af6e773bc810dc4c3452\",\"vmTrace\":null},{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c34\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"code\":\"0x\",\"gasUsed\":\"0xa3d\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x8fb0\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0xa6a56c7927deae778a749bcdab7bbf409c0d8a5d2420021a3ba328240ae832d8\",\"vmTrace\":null}]")); } [Test] @@ -987,7 +987,7 @@ public async Task Trace_replayBlockTransactions_stateDiff() """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0x0000000000000000000000000000000000123456","input":"0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4000000000000000000000000000000000000000000000000000000000000001C7B8B1991EB44757BC688016D27940DF8FB971D7C87F77A6BC4E938E3202C44037E9267B0AEAA82FA765361918F2D8ABD9CDD86E64AA6F2B81D3C4E0B69A7B055","gas":"0xf4240"}""", "trace", """{"0x0000000000000000000000000000000000000001":{"movePrecompileToAddress":"0x0000000000000000000000000000000000123456", "code": "0x"}}""", - """{"jsonrpc":"2.0","result":{"output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099","stateDiff":null,"trace":[{"action":{"callType":"call","from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","gas":"0xee9b8","input":"0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4000000000000000000000000000000000000000000000000000000000000001c7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c44037e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055","to":"0x0000000000000000000000000000000000123456","value":"0x0"},"result":{"gasUsed":"0xbb8","output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099"},"subtraces":0,"traceAddress":[],"type":"call"}],"vmTrace":null},"id":67}""" + """{"jsonrpc":"2.0","result":{"output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099","stateDiff":null,"trace":[{"action":{"callType":"call","from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","gas":"0xee838","input":"0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4000000000000000000000000000000000000000000000000000000000000001c7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c44037e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055","to":"0x0000000000000000000000000000000000123456","value":"0x0"},"result":{"gasUsed":"0xbb8","output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099"},"subtraces":0,"traceAddress":[],"type":"call"}],"vmTrace":null},"id":67}""" )] public async Task Trace_call_with_state_override(string name, string transactionJson, string traceType, string stateOverrideJson, string expectedResult) { From 8a072177399f82df5ef20ee05a380efd83604f2e Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Wed, 10 Jun 2026 15:39:06 +0530 Subject: [PATCH 05/60] fix(build): align test suites and plugins with unified type changes --- .../Ethereum.Test.Base/JsonToEthereumTest.cs | 4 +- .../TransactionJsonTest.cs | 8 ++-- .../Validators/ContractBasedValidatorTests.cs | 2 +- .../Validators/ListValidatorTests.cs | 2 +- .../BlockhashCacheTests.cs | 8 ++-- .../TxPoolSourceTests.cs | 2 +- .../Validators/HeaderValidatorTests.cs | 4 +- .../Nethermind.Blockchain/BlockTree.cs | 4 +- .../Nethermind.Blockchain/BlockhashCache.cs | 10 ++--- .../BlockhashProvider.cs | 17 ++++----- .../Blocks/BlockStore.cs | 4 +- .../Receipts/PersistentReceiptStorage.cs | 2 + .../AuRaBlockFinalizationManager.cs | 33 ++++++++-------- .../AuRaSealValidator.cs | 4 +- .../AuRaValidatorsCollectionExtensions.cs | 2 +- .../Nethermind.Consensus.Clique/Snapshot.cs | 2 +- .../SnapshotManager.cs | 2 +- .../Processing/ProcessingStats.cs | 2 +- .../Producers/TxPoolTxSource.cs | 28 +++++++------- .../Stateless/StatelessBlockTree.cs | 2 +- .../Nethermind.Core/TransactionExtensions.cs | 4 +- .../Nethermind.Db/IPruningConfig.cs | 6 +-- src/Nethermind/Nethermind.Db/PruningConfig.cs | 6 +-- .../Nethermind.Era1.Test/EraExporterTests.cs | 18 ++++----- src/Nethermind/Nethermind.Era1/EraConfig.cs | 2 +- src/Nethermind/Nethermind.Era1/EraExporter.cs | 4 +- src/Nethermind/Nethermind.Era1/EraImporter.cs | 4 +- src/Nethermind/Nethermind.Era1/EraStore.cs | 6 +-- src/Nethermind/Nethermind.Era1/IEraConfig.cs | 2 +- .../Export/EraExporterTests.cs | 12 +++--- .../Store/RemoteEraStoreDecoratorTests.cs | 2 +- .../Nethermind.EraE/Config/EraEConfig.cs | 2 +- .../Nethermind.EraE/Config/IEraEConfig.cs | 2 +- .../Nethermind.EraE/Export/EraExporter.cs | 10 ++--- .../Nethermind.EraE/Import/EraImporter.cs | 4 +- .../Nethermind.EraE/Store/EraStore.cs | 8 ++-- .../Store/RemoteEraStoreDecorator.cs | 10 ++--- .../Nethermind.Evm/BlobGasCalculator.cs | 14 +++++-- .../GasPolicy/EthereumGasPolicy.cs | 18 ++++----- .../Nethermind.Evm/GasPolicy/IGasPolicy.cs | 8 ++-- .../Instructions/EvmInstructions.Stack.cs | 4 +- .../TransactionProcessor.cs | 38 +++++++++---------- .../HistoryPrunerTests.cs | 8 ++-- .../Nethermind.History/HistoryPruner.cs | 7 ++-- .../Nethermind.History/IHistoryPruner.cs | 2 +- .../PruningTrieStateFactory.cs | 8 ++-- .../Eth/EthRpcModuleTests.Capabilities.cs | 2 +- .../Modules/Eth/EthCapabilitiesProvider.cs | 2 +- .../AuRaMergeEngineModuleTests.cs | 10 ++--- .../PayloadPreparationService.cs | 8 ++-- .../Data/BlobsBundleV1.cs | 2 +- .../Data/BlobsBundleV2.cs | 2 +- .../Nethermind.Merge.Plugin/GC/GCKeeper.cs | 4 +- .../Nethermind.Merge.Plugin/GC/IGCStrategy.cs | 2 +- .../GC/NoGCStrategy.cs | 2 +- .../GC/NoSyncGcRegionStrategy.cs | 2 +- .../Nethermind.Merge.Plugin/IMergeConfig.cs | 2 +- .../Nethermind.Merge.Plugin/MergeConfig.cs | 2 +- .../V69/Messages/ReceiptMessageDecoder69.cs | 3 ++ .../OptimismReceiptMessageDecoder.cs | 1 + .../OptimismTransactionProcessor.cs | 2 +- .../GasColumnProviderTests.cs | 2 +- .../GasColumnProvider.cs | 16 ++++---- .../PrecompileBenchmarkBase.cs | 2 +- .../ReceiptMessageDecoder.cs | 1 + .../StatelessSpecProvider.cs | 6 +-- ...ByTotalDifficultyPeerAllocationStrategy.cs | 10 ++--- .../FastBlocks/BodiesSyncFeed.cs | 8 ++-- .../FastBlocks/FastBlocksPriorities.cs | 2 +- .../FastBlocks/HeadersSyncFeed.cs | 2 +- .../ParallelSync/MultiSyncModeSelector.cs | 4 +- .../PersistentBlobTxDistinctSortedPool.cs | 2 +- src/Nethermind/Nethermind.TxPool/TxPool.cs | 2 +- .../Helpers/XdcTestBlockchain.cs | 2 +- .../ModuleTests/RpcModuleTests.cs | 4 +- .../XdcBlockProducerTest.cs | 2 +- .../XdcSubnetSealValidatorTests.cs | 2 +- .../Nethermind.Xdc/RPC/XdcRpcModule.cs | 2 +- .../Spec/XdcChainSpecEngineParameters.cs | 2 +- .../Nethermind.Xdc/Spec/XdcReleaseSpec.cs | 4 +- .../Nethermind.Xdc/XdcBlockProducer.cs | 2 +- .../Nethermind.Xdc/XdcHeaderValidator.cs | 2 +- src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs | 2 +- 83 files changed, 243 insertions(+), 235 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs index a43a7768a88c..0db09e57b8c8 100644 --- a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs @@ -232,9 +232,9 @@ public static Transaction Convert(LegacyTransactionJson transactionJson) Transaction transaction = new() { Value = transactionJson.Value, - GasLimit = transactionJson.GasLimit, + GasLimit = (ulong)transactionJson.GasLimit, GasPrice = transactionJson.GasPrice, - Nonce = transactionJson.Nonce, + Nonce = (ulong)transactionJson.Nonce, To = transactionJson.To, Data = transactionJson.Data, Signature = new Signature(transactionJson.R, transactionJson.S, transactionJson.V) diff --git a/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs b/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs index eb35b08c5b05..adc80d95c0d8 100644 --- a/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs +++ b/src/Nethermind/Ethereum.Transaction.Test/TransactionJsonTest.cs @@ -29,7 +29,7 @@ public void Can_load_access_lists() TransactionJson txJson = serializer.Deserialize(lists); txJson.SecretKey = TestItem.PrivateKeyA.KeyBytes; txJson.Value = new UInt256[1]; - txJson.GasLimit = new long[1]; + txJson.GasLimit = new ulong[1]; txJson.Data = new byte[1][]; Assert.That(txJson.AccessLists, Is.Not.Null); Assert.That(txJson.AccessLists[0][0].Address, Is.EqualTo(new Address("0x0001020304050607080900010203040506070809"))); @@ -62,7 +62,7 @@ public void Amsterdam_state_test_without_env_slot_number_defaults_to_zero() .WithChainId(1) .WithGasPrice(0x10) .WithGasLimit(0x100000) - .WithNonce(UInt256.Zero) + .WithNonce(0UL) .To(contract) .WithValue(0) .SignedAndResolved(senderKey) @@ -146,14 +146,14 @@ public void Invalid_pre_berlin_access_list_tx_with_empty_list_preserves_prestate { [recipient] = new() { - Nonce = UInt256.One, + Nonce = 1UL, Balance = UInt256.Zero, Code = [0x60, 0x01, 0x60, 0x00, 0x55], // PUSH1 1 PUSH1 0 SSTORE Storage = new() { [UInt256.Zero] = new UInt256(0xdeadbeef).ToBigEndian() } }, [sender] = new() { - Nonce = UInt256.Zero, + Nonce = 0UL, Balance = UInt256.Parse("1000000000000000000000"), Code = [], Storage = [] diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs index 3d85a82a9e69..20124990e5d0 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs @@ -525,7 +525,7 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con Action preProcess = () => validator.OnBlockProcessingStart(_block); Assert.That(preProcess, Throws.Nothing, test.TestName); validator.OnBlockProcessingEnd(_block, txReceipts); - ulong finalizedNumber = blockNumber - (ulong)validator.Validators.MinSealersForFinalization() + 1UL; + ulong finalizedNumber = blockNumber - validator.Validators.MinSealersForFinalization() + 1UL; _blockFinalizationManager.GetLastLevelFinalizedBy(_block.Header.Hash).Returns(finalizedNumber); _blockFinalizationManager.BlocksFinalized += Raise.EventWith( new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(finalizedNumber) diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs index 853912746022..665e9ea5ca6c 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ListValidatorTests.cs @@ -65,7 +65,7 @@ public void should_get_current_sealers_count(int validatorCount) => [TestCase(10, ExpectedResult = 6)] [TestCase(100, ExpectedResult = 51)] public int should_get_min_sealers_for_finalization(int validatorCount) => - GetListValidator(TestItem.Addresses.Take(validatorCount).ToArray()).Validators.MinSealersForFinalization(); + (int)GetListValidator(TestItem.Addresses.Take(validatorCount).ToArray()).Validators.MinSealersForFinalization(); [Test] public void throws_ArgumentNullException_on_empty_validator() diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs index e75f504a8af0..2f609599615f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs @@ -18,7 +18,7 @@ namespace Nethermind.Blockchain.Test; [Parallelizable(ParallelScope.All)] public class BlockhashCacheTests { - private const int FlatCacheItemLength = BlockhashCache.MaxDepth + 1; + private const int FlatCacheItemLength = (int)BlockhashCache.MaxDepth + 1; [Test] public void GetHash_with_depth_zero_returns_block_hash() @@ -236,7 +236,7 @@ public void Can_stitch_block_ranges() for (ulong i = 100ul; i <= 500ul; i += 100ul) { BlockHeader block = tree.FindHeader(i, BlockTreeLookupOptions.None)!; - cache.GetHash(block, BlockhashCache.MaxDepth); + cache.GetHash(block, (int)BlockhashCache.MaxDepth); } Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(501, 1, 5))); @@ -268,13 +268,13 @@ public async Task Can_prune_old_forks() (BlockTree tree, BlockhashCache cache) = BuildTest((int)depth); for (ulong i = BlockhashCache.MaxDepth; i < depth; i += BlockhashCache.MaxDepth) { - cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, BlockhashCache.MaxDepth); + cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, (int)BlockhashCache.MaxDepth); } Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)depth, 1, 5))); await cache.Prefetch(tree.FindHeader(depth - 1ul, BlockTreeLookupOptions.RequireCanonical)!); await Task.Delay(100); - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(BlockhashCache.MaxDepth * 2 + 1, 1, 3))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)BlockhashCache.MaxDepth * 2 + 1, 1, 3))); } [Test] diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs index 4f0cdd7ed912..1cb22746e917 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs @@ -48,7 +48,7 @@ public void GetTransactions_should_respect_customizable_blob_gas_limit(int[] blo TxPoolTxSource transactionSelector = new(txPool, specProvider, transactionComparerProvider, LimboLogs.Instance, txFilterPipeline, new BlocksConfig { SecondsPerSlot = 12, BlockProductionBlobLimit = customBlobLimit }); IEnumerable txs = transactionSelector.GetTransactions(new BlockHeader(), long.MaxValue); - int blobsCount = txs.Sum(tx => tx.GetBlobCount()); + int blobsCount = (int)txs.Sum(tx => (long)tx.GetBlobCount()); Assert.That(blobsCount, Is.LessThanOrEqualTo(Cancun.Instance.MaxProductionBlobCount(customBlobLimit))); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index 2061e1b95891..7e80273e05ed 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -100,8 +100,8 @@ public void When_gas_limit_below_parent(int adjustment, bool expectedResult) ulong delta = _parentBlock.Header.GasLimit / 1024ul; _block.Header.GasLimit = adjustment >= 0 - ? _parentBlock.Header.GasLimit + delta + (ulong)adjustment - : _parentBlock.Header.GasLimit + delta - (ulong)(-adjustment); + ? _parentBlock.Header.GasLimit - delta + (ulong)adjustment + : _parentBlock.Header.GasLimit - delta - (ulong)(-adjustment); _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 6104fc36a760..7ac517676ac7 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -1042,7 +1042,7 @@ private void TryUpdateSyncPivot() { BlockHeader? newPivotHeader = FinalizedHash is not null ? FindHeader(FinalizedHash, BlockTreeLookupOptions.RequireCanonical) - : FindHeader((Head?.Number ?? 0UL) > (ulong)Reorganization.MaxDepth ? (Head.Number - (ulong)Reorganization.MaxDepth) : 0UL, BlockTreeLookupOptions.RequireCanonical); + : FindHeader((Head?.Number ?? 0UL) > Reorganization.MaxDepth ? (Head.Number - Reorganization.MaxDepth) : 0UL, BlockTreeLookupOptions.RequireCanonical); if (newPivotHeader is null) { @@ -1412,7 +1412,7 @@ private void UpdateOrCreateLevel(in ArrayPoolListRef<(ulong number, BlockInfo bl /// /// private bool ShouldCache(ulong number) => - number == _genesisBlockNumber || Head is null || Head.Number < (ulong)BlockStore.CacheSize || number >= Head.Number - (ulong)BlockStore.CacheSize; + number == _genesisBlockNumber || Head is null || Head.Number < BlockStore.CacheSize || number >= Head.Number - BlockStore.CacheSize; public ChainLevelInfo? FindLevel(ulong number) => _chainLevelInfoRepository.LoadLevel(number); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs index 1afb5cafd73d..655a543cab77 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs @@ -23,22 +23,22 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) private readonly ConcurrentDictionary _blocks = new(); private readonly LruCache _flatCache = new(32, nameof(BlockhashCache)); private readonly Lock _lock = new(); - public const int MaxDepth = BlockhashProvider.MaxDepth; + public const ulong MaxDepth = BlockhashProvider.MaxDepth; private ulong _minBlock = ulong.MaxValue; private Task _pruningTask = Task.CompletedTask; public Hash256? GetHash(BlockHeader headBlock, int depth) => depth == 0 ? headBlock.Hash : depth == 1 ? headBlock.ParentHash - : depth > MaxDepth ? null + : (ulong)depth > MaxDepth ? null : _flatCache.TryGet(headBlock.ParentHash!, out Hash256[] array) ? array[depth - 2] : Load(headBlock, depth, out _)?.Hash; private CacheNode? Load(BlockHeader blockHeader, int depth, out Hash256[]? hashes, CancellationToken cancellationToken = default) { hashes = null; - if (depth > MaxDepth) return null; - bool alwaysAdd = depth == MaxDepth; + if ((ulong)depth > MaxDepth) return null; + bool alwaysAdd = (ulong)depth == MaxDepth; using ArrayPoolListRef<(CacheNode Node, bool NeedToAdd)> blocks = new(depth + 1); Hash256 currentHash = blockHeader.Hash!; CacheNode currentNode = null; @@ -148,7 +148,7 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) } else { - Load(blockHeader, MaxDepth, out hashes, cancellationToken); + Load(blockHeader, (int)MaxDepth, out hashes, cancellationToken); } } } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index 3d6ee1982e86..2a5f1edec08d 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -21,7 +21,7 @@ public class BlockhashProvider( ILogManager? logManager) : IBlockhashProvider { - public const int MaxDepth = 256; + public const ulong MaxDepth = 256; private readonly IBlockhashStore _blockhashStore = new BlockhashStore(worldState); private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); private Hash256[]? _hashes; @@ -29,25 +29,24 @@ public class BlockhashProvider( public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) { - if (number < 0) + if (spec.IsBlockHashInStateAvailable) { - return ReturnOutOfBounds(currentBlock, number); + return _blockhashStore.GetBlockHashFromState(currentBlock, number, spec); } - if (spec.IsBlockHashInStateAvailable) + ulong depth = currentBlock.Number - number; + if (depth == 0 || depth > MaxDepth) { - return _blockhashStore.GetBlockHashFromState(currentBlock, number, spec); + return ReturnOutOfBounds(currentBlock, number); } - long depth = (long)(currentBlock.Number - number); Hash256[]? hashes = Volatile.Read(ref _hashes); return depth switch { - <= 0 or > MaxDepth => ReturnOutOfBounds(currentBlock, number), - 1 => currentBlock.ParentHash, + 1UL => currentBlock.ParentHash, _ => hashes is not null - ? hashes[depth - 1] + ? hashes[(int)(depth - 1)] : blockhashCache.GetHash(currentBlock, (int)depth) ?? throw new InvalidDataException("Hash cannot be found when executing BLOCKHASH operation") }; diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs index 4f8b05e8ea56..1151157686e7 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs @@ -14,13 +14,13 @@ namespace Nethermind.Blockchain.Blocks; public class BlockStore([KeyFilter(DbNames.Blocks)] IDb blockDb, IHeaderDecoder? headerDecoder = null) : IBlockStore, IClearableCache { - public const int CacheSize = 128 + 32; + public const ulong CacheSize = 128 + 32; private readonly IDb _blockDb = blockDb; private readonly BlockDecoder _blockDecoder = new(headerDecoder ?? new HeaderDecoder()); private readonly AssociativeCache - _blockCache = new(CacheSize); + _blockCache = new((int)CacheSize); public void SetMetadata(byte[] key, byte[] value) => _blockDb.Set(key, value); diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs index 1015ba914c3e..4eb6d386f2cb 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs @@ -82,6 +82,7 @@ private void BlockTreeOnBlockAddedToMain(object? sender, BlockReplacementEventAr Block newMain = e.Block; // Delete old tx index + // safe: TxLookupLimit is checked to be > 0, so it is safe to cast to ulong if (_receiptConfig.TxLookupLimit > 0 && newMain.Number > (ulong)_receiptConfig.TxLookupLimit.Value) { Block newOldTx = _blockTree.FindBlock(newMain.Number - (ulong)_receiptConfig.TxLookupLimit.Value); @@ -368,6 +369,7 @@ private void EnsureCanonical(Block block, ulong? lastBlockNumber) lastBlockNumber ??= _blockTree.FindBestSuggestedHeader()?.Number ?? 0UL; if (_receiptConfig.TxLookupLimit == -1) return; + // safe: TxLookupLimit != 0 and the -1 case is already handled above, so it is safe to cast to ulong if (_receiptConfig.TxLookupLimit != 0 && lastBlockNumber.Value >= (ulong)_receiptConfig.TxLookupLimit && block.Number <= lastBlockNumber.Value - (ulong)_receiptConfig.TxLookupLimit) return; if (_receiptConfig.CompactTxIndex) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs index 0b131eb2e8c9..27e4f455f8d1 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs @@ -99,8 +99,8 @@ void UnFinalizeBlock(BlockHeader blockHeader, BatchWrite batch) { using BatchWrite batch = _chainLevelInfoRepository.StartBatch(); // need to un-finalize blocks - int minSealersForFinalization = GetMinSealersForFinalization(header.Number); - for (int i = 1; i < minSealersForFinalization; i++) + ulong minSealersForFinalization = GetMinSealersForFinalization(header.Number); + for (ulong i = 1UL; i < minSealersForFinalization; i++) { header = _blockTree.FindParentHeader(header!, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is not null) @@ -140,11 +140,11 @@ private IReadOnlyList GetFinalizedBlocks(BlockHeader block) if (_logger.IsInfo) _logger.Info($"Block {twoThirdsMajorityTransition}: Transitioning to 2/3 quorum."); } - int minSealersForFinalization = GetMinSealersForFinalization(block.Number); + ulong minSealersForFinalization = GetMinSealersForFinalization(block.Number); BlockHeader originalBlock = block; bool IsConsecutiveBlock() => originalBlock.ParentHash == _lastProcessedBlockHash; - bool ConsecutiveBlockWillFinalizeBlocks() => _consecutiveValidatorsForNotYetFinalizedBlocks.Count >= minSealersForFinalization; + bool ConsecutiveBlockWillFinalizeBlocks() => (ulong)_consecutiveValidatorsForNotYetFinalizedBlocks.Count >= minSealersForFinalization; List finalizedBlocks; bool isConsecutiveBlock = IsConsecutiveBlock(); @@ -191,7 +191,7 @@ private IReadOnlyList GetFinalizedBlocks(BlockHeader block) while (!blockInfo.IsFinalized && (isConsecutiveBlock || OriginalBlockSealerSignedOnlyOnce())) { validators.Add(block.Beneficiary); - if (validators.Count >= minSealersForFinalization) + if ((ulong)validators.Count >= minSealersForFinalization) { blockInfo.IsFinalized = true; _chainLevelInfoRepository.PersistLevel(block.Number, chainLevel, batch); @@ -292,11 +292,11 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) { BlockHeader block = _blockTree.FindHeader(blockHash, BlockTreeLookupOptions.None)!; HashSet
validators = []; - int minSealersForFinalization = GetMinSealersForFinalization(block.Number); + ulong minSealersForFinalization = GetMinSealersForFinalization(block.Number); while (block!.Number > 0) { validators.Add(block.Beneficiary); - if (validators.Count >= minSealersForFinalization) + if ((ulong)validators.Count >= minSealersForFinalization) { return block.Number; } @@ -311,7 +311,7 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) { BlockHeader? block = _blockTree.FindHeader(level, BlockTreeLookupOptions.None); HashSet
validators = []; - int minSealersForFinalization = GetMinSealersForFinalization(level); + ulong minSealersForFinalization = GetMinSealersForFinalization(level); // this can only happen when we are fast syncing headers before pivot if (block is null) @@ -319,16 +319,17 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) // in that case check if it has enough blocks to best known to be finalized // as everything before pivot should be finalized long blocksAfter = (long)_blockTree.BestKnownNumber - (long)level + 1; - if (blocksAfter >= minSealersForFinalization) + // safe: minSealersForFinalization is derived from validator counts and is bounded well within positive long range + if (blocksAfter >= (long)minSealersForFinalization) { - return level + (ulong)minSealersForFinalization - 1; + return level + minSealersForFinalization - 1UL; } } while (block is not null) { validators.Add(block.Beneficiary); - if (validators.Count >= minSealersForFinalization) + if ((ulong)validators.Count >= minSealersForFinalization) { return block.Number; } @@ -339,9 +340,9 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) return null; } - private int GetMinSealersForFinalization(ulong blockNumber) => - blockNumber == 0 - ? 1 + private ulong GetMinSealersForFinalization(ulong blockNumber) => + blockNumber == 0UL + ? 1UL : _validatorStore.GetValidators(blockNumber).MinSealersForFinalization(blockNumber >= twoThirdsMajorityTransition); public ulong LastFinalizedBlockLevel @@ -424,14 +425,14 @@ public void Clear() _blocks.Clear(); } - public BlockHeader? GetBlockThatWillBeFinalized(out HashSet
validators, int minSealersForFinalization) + public BlockHeader? GetBlockThatWillBeFinalized(out HashSet
validators, ulong minSealersForFinalization) { validators = []; for (int i = 0; i < _blocks.Count; i++) { BlockHeader? block = _blocks[i]; validators.Add(block.Beneficiary); - if (validators.Count >= minSealersForFinalization) + if ((ulong)validators.Count >= minSealersForFinalization) { return block; } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs index 867f0bd95a7f..0fa2926b8b11 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaSealValidator.cs @@ -191,7 +191,7 @@ private class StepElementComparer : IComparer private readonly List _list = []; - private const int CacheSizeFullRoundsMultiplier = 4; + private const ulong CacheSizeFullRoundsMultiplier = 4; public bool ContainsSiblingOrInsert(BlockHeader header, int validatorCount) { @@ -243,7 +243,7 @@ public bool ContainsSiblingOrInsert(BlockHeader header, int validatorCount) /// private void ClearOldCache(ulong step, int validatorCount) { - ulong siblingMaliceDetectionPeriod = (ulong)CacheSizeFullRoundsMultiplier * (ulong)validatorCount; + ulong siblingMaliceDetectionPeriod = CacheSizeFullRoundsMultiplier * (ulong)validatorCount; ulong oldestStepToKeep = step > siblingMaliceDetectionPeriod ? step - siblingMaliceDetectionPeriod : 0UL; int index = BinarySearch(oldestStepToKeep); int positiveIndex = index >= 0 ? index : ~index; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorsCollectionExtensions.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorsCollectionExtensions.cs index 3168763edfd6..d23243e84b99 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorsCollectionExtensions.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/AuRaValidatorsCollectionExtensions.cs @@ -8,6 +8,6 @@ namespace Nethermind.Consensus.AuRa.Validators { internal static class AuRaValidatorsCollectionExtensions { - public static int MinSealersForFinalization(this IList
validators, bool twoThirds = false) => (twoThirds ? validators.Count * 2 / 3 : validators.Count / 2) + 1; + public static ulong MinSealersForFinalization(this IList
validators, bool twoThirds = false) => (ulong)(twoThirds ? validators.Count * 2 / 3 : validators.Count / 2) + 1UL; } } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs b/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs index fac860203064..040ab1179384 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/Snapshot.cs @@ -39,6 +39,6 @@ public object Clone() => Votes = [.. Votes] }; - public long SignerLimit => Signers.Count / 2 + 1; + public ulong SignerLimit => (ulong)Signers.Count / 2 + 1; } } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index d1c2f7711c35..07b8dd6552c5 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -183,7 +183,7 @@ public bool HasSignedRecently(Snapshot snapshot, ulong number, Address signer) ulong signedAt = snapshot.Signers[signer]; if (signedAt == 0UL) return false; - return number - signedAt < (ulong)snapshot.SignerLimit; + return number - signedAt < snapshot.SignerLimit; } public bool IsValidVote(Snapshot snapshot, Address address, bool authorize) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 7ee5a1a4ae10..265cee0f8d0f 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -225,7 +225,7 @@ public void UpdateStats(IReadOnlyList blocks, BlockHeader? baseBlock, lon transactionCount += transactions.Length; for (int j = 0; j < transactions.Length; j++) { - blobCount += transactions[j].GetBlobCount(); + blobCount += (long)transactions[j].GetBlobCount(); } } diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 2ede66225923..36154141c7da 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -154,7 +154,7 @@ private static IEnumerable PickBlobTxsBetterThanCurrentTx(ArrayPool private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions, BlockHeader parent, IReleaseSpec spec, in UInt256 baseFee, ArrayPoolList selectedBlobTxs, int maxBlobs) { int maxBlobsToConsider = maxBlobs * 5; - int countOfRemainingBlobs = 0; + ulong countOfRemainingBlobs = 0UL; if (!TryUpdateFeePerBlobGas(parent, spec, out UInt256 feePerBlobGas)) { @@ -165,8 +165,8 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain ArrayPoolList<(Transaction tx, ulong blobChain)>? candidates = null; foreach ((Transaction blobTx, ulong blobChain) in blobTransactions) { - int txBlobCount = blobTx.GetBlobCount(); - if (txBlobCount > maxBlobs) + ulong txBlobCount = blobTx.GetBlobCount(); + if (txBlobCount > (ulong)maxBlobs) { if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space."); continue; @@ -178,7 +178,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain continue; } - if (txBlobCount == 1 && candidates is null) + if (txBlobCount == 1UL && candidates is null) { selectedBlobTxs.Add(blobTx); if (selectedBlobTxs.Count == maxBlobs) @@ -196,7 +196,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain countOfRemainingBlobs += txBlobCount; } - if (countOfRemainingBlobs > maxBlobsToConsider) + if (countOfRemainingBlobs > (ulong)maxBlobsToConsider) { // Reached max blobs to consider, should have enough to fill the block. break; @@ -210,7 +210,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain { // We have leftover candidates. Check how many blob slots remain. int leftoverCapacity = maxBlobs - selectedBlobTxs.Count; - if (countOfRemainingBlobs <= leftoverCapacity) + if (countOfRemainingBlobs <= (ulong)leftoverCapacity) { // We can take all, no optimal picking needed. foreach ((Transaction tx, ulong blobChain) tx in candidates.AsSpan()) @@ -266,11 +266,11 @@ private static void ChooseBestBlobTransactions( } // How many blobs does this tx actually consume? - int blobCount = tx.GetBlobCount(); + ulong blobCount = tx.GetBlobCount(); // If this tx has explicit dependencies (i.e. it requires k prior blobs // from the *same address* to be in the block before it), include them here. // We'll need a capacity of blobDependenciesCount slots *plus* its own blobCount. - ulong blobCapacityNeeded = blobChain + (ulong)blobCount; + ulong blobCapacityNeeded = blobChain + blobCount; // Compute the total fee this tx contributes (premium * gas used). // Use actual gas used (SpentGas) when available as the tx may be using over-estimated gaslimit ulong feeValue = (ulong)premiumPerGas * tx.SpentGas; @@ -280,7 +280,7 @@ private static void ChooseBestBlobTransactions( // if blobDependenciesCount > 0, then we require *the* previous // nonce from the same address to also be chosen in order to // include this tx's extra blob-dependency slots. - if (blobCapacityNeeded > (ulong)blobCount) + if (blobCapacityNeeded > blobCount) { // scan backward from i–1 until you hit a tx from the same address // this ensures we only link to the immediate prior-nonce. @@ -315,7 +315,7 @@ private static void ChooseBestBlobTransactions( // because the dpFees index represents total blobs used; // dependencies are "paid for" by only allowing this path // if dependencyIndex was chosen at the smaller capacity. - ulong candidateFee = dpFees[capacity - blobCount] + feeValue; + ulong candidateFee = dpFees[capacity - (int)blobCount] + feeValue; // If this improves the max fee at [capacity], record it if (candidateFee >= dpFees[capacity]) { @@ -324,7 +324,7 @@ private static void ChooseBestBlobTransactions( isChosen[i * maxCapacity + capacity] = dependencyIndex < 0 || // with a dependency: only mark this tx as chosen // if *its* predecessor was also marked in the smaller capacity. - isChosen[dependencyIndex * maxCapacity + (capacity - blobCount)]; + isChosen[dependencyIndex * maxCapacity + (capacity - (int)blobCount)]; } } } @@ -337,9 +337,9 @@ private static void ChooseBestBlobTransactions( if (isChosen[i * maxCapacity + remainingCapacity]) { Transaction tx = candidateTxs[i].tx; - int blobCount = tx.GetBlobCount(); + ulong blobCount = tx.GetBlobCount(); selectedBlobTxs.Add(tx); - remainingCapacity -= blobCount; + remainingCapacity -= (int)blobCount; } } @@ -384,7 +384,7 @@ protected virtual IEnumerable GetOrderedTransactions(IDictionary GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, int maxBlobs = 0) => - OrderCore(pendingTransactions, comparer, static tx => (ulong)tx.GetBlobCount(), filter, (ulong)maxBlobs); + OrderCore(pendingTransactions, comparer, static tx => tx.GetBlobCount(), filter, (ulong)maxBlobs); protected virtual IComparer GetComparer(BlockHeader parent, BlockPreparationContext blockPreparationContext) => _transactionComparerProvider.GetDefaultProducerComparer(blockPreparationContext); diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs index 190e07d265f0..4cb6263100f9 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs @@ -226,7 +226,7 @@ public event EventHandler? OnForkChoiceUpd public Task Prefetch(BlockHeader blockHeader, CancellationToken cancellationToken) { - const int length = BlockhashCache.MaxDepth + 1; + const int length = (int)BlockhashCache.MaxDepth + 1; Hash256[] result = new Hash256[length]; result[0] = blockHeader.Hash; for (int i = 1; i < length; i++) diff --git a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs index e119374a37dc..d44bda1e5465 100644 --- a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs @@ -56,8 +56,8 @@ public UInt256 CalculateMaxPriorityFeePerGas(bool eip1559Enabled, in UInt256 bas public bool IsAboveInitCode(IReleaseSpec spec) => tx.IsContractCreation && spec.IsEip3860Enabled && tx.DataLength > spec.MaxInitCodeSize; - public ulong GetBlobGas() => (uint)tx.GetBlobCount() * Eip4844Constants.GasPerBlob; - public int GetBlobCount() => tx.BlobVersionedHashes?.Length ?? 0; + public ulong GetBlobGas() => tx.GetBlobCount() * Eip4844Constants.GasPerBlob; + public ulong GetBlobCount() => (ulong)(tx.BlobVersionedHashes?.Length ?? 0); public void CapGasLimit(ulong? gasCap) { diff --git a/src/Nethermind/Nethermind.Db/IPruningConfig.cs b/src/Nethermind/Nethermind.Db/IPruningConfig.cs index dc434ab45fd0..0c3e60e6d099 100644 --- a/src/Nethermind/Nethermind.Db/IPruningConfig.cs +++ b/src/Nethermind/Nethermind.Db/IPruningConfig.cs @@ -93,16 +93,16 @@ The max number of parallel tasks that can be used by full pruning. long PrunePersistedNodeMinimumTarget { get; set; } [ConfigItem(Description = "Maximum number of blocks worth of unpersisted state in memory. Default is 297, which is the number of mainnet blocks per hour.", DefaultValue = "297")] - long MaxUnpersistedBlockCount { get; set; } + ulong MaxUnpersistedBlockCount { get; set; } [ConfigItem(Description = "Minimum number of block worth of unpersisted state in memory. Prevent memory pruning too often due to insufficient dirty cache memory.", DefaultValue = "8")] - long MinUnpersistedBlockCount { get; set; } + ulong MinUnpersistedBlockCount { get; set; } [ConfigItem(Description = "Maximum number of block in commit buffer before blocking.", DefaultValue = "128", HiddenFromDocs = true)] int MaxBufferedCommitCount { get; set; } [ConfigItem(Description = "[TECHNICAL] Simulate long finalization by not moving finalized block pointer until after this depth.", DefaultValue = "0", HiddenFromDocs = true)] - int SimulateLongFinalizationDepth { get; set; } + ulong SimulateLongFinalizationDepth { get; set; } [ConfigItem(Description = "If in-memory pruning is scheduled, the duration between `newPayload` and the GC trigger. If too short, it may clash with fork choice; if too long, it may overlap with GC.", DefaultValue = "75", HiddenFromDocs = true)] int PruneDelayMilliseconds { get; set; } diff --git a/src/Nethermind/Nethermind.Db/PruningConfig.cs b/src/Nethermind/Nethermind.Db/PruningConfig.cs index cb287ec14062..68d7fb43f9ee 100644 --- a/src/Nethermind/Nethermind.Db/PruningConfig.cs +++ b/src/Nethermind/Nethermind.Db/PruningConfig.cs @@ -60,10 +60,10 @@ public int DirtyNodeShardBit public double PrunePersistedNodePortion { get; set; } = 0.05; public long PrunePersistedNodeMinimumTarget { get; set; } = 50.MiB; - public long MaxUnpersistedBlockCount { get; set; } = 300; // About 1 hour on mainnet - public long MinUnpersistedBlockCount { get; set; } = 8; // About slightly more than 1 minute + public ulong MaxUnpersistedBlockCount { get; set; } = 300; // About 1 hour on mainnet + public ulong MinUnpersistedBlockCount { get; set; } = 8; // About slightly more than 1 minute public int MaxBufferedCommitCount { get; set; } = 128; - public int SimulateLongFinalizationDepth { get; set; } = 0; + public ulong SimulateLongFinalizationDepth { get; set; } = 0; public int PruneDelayMilliseconds { get; set; } = 75; } } diff --git a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs index 86c69ed68aa1..0c388137138b 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs @@ -13,15 +13,15 @@ namespace Nethermind.Era1.Test; public class EraExporterTests { - [TestCase(1, 0, 1 - 1, 1, 1)] - [TestCase(3, 0, 3 - 1, 1, 3)] - [TestCase(16, 0, 16 - 1, 16, 1)] - [TestCase(16, 0, 0, 16, 1)] - [TestCase(32, 0, 32 - 1, 16, 2)] - [TestCase(32, 8, 0, 16, 2)] - [TestCase(48, 8, 40 - 1, 16, 2)] - [TestCase(64 * 2 + 1, 0, 64 * 2 + 1 - 1, 64, 3)] - public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_WithFileName(int chainLength, int start, int end, int size, int expectedNumberOfFiles) + [TestCase(1, 0, 1 - 1, 1UL, 1)] + [TestCase(3, 0, 3 - 1, 1UL, 3)] + [TestCase(16, 0, 16 - 1, 16UL, 1)] + [TestCase(16, 0, 0, 16UL, 1)] + [TestCase(32, 0, 32 - 1, 16UL, 2)] + [TestCase(32, 8, 0, 16UL, 2)] + [TestCase(48, 8, 40 - 1, 16UL, 2)] + [TestCase(64 * 2 + 1, 0, 64 * 2 + 1 - 1, 64UL, 3)] + public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_WithFileName(int chainLength, int start, int end, ulong size, int expectedNumberOfFiles) { await using IContainer container = EraTestModule.BuildContainerBuilderWithBlockTreeOfLength(chainLength) .AddSingleton(new EraConfig() { MaxEra1Size = size }) diff --git a/src/Nethermind/Nethermind.Era1/EraConfig.cs b/src/Nethermind/Nethermind.Era1/EraConfig.cs index 09c249e8cc0b..eb3f2e0576fb 100644 --- a/src/Nethermind/Nethermind.Era1/EraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/EraConfig.cs @@ -10,7 +10,7 @@ public class EraConfig : IEraConfig public ulong From { get; set; } public ulong To { get; set; } public string? TrustedAccumulatorFile { get; set; } - public int MaxEra1Size { get; set; } = EraWriter.MaxEra1Size; + public ulong MaxEra1Size { get; set; } = EraWriter.MaxEra1Size; public string? NetworkName { get; set; } public int Concurrency { get; set; } public ulong ImportBlocksBufferSize { get; set; } = 1024 * 4; diff --git a/src/Nethermind/Nethermind.Era1/EraExporter.cs b/src/Nethermind/Nethermind.Era1/EraExporter.cs index 7184bc64da3e..144caca49c37 100644 --- a/src/Nethermind/Nethermind.Era1/EraExporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraExporter.cs @@ -27,7 +27,7 @@ public class EraExporter( : eraConfig.NetworkName.Trim().ToLower(); private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly int _era1Size = eraConfig.MaxEra1Size; + private readonly ulong _era1Size = eraConfig.MaxEra1Size; public const string AccumulatorFileName = "accumulators.txt"; public const string ChecksumsFileName = "checksums.txt"; @@ -62,7 +62,7 @@ private async Task DoExport( long totalProcessed = 0; // Cast to long is safe: epoch numbers are small ordinals (thousands at most). - ulong era1Size = (ulong)_era1Size; + ulong era1Size = _era1Size; ulong startEpoch = from / era1Size; // Ceiling division without floating point, all ulong. ulong epochCount = (to - from + era1Size) / era1Size; diff --git a/src/Nethermind/Nethermind.Era1/EraImporter.cs b/src/Nethermind/Nethermind.Era1/EraImporter.cs index 54c5e43506a2..cc77a18c9d8e 100644 --- a/src/Nethermind/Nethermind.Era1/EraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraImporter.cs @@ -32,7 +32,7 @@ public class EraImporter( { private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly int _maxEra1Size = eraConfig.MaxEra1Size; + private readonly ulong _maxEra1Size = eraConfig.MaxEra1Size; /// /// Snapshot of the pacer used by the current import run. @@ -138,7 +138,7 @@ private async Task ImportInternal( } // Earlier part can be parallelized - ulong partitionSize = (ulong)_maxEra1Size; + ulong partitionSize = _maxEra1Size; if (blockNumber + partitionSize < suggestFromBlock) { ConcurrentQueue partitionStartBlocks = new(); diff --git a/src/Nethermind/Nethermind.Era1/EraStore.cs b/src/Nethermind/Nethermind.Era1/EraStore.cs index 054731b53398..1e9e7bab23d8 100644 --- a/src/Nethermind/Nethermind.Era1/EraStore.cs +++ b/src/Nethermind/Nethermind.Era1/EraStore.cs @@ -38,7 +38,7 @@ public class EraStore : IEraStore private readonly ConcurrentDictionary _openedReader = new(); private bool _disposed = false; - private readonly int _maxEraFile; + private readonly ulong _maxEraFile; private int LastEpoch { get; set; } private int FirstEpoch { get; set; } = int.MaxValue; @@ -78,7 +78,7 @@ public EraStore( IBlockValidator blockValidator, IFileSystem fileSystem, string networkName, - int maxEraSize, + ulong maxEraSize, ISet? trustedAccumulators, string directory, int verifyConcurrency = 0 @@ -122,7 +122,7 @@ private long GetEpochNumber(ulong blockNumber) { // This seems to be the geth way of encoding blocks. // Cast to long is safe here: epoch numbers are small integers well within long range. - long epochOffset = (long)((blockNumber - FirstBlock) / (ulong)_maxEraFile); + long epochOffset = (long)((blockNumber - FirstBlock) / _maxEraFile); return FirstEpoch + epochOffset; } diff --git a/src/Nethermind/Nethermind.Era1/IEraConfig.cs b/src/Nethermind/Nethermind.Era1/IEraConfig.cs index f04754742124..657fd2434dec 100644 --- a/src/Nethermind/Nethermind.Era1/IEraConfig.cs +++ b/src/Nethermind/Nethermind.Era1/IEraConfig.cs @@ -23,7 +23,7 @@ public interface IEraConfig : IConfig string? TrustedAccumulatorFile { get; set; } [ConfigItem(Description = "Max era1 size.", DefaultValue = "8192", HiddenFromDocs = true)] - int MaxEra1Size { get; set; } + ulong MaxEra1Size { get; set; } [ConfigItem(Description = "Network name used for era directory naming. When null, it will imply from chain spec.", DefaultValue = "null", HiddenFromDocs = true)] string? NetworkName { get; set; } diff --git a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs index 4756aad34a5d..41a27c4db671 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs @@ -18,13 +18,13 @@ namespace Nethermind.EraE.Test.Export; public class EraExporterTests { - [TestCase(1, 0UL, 0UL, 1, 1)] - [TestCase(3, 0UL, 2UL, 1, 3)] - [TestCase(16, 0UL, 15UL, 16, 1)] - [TestCase(32, 0UL, 31UL, 16, 2)] - [TestCase(48, 8UL, 39UL, 16, 3)] + [TestCase(1, 0UL, 0UL, 1UL, 1)] + [TestCase(3, 0UL, 2UL, 1UL, 3)] + [TestCase(16, 0UL, 15UL, 16UL, 1)] + [TestCase(32, 0UL, 31UL, 16UL, 2)] + [TestCase(48, 8UL, 39UL, 16UL, 3)] public async Task Export_WithVaryingChainLength_CreatesCorrectNumberOfEpochFiles( - int chainLength, ulong from, ulong to, int eraSize, int expectedEraFiles) + int chainLength, ulong from, ulong to, ulong eraSize, int expectedEraFiles) { await using IContainer container = EraETestModule.BuildContainerBuilderWithBlockTreeOfLength(chainLength) .AddSingleton(new EraEConfig diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs index 10903ae5e7d8..35c574957eb7 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs @@ -156,7 +156,7 @@ public async Task FindBlockAndReceipts_WhenUnvalidatedReadPrecedesValidatedRead_ } private RemoteEraStoreDecorator CreateDecorator( - IEraStore? localStore, int maxEraSize, ISpecProvider? specProvider = null, + IEraStore? localStore, ulong maxEraSize, ISpecProvider? specProvider = null, IBlockValidator? blockValidator = null, ISet? trustedAccumulators = null) => new(localStore, _client, _downloadDir.Path, maxEraSize, specProvider ?? Substitute.For(), blockValidator ?? Always.Valid, trustedAccumulators); diff --git a/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs b/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs index 26918873fb27..48c9a27b84d1 100644 --- a/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs +++ b/src/Nethermind/Nethermind.EraE/Config/EraEConfig.cs @@ -12,7 +12,7 @@ public class EraEConfig : IEraEConfig public ulong From { get; set; } public ulong To { get; set; } public string? TrustedAccumulatorFile { get; set; } - public int MaxEraSize { get; set; } = EraWriter.MaxEraSize; + public ulong MaxEraSize { get; set; } = EraWriter.MaxEraSize; public string? NetworkName { get; set; } public int Concurrency { get; set; } public ulong ImportBlocksBufferSize { get; set; } = 4096; diff --git a/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs b/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs index 2f2a7cbe1820..d21644944086 100644 --- a/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs +++ b/src/Nethermind/Nethermind.EraE/Config/IEraEConfig.cs @@ -23,7 +23,7 @@ public interface IEraEConfig : IConfig string? TrustedAccumulatorFile { get; set; } [ConfigItem(Description = "Max number of blocks per era file.", DefaultValue = "8192", HiddenFromDocs = true)] - int MaxEraSize { get; set; } + ulong MaxEraSize { get; set; } [ConfigItem(Description = "Network name used for EraE directory naming. When null, inferred from chain spec.", DefaultValue = "null", HiddenFromDocs = true)] string? NetworkName { get; set; } diff --git a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs index ec0fd60c4b93..636c9a8d7425 100644 --- a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs +++ b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs @@ -35,7 +35,7 @@ public sealed class EraExporter( private readonly ILogger _logger = logManager.GetClassLogger(); private readonly ReceiptMessageDecoder _receiptDecoder = new(); - private readonly int _eraSize = eraConfig.MaxEraSize is > 0 and <= EraWriter.MaxEraSize + private readonly ulong _eraSize = eraConfig.MaxEraSize is > 0UL and <= (ulong)EraWriter.MaxEraSize ? eraConfig.MaxEraSize : throw new ArgumentException($"MaxEraSize must be between 1 and {EraWriter.MaxEraSize} (SLOTS_PER_HISTORICAL_ROOT). Got {eraConfig.MaxEraSize}."); @@ -72,8 +72,8 @@ private async Task DoExport(string destinationPath, ulong from, ulong to, Cancel using ProgressReporter progress = new("EraE export", logManager, to - from + 1); long totalProcessed = 0; - ulong startEpoch = from / (ulong)_eraSize; - ulong endEpoch = to / (ulong)_eraSize; + ulong startEpoch = from / _eraSize; + ulong endEpoch = to / _eraSize; ulong epochCount = endEpoch - startEpoch + 1; using ArrayPoolList epochIdxs = new((int)epochCount); @@ -115,9 +115,9 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) ulong epoch = startEpoch + (ulong)epochIdx; // Each epoch covers [epoch * eraSize, epoch * eraSize + eraSize - 1]. // Clamp to [from, to] to handle partial first and last epochs. - ulong epochBlockStart = epoch * (ulong)_eraSize; + ulong epochBlockStart = epoch * _eraSize; ulong writeFrom = Math.Max(epochBlockStart, from); - ulong writeTo = Math.Min(epochBlockStart + (ulong)_eraSize - 1, to); + ulong writeTo = Math.Min(epochBlockStart + _eraSize - 1, to); if (TrySkipExistingEpoch(destinationPath, epoch, idx, writeFrom, writeTo, accumulators, checksums, fileNames, cachedChecksums, cachedAccumulators, ref totalProcessed)) return; diff --git a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs index 5ef7e6bccb9e..6f97b90091af 100644 --- a/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs +++ b/src/Nethermind/Nethermind.EraE/Import/EraImporter.cs @@ -34,7 +34,7 @@ public sealed class EraImporter( : IEraImporter { private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly int _maxEraSize = eraConfig.MaxEraSize; + private readonly ulong _maxEraSize = eraConfig.MaxEraSize; public async Task Import(string src, ulong from, ulong to, string? accumulatorFile, CancellationToken cancellation = default) { @@ -108,7 +108,7 @@ private async Task ImportInternal(ulong from, ulong to, IEraStore eraStore, Canc } // Parallel historical import (blocks without state) - ulong partitionSize = (ulong)_maxEraSize; + ulong partitionSize = _maxEraSize; if (blockNumber + partitionSize < suggestFromBlock) { ConcurrentQueue partitionStartBlocks = new(); diff --git a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs index 64917758c23c..09f5e2bcd10f 100644 --- a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs +++ b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs @@ -37,7 +37,7 @@ public sealed class EraStore : IEraStore // Changed int → uint: era size is always a small positive count (e.g. 8192), // never negative, so uint is the honest type and avoids the (ulong) cast in // GetEpochNumber without overstating the range as ulong. - private readonly uint _maxEraSize; + private readonly ulong _maxEraSize; private readonly int _verifyConcurrency; private volatile bool _disposed; @@ -53,7 +53,7 @@ public EraStore( IBlockValidator blockValidator, IFileSystem fileSystem, string networkName, - int maxEraSize, + ulong maxEraSize, ISet? trustedAccumulators, string directory, int verifyConcurrency = 0, @@ -62,7 +62,7 @@ public EraStore( ArgumentNullException.ThrowIfNull(specProvider); ArgumentNullException.ThrowIfNull(blockValidator); ArgumentException.ThrowIfNullOrEmpty(networkName); - ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(maxEraSize, 0); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(maxEraSize, 0UL); _specProvider = specProvider; _blockValidator = blockValidator; @@ -70,7 +70,7 @@ public EraStore( _validator = validator; // Boundary cast — safe: validated > 0 immediately above, and era sizes // are small counts (e.g. 8192) that trivially fit in uint. - _maxEraSize = (uint)maxEraSize; + _maxEraSize = maxEraSize; _maxOpenFile = Environment.ProcessorCount * 2; _verifyConcurrency = verifyConcurrency == 0 ? Environment.ProcessorCount : verifyConcurrency; diff --git a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs index 3600e3a6a2bc..0abce1491db8 100644 --- a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs +++ b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs @@ -28,7 +28,7 @@ public sealed class RemoteEraStoreDecorator : IEraStore // Changed int → uint: era size is always a small positive count (e.g. 8192), // never negative, so uint is the honest type and avoids (ulong) casts in // epoch arithmetic. - private readonly uint _maxEraSize; + private readonly ulong _maxEraSize; private readonly ISpecProvider _specProvider; private readonly IBlockValidator _blockValidator; private readonly Proofs.Validator? _validator; @@ -63,7 +63,7 @@ public RemoteEraStoreDecorator( IEraStore? localStore, IRemoteEraClient client, string downloadDir, - int maxEraSize, + ulong maxEraSize, ISpecProvider specProvider, IBlockValidator blockValidator, ISet? trustedAccumulators = null, @@ -72,7 +72,7 @@ public RemoteEraStoreDecorator( { ArgumentNullException.ThrowIfNull(client); ArgumentException.ThrowIfNullOrWhiteSpace(downloadDir); - ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(maxEraSize, 0); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(maxEraSize, 0UL); ArgumentNullException.ThrowIfNull(specProvider); ArgumentNullException.ThrowIfNull(blockValidator); @@ -81,7 +81,7 @@ public RemoteEraStoreDecorator( _downloadDir = downloadDir; // Boundary cast — safe: validated > 0 immediately above, and era sizes // are small counts (e.g. 8192) that trivially fit in uint. - _maxEraSize = (uint)maxEraSize; + _maxEraSize = maxEraSize; _specProvider = specProvider; _blockValidator = blockValidator; _trustedAccumulators = trustedAccumulators; @@ -182,7 +182,7 @@ private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reade // The actual last block may be slightly lower for a non-full final epoch. // FindBlockAndReceipts returns (null, null) when number > reader.LastBlock, so importers that // rely on this value (to=0 / auto mode) will stop naturally at the real end. - return ((ulong)minEpoch * (ulong)_maxEraSize, (ulong)(maxEpoch + 1) * (ulong)_maxEraSize - 1); + return ((ulong)minEpoch * _maxEraSize, (ulong)(maxEpoch + 1) * _maxEraSize - 1); } private async Task> GetManifestAsync(CancellationToken cancellation = default) diff --git a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs index 3a13edf8afb8..cef48365a609 100644 --- a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs @@ -14,6 +14,9 @@ public static class BlobGasCalculator /// /// if the multiplication overflows; otherwise . public static bool TryCalculateBlobMaxFee(int blobCount, UInt256 maxFeePerBlobGas, out UInt256 blobFee) => + TryCalculateBlobMaxFee((ulong)blobCount, maxFeePerBlobGas, out blobFee); + + public static bool TryCalculateBlobMaxFee(ulong blobCount, UInt256 maxFeePerBlobGas, out UInt256 blobFee) => !UInt256.MultiplyOverflow((UInt256)blobCount * (UInt256)Eip4844Constants.GasPerBlob, maxFeePerBlobGas, out blobFee); public static bool TrySubtractBlobFee(IReleaseSpec spec, Transaction tx, ref UInt256 available) @@ -21,7 +24,7 @@ public static bool TrySubtractBlobFee(IReleaseSpec spec, Transaction tx, ref UIn if (!spec.IsEip4844Enabled || tx.BlobVersionedHashes?.Length is not > 0) return true; - if (!TryCalculateBlobMaxFee(tx.BlobVersionedHashes.Length, tx.MaxFeePerBlobGas ?? UInt256.Zero, out UInt256 blobFee) + if (!TryCalculateBlobMaxFee((ulong)tx.BlobVersionedHashes.Length, tx.MaxFeePerBlobGas ?? UInt256.Zero, out UInt256 blobFee) || blobFee > available) return false; @@ -30,19 +33,22 @@ public static bool TrySubtractBlobFee(IReleaseSpec spec, Transaction tx, ref UIn } public static ulong CalculateBlobGas(int blobCount) => - (ulong)blobCount * Eip4844Constants.GasPerBlob; + CalculateBlobGas((ulong)blobCount); + + public static ulong CalculateBlobGas(ulong blobCount) => + blobCount * Eip4844Constants.GasPerBlob; public static ulong CalculateBlobGas(Transaction transaction) => CalculateBlobGas(transaction.GetBlobCount()); public static ulong CalculateBlobGas(Transaction[] transactions) { - int blobCount = 0; + ulong blobCount = 0UL; foreach (Transaction tx in transactions) { if (tx.SupportsBlobs) { - blobCount += tx.BlobVersionedHashes!.Length; + blobCount += tx.GetBlobCount(); } } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 0b3866ba9bd2..7e8e4eb82903 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -383,17 +383,17 @@ public static void ResetForHalt(ref EthereumGasPolicy gas, ulong initialStateRes } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => - spec.IsEip8037Enabled || codeInsertRefunds <= 0 - ? 0 - : (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * (ulong)codeInsertRefunds; + public static ulong GetCodeInsertRegularRefund(ulong codeInsertRefunds, IReleaseSpec spec) => + spec.IsEip8037Enabled || codeInsertRefunds == 0UL + ? 0UL + : (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * codeInsertRefunds; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, int codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) + public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, ulong codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) { - if (codeInsertRefunds > 0 && spec.IsEip8037Enabled) + if (codeInsertRefunds > 0UL && spec.IsEip8037Enabled) { - ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * (ulong)codeInsertRefunds); + ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * codeInsertRefunds); ulong refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); RefundStateGas(ref gas, stateGasRefund, refundFloor, trackSpillRefund: false); } @@ -413,9 +413,9 @@ public static bool ConsumeCallValueTransfer(ref EthereumGasPolicy gas) }; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool ConsumeLogEmission(ref EthereumGasPolicy gas, long topicCount, long dataSize) + public static bool ConsumeLogEmission(ref EthereumGasPolicy gas, ulong topicCount, ulong dataSize) { - ulong cost = GasCostOf.Log + (ulong)topicCount * GasCostOf.LogTopic + (ulong)dataSize * GasCostOf.LogData; + ulong cost = GasCostOf.Log + topicCount * GasCostOf.LogTopic + dataSize * GasCostOf.LogData; return UpdateGas(ref gas, cost); } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs index ec54884a59f7..71ecdbf6c495 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs @@ -122,16 +122,16 @@ static virtual void RemoveStateGasRefundFromReservoir(ref TSelf gas, ulong amoun static virtual void ResetForHalt(ref TSelf gas, ulong initialStateReservoir, ulong initialStateGasUsed) { } // EIP-7702 code-insert refund regular-gas portion. Pre-EIP-8037: (NewAccount - PerAuthBaseCost) each. - static virtual ulong GetCodeInsertRegularRefund(int codeInsertRefunds, IReleaseSpec spec) => - codeInsertRefunds > 0 ? (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * (ulong)codeInsertRefunds : 0; + static virtual ulong GetCodeInsertRegularRefund(ulong codeInsertRefunds, IReleaseSpec spec) => + codeInsertRefunds > 0UL ? (GasCostOf.NewAccount - GasCostOf.PerAuthBaseCost) * codeInsertRefunds : 0UL; // EIP-8037: replenishes tx state reservoir before exec (intrinsic state gas already charged). - static virtual ulong ApplyCodeInsertRefunds(ref TSelf gas, int codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) => + static virtual ulong ApplyCodeInsertRefunds(ref TSelf gas, ulong codeInsertRefunds, IReleaseSpec spec, ulong stateGasFloor) => TSelf.GetCodeInsertRegularRefund(codeInsertRefunds, spec); static abstract bool ConsumeCallValueTransfer(ref TSelf gas); static abstract bool ConsumeNewAccountCreation(ref TSelf gas) where TEip8037 : struct, IFlag; - static abstract bool ConsumeLogEmission(ref TSelf gas, long topicCount, long dataSize); + static abstract bool ConsumeLogEmission(ref TSelf gas, ulong topicCount, ulong dataSize); static abstract TSelf Max(in TSelf a, in TSelf b); static virtual IntrinsicGas CalculateIntrinsicGas(Transaction tx, IReleaseSpec spec) => diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Stack.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Stack.cs index 9ab7cea6f20d..e7c4620ca85a 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Stack.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Stack.cs @@ -1087,12 +1087,12 @@ public static EvmExceptionType InstructionLog(VirtualMachi if (!stack.PopUInt256(out UInt256 position, out UInt256 length)) goto StackUnderflow; // The number of topics is defined by the generic parameter. - long topicsCount = TOpCount.Count; + ulong topicsCount = (ulong)TOpCount.Count; // Ensure that the memory expansion for the log data is accounted for. if (!TGasPolicy.UpdateMemoryCost(ref gas, in position, length, vmState)) goto OutOfGas; // Deduct gas for the log entry itself, including per-topic and per-byte data costs. - long dataSize = (long)length; + ulong dataSize = (ulong)length; if (!TGasPolicy.ConsumeLogEmission(ref gas, topicsCount, dataSize)) goto OutOfGas; // Load the log data from memory. diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index fff31dc3a013..a2c612f191a6 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -284,8 +284,8 @@ private TransactionResult ExecuteEvmTransaction( if (tx.IsContractCreation) Metrics.IncrementCreates(); // substate.Logs contains a reference to accessTracker.Logs so we can't Dispose until end of the method using StackAccessTracker accessTracker = new(tracer.IsTracingAccess); - int delegationRefunds = 0; - int delegationAuthBaseRefunds = 0; + ulong delegationRefunds = 0UL; + ulong delegationAuthBaseRefunds = 0UL; TransactionResult result; if (!(result = Validate8037DelegationRefundBounds(tx, spec, in gasAvailable))) return result; @@ -585,8 +585,8 @@ private TransactionResult Apply8037DelegationRefunds( IReleaseSpec spec, in IntrinsicGas intrinsicGas, ref TGasPolicy gasAvailable, - ref int delegationRefunds, - ref int delegationAuthBaseRefunds) + ref ulong delegationRefunds, + ref ulong delegationAuthBaseRefunds) { if (spec.IsEip8037Enabled && (delegationRefunds > 0 || delegationAuthBaseRefunds > 0)) { @@ -629,8 +629,8 @@ private TransactionResult Validate8037DelegationRefundBounds(Transaction tx, IRe if (!TryCalculate8037DelegationRefund( newAccountStateCost, perAuthBaseStateCost, - maxRefunds, - maxRefunds, + (ulong)maxRefunds, + (ulong)maxRefunds, out _)) { TraceLogInvalidTx(tx, "AUTHORIZATION_REFUND_OVERFLOW"); @@ -643,24 +643,20 @@ private TransactionResult Validate8037DelegationRefundBounds(Transaction tx, IRe private static bool TryCalculate8037DelegationRefund( ulong newAccountStateCost, ulong perAuthBaseStateCost, - int delegationRefunds, - int delegationAuthBaseRefunds, + ulong delegationRefunds, + ulong delegationAuthBaseRefunds, out ulong stateGasRefund) { stateGasRefund = 0; - if (delegationRefunds < 0 || delegationAuthBaseRefunds < 0) - { - return false; - } - if ((delegationRefunds != 0 && newAccountStateCost > ulong.MaxValue / (ulong)delegationRefunds) || - (delegationAuthBaseRefunds != 0 && perAuthBaseStateCost > ulong.MaxValue / (ulong)delegationAuthBaseRefunds)) + if ((delegationRefunds != 0UL && newAccountStateCost > ulong.MaxValue / delegationRefunds) || + (delegationAuthBaseRefunds != 0UL && perAuthBaseStateCost > ulong.MaxValue / delegationAuthBaseRefunds)) { return false; } - ulong newAccountStateRefund = newAccountStateCost * (ulong)delegationRefunds; - ulong authBaseStateRefund = perAuthBaseStateCost * (ulong)delegationAuthBaseRefunds; + ulong newAccountStateRefund = newAccountStateCost * delegationRefunds; + ulong authBaseStateRefund = perAuthBaseStateCost * delegationAuthBaseRefunds; if (newAccountStateRefund > ulong.MaxValue - authBaseStateRefund) { return false; @@ -671,12 +667,12 @@ private static bool TryCalculate8037DelegationRefund( } [MethodImpl(MethodImplOptions.NoInlining)] - private int ProcessDelegations(Transaction tx, IReleaseSpec spec, in StackAccessTracker accessTracker, out int authBaseRefunds) + private ulong ProcessDelegations(Transaction tx, IReleaseSpec spec, in StackAccessTracker accessTracker, out ulong authBaseRefunds) { Debug.Assert(spec.IsEip7702Enabled && tx.HasAuthorizationList); - int refunds = 0; - authBaseRefunds = 0; + ulong refunds = 0UL; + authBaseRefunds = 0UL; foreach (AuthorizationTuple authTuple in tx.AuthorizationList) { Address authority = (authTuple.Authority ??= Ecdsa.RecoverAddress(authTuple))!; @@ -1175,7 +1171,7 @@ private int ExecuteEvmCall( IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts, - int delegationRefunds, + ulong delegationRefunds, IntrinsicGas gas, in StackAccessTracker accessedItems, TGasPolicy gasAvailable, @@ -1538,7 +1534,7 @@ protected void TraceLogInvalidTx(Transaction transaction, string reason) } protected virtual GasConsumed Refund(Transaction tx, BlockHeader header, IReleaseSpec spec, ExecutionOptions opts, - in TransactionSubstate substate, in TGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in TGasPolicy floorGas, in TGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) + in TransactionSubstate substate, in TGasPolicy unspentGas, in UInt256 gasPrice, ulong codeInsertRefunds, in TGasPolicy floorGas, in TGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) { TGasPolicy gasAfterExecution = unspentGas; ulong stateGasFloor = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); diff --git a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs index 927960aaa8b3..6851d24fd459 100644 --- a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs +++ b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs @@ -193,10 +193,10 @@ public async Task Prunes_history( CheckOldestAndCutoff(expectedPruneBelow, finalCutoff, historyPruner); } - [TestCase(0L, 0L)] - [TestCase(1L, 32L)] - [TestCase(82125L, 2_628_000L)] // mainnet EIP-4444 default - public async Task GetRetentionBlocks_converts_epochs_to_blocks(long retentionEpochs, long expected) + [TestCase(0UL, 0UL)] + [TestCase(1UL, 32UL)] + [TestCase(82125UL, 2_628_000UL)] // mainnet EIP-4444 default + public async Task GetRetentionBlocks_converts_epochs_to_blocks(ulong retentionEpochs, ulong expected) { IHistoryConfig historyConfig = new HistoryConfig { Pruning = PruningModes.Disabled, PruningInterval = 0 }; using BasicTestBlockchain testBlockchain = await CreateBlockchainWithBlocks(historyConfig, blocks: 0); diff --git a/src/Nethermind/Nethermind.History/HistoryPruner.cs b/src/Nethermind/Nethermind.History/HistoryPruner.cs index 77f54c162de2..a487e4190129 100644 --- a/src/Nethermind/Nethermind.History/HistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/HistoryPruner.cs @@ -26,9 +26,9 @@ namespace Nethermind.History; public class HistoryPruner : IHistoryPruner { private const int LockWaitTimeoutMs = 100; - private const int SlotsPerEpoch = 32; + private const ulong SlotsPerEpoch = 32; - public long GetRetentionBlocks(long retentionEpochs) => retentionEpochs * SlotsPerEpoch; + public ulong GetRetentionBlocks(ulong retentionEpochs) => retentionEpochs * SlotsPerEpoch; private readonly object _pruneLock = new(); @@ -89,8 +89,7 @@ public HistoryPruner( _backgroundTaskScheduler = backgroundTaskScheduler; _historyConfig = historyConfig; _enabled = historyConfig.Enabled(); - // SlotsPerEpoch is int; promote to ulong before multiply. - _pruningInterval = historyConfig.PruningInterval * (ulong)SlotsPerEpoch; + _pruningInterval = historyConfig.PruningInterval * SlotsPerEpoch; _minHistoryRetentionEpochs = specProvider.GenesisSpec.MinHistoryRetentionEpochs; _minBalRetentionEpochs = specProvider.GenesisSpec.MinBalRetentionEpochs; _minDeletableBlockNumber = (_blockTree.Genesis?.Number ?? 0) + 1; // do not remove genesis diff --git a/src/Nethermind/Nethermind.History/IHistoryPruner.cs b/src/Nethermind/Nethermind.History/IHistoryPruner.cs index 22969c7726fa..3d8651aef6d6 100644 --- a/src/Nethermind/Nethermind.History/IHistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/IHistoryPruner.cs @@ -24,5 +24,5 @@ public interface IHistoryPruner /// Converts a retention window expressed in epochs to a block count using this pruner's /// slots-per-epoch constant. Keeps the epoch→blocks conversion co-located with the pruner. ///
- long GetRetentionBlocks(long retentionEpochs); + ulong GetRetentionBlocks(ulong retentionEpochs); } diff --git a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs index 2991643a272c..f7d9aea04e0f 100644 --- a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs +++ b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs @@ -148,8 +148,8 @@ ILogManager logManager IPruningStrategy pruningStrategy = Prune .WhenCacheReaches(pruningConfig.DirtyCacheMb.MB) .WhenPersistedCacheReaches(pruningConfig.CacheMb.MB - pruningConfig.DirtyCacheMb.MB) - .WhenLastPersistedBlockIsTooOld((ulong)pruningConfig.MaxUnpersistedBlockCount, pruningConfig.PruningBoundary) - .UnlessLastPersistedBlockIsTooNew((ulong)pruningConfig.MinUnpersistedBlockCount, pruningConfig.PruningBoundary); + .WhenLastPersistedBlockIsTooOld(pruningConfig.MaxUnpersistedBlockCount, pruningConfig.PruningBoundary) + .UnlessLastPersistedBlockIsTooNew(pruningConfig.MinUnpersistedBlockCount, pruningConfig.PruningBoundary); if (!pruningConfig.Mode.IsMemory()) { @@ -164,9 +164,9 @@ ILogManager logManager INodeStorage mainNodeStorage = nodeStorageFactory.WrapKeyValueStore(stateDb); - if (pruningConfig.SimulateLongFinalizationDepth != 0) + if (pruningConfig.SimulateLongFinalizationDepth != 0UL) { - finalizedStateProvider = new DelayedFinalizedStateProvider(finalizedStateProvider, blockTree, (ulong)pruningConfig.SimulateLongFinalizationDepth); + finalizedStateProvider = new DelayedFinalizedStateProvider(finalizedStateProvider, blockTree, pruningConfig.SimulateLongFinalizationDepth); } PruningTrieStore = new TrieStore( diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs index b9c192898185..4094630a2cc5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs @@ -61,7 +61,7 @@ private static IHistoryPruner MockHistoryPruner(ulong oldestBlockNumber) { IHistoryPruner pruner = Substitute.For(); pruner.OldestBlockHeader.Returns(Build.A.BlockHeader.WithNumber(oldestBlockNumber).TestObject); - pruner.GetRetentionBlocks(Arg.Any()).Returns(call => (long)call[0] * 32); + pruner.GetRetentionBlocks(Arg.Any()).Returns(call => (ulong)call[0] * 32UL); return pruner; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs index ca858daf9661..40e829b3f65e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs @@ -41,7 +41,7 @@ public EthCapabilities GetCapabilities() ulong historyFloor = historyPruner.OldestBlockHeader?.Number ?? 0ul; DeleteStrategy? historyWindow = BuildWindow( - historyConfig.Pruning == PruningModes.Rolling ? historyPruner.GetRetentionBlocks(historyConfig.RetentionEpochs) : 0); + historyConfig.Pruning == PruningModes.Rolling ? (long)historyPruner.GetRetentionBlocks(historyConfig.RetentionEpochs) : 0L); ulong lowestReceipt = Math.Max(syncPointers.LowestInsertedReceiptBlockNumber ?? 0ul, receiptsBarrier); ulong lowestBody = Math.Max(syncPointers.LowestInsertedBodyNumber ?? 0ul, bodiesBarrier); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index 038c46fbe12e..698acd6c1912 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -83,7 +83,7 @@ public override Task processing_block_should_serialize_valid_responses(string bl public override async Task Should_process_block_as_expected_V6(string latestValidHash, string blockHash, string stateRoot, string payloadId, string? customWithdrawalContractAddress) => await base.Should_process_block_as_expected_V6(latestValidHash, blockHash, stateRoot, payloadId, customWithdrawalContractAddress); - [TestCase("0x14d7d22cfaa851f3b79a790d6f961f0cc4da2e714cd15b16bce8468f25152911", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0x3e98244425fbc5413150a01fd823bece9ae66ef182f11597f0abdfd251d9aa16", false, false)] + [TestCase("0xff020d96d1b4a772fbaae047f094eced81b15ccb1ed9b538c90ab75f4f39742d", "0xac3989a5349b5efc7f2f6847e76c4d6d4c5fcbf54939c80b05b57142ae1236fb", "0xa666ed23428011d2a577df5a065c19861495f61e8d5d4c6298fbe2d34c211059", false, false)] public override async Task NewPayloadV5_accepts_valid_BAL(string? blockHash, string? receiptsRoot, string? stateRoot, bool eip8037Enabled, bool useEnginePipeline) => await NewPayloadV5_via_manual_block(blockHash, receiptsRoot, stateRoot, customWithdrawalContractAddress: _auraWithdrawalContractAddress); @@ -98,10 +98,10 @@ public override async Task NewPayloadV5_accepts_valid_BAL(string? blockHash, str public override Task NewPayloadV5_rejects_invalid_BAL_after_processing(string blockHash, string stateRoot, string invalidBalHash, string expectedBalHash, string? customWithdrawalContractAddress) => base.NewPayloadV5_rejects_invalid_BAL_after_processing(blockHash, stateRoot, invalidBalHash, expectedBalHash, customWithdrawalContractAddress); - [TestCase("0x5ab84199bdbe0d5806de6bffbbd52cf31ede2248f842395aa9a850a45ad9f4db", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.IncorrectChange)] - [TestCase("0x56f188e232e95462ad7235ca53b336f5f73cc208992d307033210c085ea6f959", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.MissingChange)] - [TestCase("0x1625b8215c5d6ab493105efb8cc20b7409d4957ca46d98996c6cc01e50b69ab3", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusChange)] - [TestCase("0x91e03d0f1b756f6577cab73c9f910f9b18fbe45ac27bb346ada0fa912a71dac8", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusReads)] + [TestCase("0xf23d9e6ccefd3f1223c05cff771c8e733040202871992257c8257cb629d95ee2", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.IncorrectChange)] + [TestCase("0x1b5f2d1e50a4c6322dff93847871a743b6d11c8e7b5218cc9547fe377709561f", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.MissingChange)] + [TestCase("0xe4a4bcd80d82527450d8ced83aa14aa0851d52618fa491bd4218d31c7257f00d", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusChange)] + [TestCase("0x4d85109195f43e0c29ba4d0a403081948fe0e29d0aa57379fc61fe4cea2820ac", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusReads)] public override Task NewPayloadV5_rejects_invalid_BAL_early(string? blockHash, string? receiptsRoot, string? stateRoot, bool eip8037Enabled, bool useEnginePipeline, BalErrorKind errorKind) => NewPayloadV5_via_manual_block(blockHash, receiptsRoot, stateRoot, GetExpectedBalError(errorKind), errorKind, customWithdrawalContractAddress: _auraWithdrawalContractAddress); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs index 4f34ea6dc17a..c78bff22759c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs @@ -350,13 +350,13 @@ private void LogProductionResult(Task t, Block currentBestBlock, UInt256 Block? block = t.Result; if (block is not null && !ReferenceEquals(block, currentBestBlock)) { - int blobs = 0; + ulong blobs = 0UL; int blobTx = 0; UInt256 gas = 0; foreach (Transaction tx in block.Transactions) { - int blobCount = tx.GetBlobCount(); - if (blobCount > 0) + ulong blobCount = tx.GetBlobCount(); + if (blobCount > 0UL) { blobs += blobCount; blobTx++; @@ -364,7 +364,7 @@ private void LogProductionResult(Task t, Block currentBestBlock, UInt256 gas += tx.SpentGas * premiumPerGas; } } - _logger.Info($" Produced {blockFees.ToDecimal(null) / weiToEth,6:N4}{BlocksConfig.GasTokenTicker,4} {block.ToString(block.Difficulty != 0 ? Block.Format.HashNumberDiffAndTx : Block.Format.HashNumberMGasAndTx)} | {time.TotalMilliseconds,8:N2} ms {((blobs > 0) ? $"{blobs,2:N0} blobs in {blobTx,2:N0} tx @ {(decimal)gas / weiToGwei,7:N0} gwei" : "")}"); + _logger.Info($" Produced {blockFees.ToDecimal(null) / weiToEth,6:N4}{BlocksConfig.GasTokenTicker,4} {block.ToString(block.Difficulty != 0 ? Block.Format.HashNumberDiffAndTx : Block.Format.HashNumberMGasAndTx)} | {time.TotalMilliseconds,8:N2} ms {((blobs > 0UL) ? $"{blobs,2:N0} blobs in {blobTx,2:N0} tx @ {(decimal)gas / weiToGwei,7:N0} gwei" : "")}"); } else { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs index 3871f06deb10..66ff4c78548d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs @@ -20,7 +20,7 @@ public BlobsBundleV1(Block block) int blobsCount = 0; foreach (Transaction? tx in block.Transactions) { - blobsCount += tx?.GetBlobCount() ?? 0; + blobsCount += (int)(tx?.GetBlobCount() ?? 0UL); } Commitments = new byte[blobsCount][]; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs index f24b29f65f8e..832b28858d03 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs @@ -23,7 +23,7 @@ public BlobsBundleV2(Block block) int blobsCount = 0; foreach (Transaction? tx in block.Transactions) { - blobsCount += tx?.GetBlobCount() ?? 0; + blobsCount += (int)(tx?.GetBlobCount() ?? 0UL); } Commitments = new byte[blobsCount][]; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/GC/GCKeeper.cs b/src/Nethermind/Nethermind.Merge.Plugin/GC/GCKeeper.cs index 46d28d5e891a..8ef426960e71 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/GC/GCKeeper.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/GC/GCKeeper.cs @@ -175,10 +175,10 @@ private async Task ScheduleGCInternal() if (GCSettings.LatencyMode != GCLatencyMode.NoGCRegion) { ulong forcedGcCount = Interlocked.Increment(ref _forcedGcCount); - int collectionsPerDecommit = _gcStrategy.CollectionsPerDecommit; + ulong collectionsPerDecommit = _gcStrategy.CollectionsPerDecommit; GCCollectionMode mode = GCCollectionMode.Forced; - if (collectionsPerDecommit == 0 || (forcedGcCount % (ulong)collectionsPerDecommit == 0)) + if (collectionsPerDecommit == 0 || (forcedGcCount % collectionsPerDecommit == 0)) { // Also decommit memory back to O/S mode = GCCollectionMode.Aggressive; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/GC/IGCStrategy.cs b/src/Nethermind/Nethermind.Merge.Plugin/GC/IGCStrategy.cs index d71d267db7fb..099978574cfe 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/GC/IGCStrategy.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/GC/IGCStrategy.cs @@ -7,7 +7,7 @@ namespace Nethermind.Merge.Plugin.GC; public interface IGCStrategy { - int CollectionsPerDecommit { get; } + ulong CollectionsPerDecommit { get; } int PostBlockDelayMs { get; } bool CanStartNoGCRegion(); (GcLevel Generation, GcCompaction Compacting) GetForcedGCParams(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/GC/NoGCStrategy.cs b/src/Nethermind/Nethermind.Merge.Plugin/GC/NoGCStrategy.cs index 043b09109d8a..8cf49828d1af 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/GC/NoGCStrategy.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/GC/NoGCStrategy.cs @@ -6,7 +6,7 @@ namespace Nethermind.Merge.Plugin.GC; public class NoGCStrategy : IGCStrategy { public static readonly NoGCStrategy Instance = new(); - public int CollectionsPerDecommit => -1; + public ulong CollectionsPerDecommit => 0UL; public int PostBlockDelayMs => 0; public bool CanStartNoGCRegion() => false; public (GcLevel Generation, GcCompaction Compacting) GetForcedGCParams() => (GcLevel.NoGC, GcCompaction.No); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/GC/NoSyncGcRegionStrategy.cs b/src/Nethermind/Nethermind.Merge.Plugin/GC/NoSyncGcRegionStrategy.cs index 3aee165f6e62..48f3e82590bb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/GC/NoSyncGcRegionStrategy.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/GC/NoSyncGcRegionStrategy.cs @@ -23,7 +23,7 @@ public NoSyncGcRegionStrategy(ISyncModeSelector syncModeSelector, IMergeConfig m PostBlockDelayMs = mergeConfig.PostBlockGcDelayMs ?? (int)((mergeConfig.SecondsPerSlot * 1000) / 8); } - public int CollectionsPerDecommit { get; } + public ulong CollectionsPerDecommit { get; } public int PostBlockDelayMs { get; } public bool CanStartNoGCRegion() => _canStartNoGCRegion && _syncModeSelector.Current == SyncMode.WaitingForBlock; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs b/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs index 7f1d62f47133..d9bd3fe6e19c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IMergeConfig.cs @@ -62,7 +62,7 @@ The number of requests to the garbage collector (GC) to release the process memo """, DefaultValue = "25")] - public int CollectionsPerDecommit { get; set; } + public ulong CollectionsPerDecommit { get; set; } [ConfigItem(Description = "The timeout, in milliseconds, for the `engine_newPayload` method.", DefaultValue = "7000", HiddenFromDocs = true)] public int NewPayloadBlockProcessingTimeout { get; set; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs index 806a465e3b2e..65c1fa0c0073 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergeConfig.cs @@ -29,7 +29,7 @@ public class MergeConfig : IMergeConfig public GcCompaction CompactMemory { get; set; } = GcCompaction.Yes; - public int CollectionsPerDecommit { get; set; } = 25; + public ulong CollectionsPerDecommit { get; set; } = 25; public const int DefaultNewPayloadBlockProcessingTimeout = 7000; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs index 406406ea2d2b..a35a7a769090 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs @@ -35,15 +35,18 @@ public sealed class ReceiptMessageDecoder69(bool skipStateAndStatus = false) : R if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; + // safe: DecodePositiveLong guarantees a non-negative result txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); } else if (firstItem.Length is >= 1 and <= 4) { + // safe: ToPositiveLong guarantees a non-negative result txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Hash256(firstItem); + // safe: DecodePositiveLong guarantees a non-negative result txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs index d792654304f9..d654b072ea0f 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs @@ -37,6 +37,7 @@ protected override OptimismTxReceipt DecodeInternal(ref Rlp.ValueDecoderContext } else if (firstItem.Length is >= 1 and <= 4) { + // safe: ToPositiveLong guarantees a non-negative result txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 3a04b726144b..89e9e57094c3 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -174,7 +174,7 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec } protected override GasConsumed Refund(Transaction tx, BlockHeader header, IReleaseSpec spec, ExecutionOptions opts, - in TransactionSubstate substate, in EthereumGasPolicy unspentGas, in UInt256 gasPrice, int codeInsertRefunds, in EthereumGasPolicy floorGas, in EthereumGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) + in TransactionSubstate substate, in EthereumGasPolicy unspentGas, in UInt256 gasPrice, ulong codeInsertRefunds, in EthereumGasPolicy floorGas, in EthereumGasPolicy intrinsicGasStandard, ulong postIntrinsicStateReservoir) { // if deposit: skip refunds, skip tipping coinbase // Regolith changes this behaviour to report the actual gasUsed instead of always reporting all gas used. diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark.Test/GasColumnProviderTests.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark.Test/GasColumnProviderTests.cs index c93d926bb6dc..83ee270987e5 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark.Test/GasColumnProviderTests.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark.Test/GasColumnProviderTests.cs @@ -11,7 +11,7 @@ public class GasColumnProviderTests [Test] public void Lower_throughput_bound_is_less_than_upper_throughput_bound() { - long gas = 100_000; + ulong gas = 100_000; double[] samples = [900, 920, 950, 970, 980, 1000, 1000, 1010, 1020, 1050, 1080, 1100]; Statistics stats = new(samples); diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/GasColumnProvider.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/GasColumnProvider.cs index 98381370f276..d0e862cc5b59 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/GasColumnProvider.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/GasColumnProvider.cs @@ -30,12 +30,12 @@ public class GasColumnProvider : IColumnProvider /// /// Converts gas consumed and execution time into MGas/s throughput. /// - internal static double CalculateMGasThroughput(long gas, double nanoseconds) => gas * 1000.0 / nanoseconds; + internal static double CalculateMGasThroughput(ulong gas, double nanoseconds) => gas * 1000.0 / nanoseconds; /// /// Computes the MGas/s throughput for a given Benchmark Statistics. /// - internal static double GetThroughputBound(long gas, Statistics stats, bool isLowerBound) + internal static double GetThroughputBound(ulong gas, Statistics stats, bool isLowerBound) { ConfidenceInterval ci = stats.GetConfidenceInterval(ConfidenceLevel.L99); // BDN's CI is in nanoseconds; throughput = gas/time is inversely proportional, @@ -56,12 +56,12 @@ private abstract class BaseGasColumn : IColumn public abstract string ColumnName { get; } public abstract string Legend { get; } - protected static (long? gas, Statistics? stats) GetBenchmarkData(Summary summary, BenchmarkCase benchmarkCase) + protected static (ulong? gas, Statistics? stats) GetBenchmarkData(Summary summary, BenchmarkCase benchmarkCase) { BenchmarkDotNet.Parameters.ParameterInstance? inputParam = benchmarkCase.Parameters.Items.FirstOrDefault(p => p.Name == "Input"); - long? gas = inputParam?.Value is PrecompileBenchmarkBase.Param precompileInput + ulong? gas = inputParam?.Value is PrecompileBenchmarkBase.Param precompileInput ? precompileInput.Gas(Cancun.Instance) - : (long?)null; + : (ulong?)null; Statistics? stats = summary.Reports.FirstOrDefault(r => r.BenchmarkCase == benchmarkCase)?.ResultStatistics; return (gas, stats); } @@ -87,7 +87,7 @@ private class GasColumn : BaseGasColumn public override string GetValue(Summary summary, BenchmarkCase benchmarkCase) { - (long? gas, Statistics? _) = GetBenchmarkData(summary, benchmarkCase); + (ulong? gas, Statistics? _) = GetBenchmarkData(summary, benchmarkCase); return gas?.ToString() ?? "N/A"; } } @@ -100,7 +100,7 @@ private class GasThroughputColumn : BaseGasColumn public override string GetValue(Summary summary, BenchmarkCase benchmarkCase) { - (long? gas, Statistics? stats) = GetBenchmarkData(summary, benchmarkCase); + (ulong? gas, Statistics? stats) = GetBenchmarkData(summary, benchmarkCase); if (gas is null || stats?.Mean is null) { @@ -120,7 +120,7 @@ private class GasConfidenceIntervalColumn(bool isLower) : BaseGasColumn public override string GetValue(Summary summary, BenchmarkCase benchmarkCase) { - (long? gas, Statistics? stats) = GetBenchmarkData(summary, benchmarkCase); + (ulong? gas, Statistics? stats) = GetBenchmarkData(summary, benchmarkCase); if (gas is null || stats?.Mean is null) { diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/PrecompileBenchmarkBase.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/PrecompileBenchmarkBase.cs index 1e1f793e6586..4ce71ec51d27 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/PrecompileBenchmarkBase.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/PrecompileBenchmarkBase.cs @@ -33,7 +33,7 @@ public readonly struct Param(IPrecompile precompile, string name, byte[] bytes, public string Name { get; } = name; - public long Gas(IReleaseSpec releaseSpec) => + public ulong Gas(IReleaseSpec releaseSpec) => precompile.BaseGasCost(releaseSpec) + precompile.DataGasCost(Bytes, releaseSpec); public override string ToString() => Name; diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs index 8757306c10b3..4b91dea1eeb5 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs @@ -42,6 +42,7 @@ protected override TxReceipt DecodeInternal(ref Rlp.ValueDecoderContext ctx, Rlp } else if (firstItem.Length is >= 1 and <= 4) { + // safe: ToPositiveLong guarantees a non-negative result txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); } else diff --git a/src/Nethermind/Nethermind.Stateless.Executor/StatelessSpecProvider.cs b/src/Nethermind/Nethermind.Stateless.Executor/StatelessSpecProvider.cs index d6cd0e22641a..afeba8d80da8 100644 --- a/src/Nethermind/Nethermind.Stateless.Executor/StatelessSpecProvider.cs +++ b/src/Nethermind/Nethermind.Stateless.Executor/StatelessSpecProvider.cs @@ -29,7 +29,7 @@ internal sealed class StatelessSpecProvider( public IReleaseSpec GenesisSpec => baseProvider.GenesisSpec; - public long? DaoBlockNumber => baseProvider.DaoBlockNumber; + public ulong? DaoBlockNumber => baseProvider.DaoBlockNumber; public ulong? BeaconChainGenesisTimestamp => baseProvider.BeaconChainGenesisTimestamp; @@ -44,7 +44,7 @@ internal sealed class StatelessSpecProvider( public IReleaseSpec GetSpec(ForkActivation activation) => activation >= activeForkActivation ? activeForkSpec : baseProvider.GetSpec(activation); - public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null) => + public void UpdateMergeTransitionInfo(ulong? blockNumber, UInt256? terminalTotalDifficulty = null) => baseProvider.UpdateMergeTransitionInfo(blockNumber, terminalTotalDifficulty); public static StatelessSpecProvider Create(IForkAwareSpecProvider baseProvider, ForkConfig forkConfig) @@ -65,6 +65,6 @@ private sealed class StatelessReleaseSpec(IReleaseSpec spec, BlobSchedule blobSc { public override ulong TargetBlobCount => blobSchedule.Target; public override ulong MaxBlobCount => blobSchedule.Max; - public override UInt256 BlobBaseFeeUpdateFraction => new(blobSchedule.BaseFeeUpdateFraction); + public override ulong BlobBaseFeeUpdateFraction => blobSchedule.BaseFeeUpdateFraction; } } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs index f11c05f7e754..ebb724300175 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/ByTotalDifficultyPeerAllocationStrategy.cs @@ -12,9 +12,9 @@ namespace Nethermind.Synchronization.Blocks { - public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPeerAllocationStrategy + public class ByTotalDifficultyPeerAllocationStrategy(ulong? minBlocksAhead) : IPeerAllocationStrategy { - private readonly long? _minBlocksAhead = minBlocksAhead; + private readonly ulong? _minBlocksAhead = minBlocksAhead; private const decimal MinDiffPercentageForSpeedSwitch = 0.10m; private const int MinDiffForSpeedSwitch = 10; @@ -54,7 +54,7 @@ public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPe if (_minBlocksAhead is not null) { - if (info.HeadNumber < (blockTree.BestSuggestedHeader?.Number ?? 0UL) + (ulong)_minBlocksAhead) + if (info.HeadNumber < (blockTree.BestSuggestedHeader?.Number ?? 0UL) + _minBlocksAhead.Value) { // we need to be able to download some blocks ahead continue; @@ -98,7 +98,7 @@ public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPe return fastestPeer.Info; } - const int minBlocksDiff = 16; + const ulong minBlocksDiff = 16; averageSpeed /= peersCount; if (bestDiffPeer.Info.TotalDifficulty is { } bestPeerTD) // Try to compare by TD if present @@ -126,7 +126,7 @@ public class ByTotalDifficultyPeerAllocationStrategy(long? minBlocksAhead) : IPe // at least 16 blocks if (blockDifference > 0 - && (blockDifference >= localNumber + (ulong)minBlocksDiff + && (blockDifference >= localNumber + minBlocksDiff || bestDiffPeer.TransferSpeed > averageSpeed)) { return bestDiffPeer.Info; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 4afe09a665b6..98ffdd55db43 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -40,8 +40,8 @@ private ulong ComputeBarrier(ulong pivotNumber) private readonly FastBlocksAllocationStrategy _approximateAllocationStrategy = new(TransferSpeedType.Bodies, 0, true); - private const long DefaultFlushDbInterval = 100000; // About every 10GB on mainnet - private readonly long _flushDbInterval; // About every 10GB on mainnet + private const ulong DefaultFlushDbInterval = 100000; // About every 10GB on mainnet + private readonly ulong _flushDbInterval; // About every 10GB on mainnet private readonly IBlockTree _blockTree; private readonly IBlockValidator _blockValidator; @@ -73,7 +73,7 @@ public BodiesSyncFeed( [KeyFilter(DbNames.Blocks)] IDb blocksDb, [KeyFilter(DbNames.Metadata)] IDb metadataDb, ILogManager logManager, - long flushDbInterval = DefaultFlushDbInterval) + ulong flushDbInterval = DefaultFlushDbInterval) : base(metadataDb, specProvider, logManager.GetClassLogger()) { _blockTree = blockTree; @@ -173,7 +173,7 @@ private void PostFinishCleanUp() } if ( - (_syncPointers.LowestInsertedBodyNumber ?? ulong.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > (ulong)_flushDbInterval || + (_syncPointers.LowestInsertedBodyNumber ?? ulong.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval || _syncStatusList.LowestInsertWithoutGaps <= _barrier // Other state depends on LowestInsertedBodyNumber, so this need to flush or it wont finish ) { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksPriorities.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksPriorities.cs index 0b6bafe41e87..9e3dcd6c97bc 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksPriorities.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlocksPriorities.cs @@ -9,6 +9,6 @@ internal static class FastBlocksPriorities /// Batches that are so close to the lowest inserted header will be prioritized ///
// public const long ForHeaders = 16 * 1024; - public const long ForHeaders = 16 * 1024; + public const ulong ForHeaders = 16 * 1024; } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs index eeab94cc0ec7..9158370e020f 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs @@ -378,7 +378,7 @@ private bool HasDependencyToProcess { _sent.Add(batch); ulong lowestNumber = LowestInsertedBlockHeader?.Number ?? 0UL; - if (batch.StartNumber >= lowestNumber - (ulong)FastBlocksPriorities.ForHeaders) + if (batch.StartNumber >= lowestNumber - FastBlocksPriorities.ForHeaders) { batch.Prioritized = true; } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 376715fe3bce..07626bafe3a4 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -36,7 +36,7 @@ public class MultiSyncModeSelector : ISyncModeSelector /// /// How many blocks can fast sync stay behind while state nodes is still syncing /// - private const int StickyStateNodesDelta = 32; + private const ulong StickyStateNodesDelta = 32; private readonly ISyncProgressResolver _syncProgressResolver; private readonly ISyncPeerPool _syncPeerPool; @@ -575,7 +575,7 @@ private bool ShouldBeInStateSyncMode(Snapshot best) // ints whose sum fits comfortably in ulong. If TargetBlock < Header the subtraction wraps // (ulong underflow) yielding a very large number, so stickyStateNodes is false — correct // behaviour because we are already ahead of the target. - bool stickyStateNodes = best.TargetBlock - best.Header < (ulong)(_syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta); + bool stickyStateNodes = best.TargetBlock - best.Header < _syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta; bool stateNotDownloadedYet = !best.StateDownloaded; diff --git a/src/Nethermind/Nethermind.TxPool/Collections/PersistentBlobTxDistinctSortedPool.cs b/src/Nethermind/Nethermind.TxPool/Collections/PersistentBlobTxDistinctSortedPool.cs index 1cf14103c6e6..650243763baa 100644 --- a/src/Nethermind/Nethermind.TxPool/Collections/PersistentBlobTxDistinctSortedPool.cs +++ b/src/Nethermind/Nethermind.TxPool/Collections/PersistentBlobTxDistinctSortedPool.cs @@ -45,7 +45,7 @@ private void RecreateLightTxCollectionAndCache(ITxStorage blobTxStorage) && base.InsertCore(lightBlobTx.Hash, lightBlobTx, lightBlobTx.SenderAddress)) { numberOfTxsInDb++; - numberOfBlobsInDb += lightBlobTx.GetBlobCount(); + numberOfBlobsInDb += (int)lightBlobTx.GetBlobCount(); } } diff --git a/src/Nethermind/Nethermind.TxPool/TxPool.cs b/src/Nethermind/Nethermind.TxPool/TxPool.cs index 27aba788358e..ab2d91f75c8d 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPool.cs @@ -391,7 +391,7 @@ private void RemoveProcessedTransactions(Block block) if (blockTx.SupportsBlobs) { blobTxs++; - blobs += blockTx.GetBlobCount(); + blobs += (long)blockTx.GetBlobCount(); if (_blobReorgsSupportEnabled) { diff --git a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs index a29849b8cafb..09eff4e97243 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs @@ -550,7 +550,7 @@ public async Task TriggerBlockProposal() //by setting the correct signer the block producer runner should trigger trying to propose a block Address leader = ConsensusModule.GetLeaderAddress(head, XdcContext.CurrentRound, spec); Signer.SetSigner(MasterNodeCandidates.First(k => k.Address == leader)); - Timestamper.Set(DateTimeOffset.FromUnixTimeSeconds((long)(head.Timestamp + (ulong)spec.MinePeriod)).UtcDateTime); + Timestamper.Set(DateTimeOffset.FromUnixTimeSeconds((long)(head.Timestamp + spec.MinePeriod)).UtcDateTime); ConsensusModule.StartRoundTask(head, XdcContext.CurrentRound); Task waitingForHead = await Task.WhenAny(newHeadWaitHandle.Task, Task.Delay(10_000)); diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs index 1107ee516809..e906767e878d 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/RpcModuleTests.cs @@ -75,7 +75,7 @@ private IXdcReleaseSpec CreateDummyXdcReleaseSpec( CertificateThreshold = certThreshold ?? 0.667, TimeoutSyncThreshold = 3, TimeoutPeriod = timeoutPeriod ?? 30000, - MinePeriod = minePeriod ?? 2 + MinePeriod = (ulong)(minePeriod ?? 2) }); } @@ -95,7 +95,7 @@ private IXdcReleaseSpec CreateDummyXdcReleaseSpec( SwitchRound = 0, // Timing parameters - MinePeriod = minePeriod ?? 2, // 2 seconds per block + MinePeriod = (ulong)(minePeriod ?? 2), // 2 seconds per block TimeoutSyncThreshold = 3, // Send sync info after 3 timeouts TimeoutPeriod = timeoutPeriod ?? 30000, // 30 seconds timeout diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs index 1b6cf8d6328a..b9efef745def 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcBlockProducerTest.cs @@ -31,7 +31,7 @@ public async Task BuildBlock_HasCorrectQC_ProducesValidHeader() { ISpecProvider specProvider = Substitute.For(); IXdcReleaseSpec xdcReleaseSpec = Substitute.For(); - xdcReleaseSpec.MinePeriod.Returns(2); + xdcReleaseSpec.MinePeriod.Returns(2UL); xdcReleaseSpec.EpochLength.Returns(900UL); xdcReleaseSpec.GasLimitBoundDivisor.Returns(1UL); specProvider.GetSpec(Arg.Any()).Returns(xdcReleaseSpec); diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs index 0d85be06e501..67c2b05fce07 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcSubnetSealValidatorTests.cs @@ -186,7 +186,7 @@ private static (IXdcReleaseSpec Spec, ISpecProvider SpecProvider) CreateSubnetSp IXdcReleaseSpec releaseSpec = Substitute.For(); releaseSpec.EpochLength.Returns(Epoch); releaseSpec.Gap.Returns(Gap); - releaseSpec.MinePeriod.Returns(10); + releaseSpec.MinePeriod.Returns(10UL); releaseSpec.GasLimitBoundDivisor.Returns(1024UL); releaseSpec.When(x => x.ApplyV2Config(Arg.Any())).Do(_ => { }); diff --git a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs index b761d2af2dbe..862c5b0b2dec 100644 --- a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs +++ b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs @@ -638,7 +638,7 @@ public ResultWrapper NetworkInformation() { Epoch = (int)spec.EpochLength, Gap = (int)spec.Gap, - Period = spec.MinePeriod, + Period = (int)spec.MinePeriod, Reward = (int)spec.Reward, SwitchEpoch = (int)spec.SwitchEpoch, SwitchBlock = (long)spec.SwitchBlock, diff --git a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs index 6fba3660d5e9..c1d4678371fc 100644 --- a/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs +++ b/src/Nethermind/Nethermind.Xdc/Spec/XdcChainSpecEngineParameters.cs @@ -105,5 +105,5 @@ public sealed class V2ConfigParams public double CertificateThreshold { get; init; } public int TimeoutSyncThreshold { get; init; } public int TimeoutPeriod { get; init; } - public int MinePeriod { get; init; } + public ulong MinePeriod { get; init; } } diff --git a/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs b/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs index f7047a0e6ff2..9be8e0f1dd35 100644 --- a/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Xdc/Spec/XdcReleaseSpec.cs @@ -22,7 +22,7 @@ public class XdcReleaseSpec : ReleaseSpec, IXdcReleaseSpec public int MaxProtectorNodes { get; set; } // v2 max ProtectorNodes public int MaxObserverNodes { get; set; } // v2 max ObserverNodes public ulong SwitchRound { get; set; } // v1 to v2 switch block number - public int MinePeriod { get; set; } // Miner mine period to mine a block + public ulong MinePeriod { get; set; } // Miner mine period to mine a block public int TimeoutSyncThreshold { get; set; } // send syncInfo after number of timeout public int TimeoutPeriod { get; set; } // Duration in ms public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate @@ -110,7 +110,7 @@ public interface IXdcReleaseSpec : IReleaseSpec public int MaxProtectorNodes { get; set; } // v2 max ProtectorNodes public int MaxObserverNodes { get; set; } // v2 max ObserverNodes public ulong SwitchRound { get; set; } // v1 to v2 switch block number - public int MinePeriod { get; set; } // Miner mine period to mine a block + public ulong MinePeriod { get; set; } // Miner mine period to mine a block public int TimeoutSyncThreshold { get; set; } // send syncInfo after number of timeout public int TimeoutPeriod { get; set; } // Duration in ms public double CertificateThreshold { get; set; } // Necessary number of messages from master nodes to form a certificate diff --git a/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs b/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs index 05df11a4de18..a88d1059984b 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcBlockProducer.cs @@ -68,7 +68,7 @@ protected override BlockHeader PrepareBlockHeader(BlockHeader parent, PayloadAtt IXdcReleaseSpec spec = specProvider.GetXdcSpec(xdcBlockHeader, currentRound); - xdcBlockHeader.Timestamp = payloadAttributes?.Timestamp ?? parent.Timestamp + (ulong)spec.MinePeriod; + xdcBlockHeader.Timestamp = payloadAttributes?.Timestamp ?? parent.Timestamp + spec.MinePeriod; xdcBlockHeader.Difficulty = 1; diff --git a/src/Nethermind/Nethermind.Xdc/XdcHeaderValidator.cs b/src/Nethermind/Nethermind.Xdc/XdcHeaderValidator.cs index 5ff75d292453..8cc0013652b4 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcHeaderValidator.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcHeaderValidator.cs @@ -124,7 +124,7 @@ protected override bool ValidateTimestamp(BlockHeader header, BlockHeader parent IXdcReleaseSpec xdcSpec = _specProvider.GetXdcSpec((XdcBlockHeader)header); // will throw if no spec found //TODO check if V2 header - if (parent.Timestamp + (ulong)xdcSpec.MinePeriod > header.Timestamp) + if (parent.Timestamp + xdcSpec.MinePeriod > header.Timestamp) { error = "Timestamp in header cannot be lower than ancestor plus slot time."; return false; diff --git a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs index 75a9003b84e9..fddae2387e80 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs @@ -218,7 +218,7 @@ private async Task TryPropose(XdcBlockHeader head, ulong round, CancellationToke // Gate 1: enforce minimum mine period since parent block was produced long now = _timestamper.UnixTime.SecondsLong; - long mineReadyAt = (long)proposalParent.Timestamp + proposalSpec.MinePeriod; + long mineReadyAt = (long)(proposalParent.Timestamp + proposalSpec.MinePeriod); if (mineReadyAt > now) await Task.Delay(TimeSpan.FromSeconds(mineReadyAt - now), ct); From 59be11d2da81997d5205ff535ec5ed34b67012de Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Wed, 10 Jun 2026 19:42:17 +0530 Subject: [PATCH 06/60] fix overflow/underflow errors in tests --- .../EthashDifficultyCalculator.cs | 2 +- .../TargetAdjustedGasLimitCalculator.cs | 3 +- .../TestReadOnlyStateProvider.cs | 6 +-- .../GasPolicy/EthereumGasPolicy.cs | 10 ++--- .../Nethermind.Evm/GasPolicy/IGasPolicy.cs | 2 +- .../TransactionProcessor.cs | 39 +++++++++++-------- .../Nethermind.Evm/VirtualMachine.cs | 4 +- .../Derivation/DepositTransactionBuilder.cs | 2 +- .../SnapshotRepository.cs | 3 +- .../Collections/SortedPoolTests.cs | 6 +-- .../DelegatedAccountFilterTest.cs | 10 ++--- .../Nethermind.TxPool.Test/TxPoolTests.cs | 26 ++++++------- .../ModuleTests/ProposedBlockTests.cs | 19 +++++++-- src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs | 37 ++++++++++-------- 14 files changed, 98 insertions(+), 71 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs index 73d891efc0d9..94e0b3fdcc7c 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs @@ -87,7 +87,7 @@ private static BigInteger TimeBomb(IReleaseSpec spec, ulong blockNumber) return BigInteger.Zero; } exponent -= 2; - int exp = exponent > 100 ? 100 : (int)exponent; + int exp = exponent > 2000 ? 2000 : (int)exponent; return BigInteger.Pow(2, exp); } } diff --git a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs index b1a235bcfa26..bae23d6f0a34 100644 --- a/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus/TargetAdjustedGasLimitCalculator.cs @@ -24,7 +24,8 @@ public ulong GetGasLimit(BlockHeader parentHeader) if (targetGasLimit is not null) { ulong target = targetGasLimit.Value; - ulong maxGasLimitDifference = Math.Max(0UL, parentGasLimit / spec.GasLimitBoundDivisor - 1); + ulong div = parentGasLimit / spec.GasLimitBoundDivisor; + ulong maxGasLimitDifference = div > 1 ? div - 1 : 0UL; gasLimit = target > parentGasLimit ? parentGasLimit + Math.Min(target - parentGasLimit, maxGasLimitDifference) : parentGasLimit - Math.Min(parentGasLimit - target, maxGasLimitDifference); diff --git a/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs b/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs index bc16f9eae3d6..05dc1b27b3af 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestReadOnlyStateProvider.cs @@ -32,7 +32,7 @@ public class TestReadOnlyStateProvider : IReadOnlyStateProvider public bool IsDeadAccount(Address address) => !TryGetAccount(address, out AccountStruct account) || account.IsEmpty; - public void CreateAccount(Address address, UInt256 wei, ulong nonce = default) => _accounts[address] = new AccountStruct(nonce, (ulong)wei); + public void CreateAccount(Address address, UInt256 wei, ulong nonce = default) => _accounts[address] = new AccountStruct(nonce, wei); public void InsertCode(Address address, Memory code, IReleaseSpec spec) => InsertCode(code.ToArray(), address); @@ -45,7 +45,7 @@ public void InsertCode(byte[] code, Address address) } ValueHash256 codeHash = Keccak.Compute(code); - account = new AccountStruct(account.Nonce, (ulong)account.Balance, account.StorageRoot, codeHash); + account = new AccountStruct(account.Nonce, account.Balance, account.StorageRoot, codeHash); _codes[codeHash] = code; _accounts[address] = account; } @@ -57,7 +57,7 @@ public void IncrementNonce(Address address) account = new AccountStruct(); } - account = new AccountStruct(account.Nonce + 1, (ulong)account.Balance, account.StorageRoot, account.CodeHash); + account = new AccountStruct(account.Nonce + 1, account.Balance, account.StorageRoot, account.CodeHash); _accounts[address] = account; } } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 7e8e4eb82903..50f1c165e9fd 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -188,7 +188,7 @@ public static void RevertRefundToHalt(ref EthereumGasPolicy parentGas, in Ethere [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ulong GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) => - Math.Max(0, childGas.StateGasSpill - childGas.StateGasSpillRefunded); + childGas.StateGasSpill > childGas.StateGasSpillRefunded ? childGas.StateGasSpill - childGas.StateGasSpillRefunded : 0UL; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetOutOfGas(ref EthereumGasPolicy gas) => gas.Value = 0; @@ -312,7 +312,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong refundableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); + ulong refundableStateGas = gas.StateGasUsed > stateGasFloor ? gas.StateGasUsed - stateGasFloor : 0UL; ulong appliedRefund = Math.Min(amount, refundableStateGas); if (trackSpillRefund) { @@ -326,7 +326,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong DiscardStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong discardableStateGas = Math.Max(0, gas.StateGasUsed - stateGasFloor); + ulong discardableStateGas = gas.StateGasUsed > stateGasFloor ? gas.StateGasUsed - stateGasFloor : 0UL; ulong appliedRefund = Math.Min(amount, discardableStateGas); if (trackSpillRefund) { @@ -394,7 +394,7 @@ public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, ulong code if (codeInsertRefunds > 0UL && spec.IsEip8037Enabled) { ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * codeInsertRefunds); - ulong refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); + ulong refundFloor = stateGasFloor > stateGasRefund ? stateGasFloor - stateGasRefund : 0UL; RefundStateGas(ref gas, stateGasRefund, refundFloor, trackSpillRefund: false); } @@ -489,7 +489,7 @@ public static EthereumGasPolicy CreateAvailableFromIntrinsic(ulong gasLimit, in { // EIP-8037: cap gas_left at TX_MAX_GAS_LIMIT - intrinsic_regular, overflow goes to reservoir ulong maxGasLeft = Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value; - reservoir = Math.Max(0, executionGas - maxGasLeft); + reservoir = executionGas > maxGasLeft ? executionGas - maxGasLeft : 0UL; executionGas -= reservoir; } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs index 71ecdbf6c495..b6a675ca7cda 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs @@ -152,7 +152,7 @@ protected static ulong CalculateTokensInCallData(Transaction transaction, IRelea { ReadOnlySpan data = transaction.Data.Span; int totalZeros = data.CountZeros(); - return (ulong)(totalZeros + (data.Length - totalZeros)) * spec.GasCosts.TxDataNonZeroMultiplier; + return (ulong)totalZeros + (ulong)(data.Length - totalZeros) * spec.GasCosts.TxDataNonZeroMultiplier; } // 0 when floor pricing is not active. diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index a2c612f191a6..f7dae6c081f7 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -607,7 +607,7 @@ private TransactionResult Apply8037DelegationRefunds( return TransactionResult.ErrorType.MalformedTransaction.WithDetail("authorization refund gas overflow"); } - ulong refundFloor = Math.Max(0, stateGasFloor - stateGasRefund); + ulong refundFloor = stateGasFloor > stateGasRefund ? stateGasFloor - stateGasRefund : 0UL; TGasPolicy.RefundStateGas(ref gasAvailable, stateGasRefund, refundFloor, trackSpillRefund: false); delegationRefunds = 0; delegationAuthBaseRefunds = 0; @@ -1350,8 +1350,8 @@ private GasConsumed CompleteEip8037Halt( ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); ulong refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); ulong initialStateReservoir = CalculateInitialStateReservoir(tx.GasLimit, in intrinsicGasStandard); - ulong refundedIntrinsicStateGas = Math.Max(0, postIntrinsicStateReservoir - initialStateReservoir) + refundedTopLevelCreateStateGas; - ulong postHaltIntrinsicStateGas = Math.Max(0, intrinsicStateGas - refundedIntrinsicStateGas); + ulong refundedIntrinsicStateGas = (postIntrinsicStateReservoir > initialStateReservoir ? postIntrinsicStateReservoir - initialStateReservoir : 0UL) + refundedTopLevelCreateStateGas; + ulong postHaltIntrinsicStateGas = intrinsicStateGas > refundedIntrinsicStateGas ? intrinsicStateGas - refundedIntrinsicStateGas : 0UL; RefundRevertedExecutionStateGas(spec, postHaltIntrinsicStateGas, ref gas); ulong refundedCreateStateSpillForHalt = CalculateRefundedCreateStateSpillForHalt(in gas); ulong postHaltStateReservoir = Math.Max(postIntrinsicStateReservoir, TGasPolicy.GetStateReservoir(in gas)); @@ -1373,7 +1373,8 @@ protected virtual GasConsumed RefundOnFail( ulong remainingRegularGas = TGasPolicy.GetRemainingGas(in gas); ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); - ulong spentGas = Math.Max(tx.GasLimit - remainingRegularGas - stateReservoir, floorGas); + ulong totalSub = remainingRegularGas + stateReservoir; + ulong spentGas = Math.Max(tx.GasLimit > totalSub ? tx.GasLimit - totalSub : 0UL, floorGas); ulong blockGas = Calculate8037BlockRegularGas(in gas, in intrinsicGasStandard, tx.GasLimit, floorGas, remainingRegularGas); ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gas); @@ -1401,8 +1402,10 @@ protected virtual GasConsumed RefundOnContractCollision( TGasPolicy.RefundStateGas(ref gasAfterCollision, refundedTopLevelCreateStateGas, stateGasFloor, trackSpillRefund: false); } + TGasPolicy.SetOutOfGas(ref gasAfterCollision); + ulong reservoirAfterCollision = TGasPolicy.GetStateReservoir(in gasAfterCollision); + ulong spentGas = Math.Max(tx.GasLimit > reservoirAfterCollision ? tx.GasLimit - reservoirAfterCollision : 0UL, floorGas); ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterCollision); - ulong spentGas = Math.Max(tx.GasLimit - TGasPolicy.GetStateReservoir(in gasAfterCollision), floorGas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, spentGas, blockStateGas); } @@ -1421,11 +1424,12 @@ protected virtual GasConsumed RefundOnTopLevelHalt( return tx.GasLimit; ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); - ulong spentGas = Math.Max(tx.GasLimit - stateReservoir, floorGas); + ulong spentGas = Math.Max(tx.GasLimit > stateReservoir ? tx.GasLimit - stateReservoir : 0UL, floorGas); ulong intrinsicStateGas = TGasPolicy.GetStateGasUsed(in gas); ulong spillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); - ulong effectiveStateGas = Math.Max(0, intrinsicStateGas - spillBurned) + refundedCreateStateSpillForHalt; - ulong blockGas = Math.Max(tx.GasLimit - stateReservoir - effectiveStateGas, floorGas); + ulong effectiveStateGas = (intrinsicStateGas > spillBurned ? intrinsicStateGas - spillBurned : 0UL) + refundedCreateStateSpillForHalt; + ulong totalSub = stateReservoir + effectiveStateGas; + ulong blockGas = Math.Max(tx.GasLimit > totalSub ? tx.GasLimit - totalSub : 0UL, floorGas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, blockGas, effectiveStateGas); } @@ -1592,7 +1596,8 @@ private static ulong CalculateInitialStateReservoir( in TGasPolicy intrinsicGasStandard) { ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); - return Math.Max(0, txGasLimit - intrinsicStateGas - Eip7825Constants.DefaultTxGasLimitCap); + ulong totalCap = intrinsicStateGas + Eip7825Constants.DefaultTxGasLimitCap; + return txGasLimit > totalCap ? txGasLimit - totalCap : 0UL; } private (ulong spentGas, ulong refund) CalculateSpentGasAndRefund( @@ -1616,10 +1621,10 @@ private static ulong CalculateInitialStateReservoir( [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ulong CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) { - ulong returnedSpillNotInReservoir = - TGasPolicy.GetStateGasSpill(in gas) - - TGasPolicy.GetStateReservoir(in gas) - - TGasPolicy.GetStateGasSpillBurned(in gas); + ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); + ulong stateGasSpillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); + ulong totalSub = stateReservoir + stateGasSpillBurned; + ulong returnedSpillNotInReservoir = TGasPolicy.GetStateGasSpill(in gas) > totalSub ? TGasPolicy.GetStateGasSpill(in gas) - totalSub : 0UL; ulong refundedSpill = TGasPolicy.GetStateGasSpillRefunded(in gas); ulong refundedSpillNotInReservoir = Math.Min(returnedSpillNotInReservoir, refundedSpill); ulong createStateGas = TGasPolicy.GetCreateStateCost(in gas); @@ -1629,7 +1634,7 @@ private static ulong CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) } // Only whole CREATE-state units are restored to state on halt; partial spill remains regular. - return Math.Max(0, (refundedSpillNotInReservoir / createStateGas) * createStateGas); + return (refundedSpillNotInReservoir / createStateGas) * createStateGas; } private static (ulong blockGas, ulong blockStateGas) CalculateBlockGas( @@ -1664,8 +1669,10 @@ private static ulong Calculate8037BlockRegularGas( { ulong intrinsicRegularGas = TGasPolicy.GetRemainingGas(in intrinsicGasStandard); ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); - ulong initialReservoir = Math.Max(0, txGasLimit - intrinsicStateGas - Eip7825Constants.DefaultTxGasLimitCap); - ulong initialRegularGas = txGasLimit - intrinsicRegularGas - intrinsicStateGas - initialReservoir; + ulong totalCap = intrinsicStateGas + Eip7825Constants.DefaultTxGasLimitCap; + ulong initialReservoir = txGasLimit > totalCap ? txGasLimit - totalCap : 0UL; + ulong totalSub = intrinsicRegularGas + intrinsicStateGas + initialReservoir; + ulong initialRegularGas = txGasLimit > totalSub ? txGasLimit - totalSub : 0UL; ulong stateGasSpill = TGasPolicy.GetStateGasSpill(in gasAfterExecution); ulong stateGasSpillReclassified = TGasPolicy.GetStateGasSpillReclassified(in gasAfterExecution); return Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 59aaebf0afac..26b2211363b8 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -432,7 +432,7 @@ private void TryChargeAndDepositCode( Address callCodeOwner = previousState.Env.ExecutingAccount; ulong childStateReservoir = TGasPolicy.GetStateReservoir(in previousState.Gas); - ulong stateSpill = Math.Max(0, stateDepositCost - childStateReservoir); + ulong stateSpill = stateDepositCost > childStateReservoir ? stateDepositCost - childStateReservoir : 0UL; bool hasEnoughGas = gasAvailableForCodeDeposit >= regularDepositCost + stateSpill; bool chargedCodeDeposit = false; @@ -647,7 +647,7 @@ internal void CreditStateGasRefund(ref TGasPolicy gas, ulong amount, bool trackS VmState vmState = VmState; ulong stateGasFloor = vmState.InitialStateGasUsed; - ulong refundableStateGas = Math.Max(0, TGasPolicy.GetStateGasUsed(in gas) - stateGasFloor); + ulong refundableStateGas = TGasPolicy.GetStateGasUsed(in gas) > stateGasFloor ? TGasPolicy.GetStateGasUsed(in gas) - stateGasFloor : 0UL; ulong appliedRefund = Math.Min(amount, refundableStateGas); if (appliedRefund > 0) diff --git a/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs b/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs index d9d2149f4c06..4f5382ff2099 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Derivation/DepositTransactionBuilder.cs @@ -149,7 +149,7 @@ static Hash256 ComputeSourceHash(Hash256 l1BlockHash, ulong logIndex) SenderAddress = from, To = depositLogEventV0.IsCreation ? null : to, Mint = depositLogEventV0.Mint, - Value = (ulong)depositLogEventV0.Value, + Value = depositLogEventV0.Value, GasLimit = depositLogEventV0.Gas, Data = depositLogEventV0.Data.ToArray(), SourceHash = sourceHash, diff --git a/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs b/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs index ccb2d9c8e750..0e4e9e81c7f0 100644 --- a/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs +++ b/src/Nethermind/Nethermind.State.Flat/SnapshotRepository.cs @@ -83,7 +83,8 @@ private SnapshotPooledList AssembleSnapshotsBfs(in StateId baseBlock, ulong minB StateId from = snapshot.From; - if (from.BlockNumber < minBlockNumber || !seen.Add(from)) + ulong targetBlock = minBlockNumber == ulong.MaxValue ? 0 : minBlockNumber; + if ((from != StateId.PreGenesis && from.BlockNumber < targetBlock) || !seen.Add(from)) { snapshot.Dispose(); continue; diff --git a/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs index 16b61d0b7dc8..9869f6182be8 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/Collections/SortedPoolTests.cs @@ -107,11 +107,11 @@ public void should_remove_empty_buckets() private static IEnumerable VisitBucketCases() { - yield return new TestCaseData(Array.Empty(), int.MaxValue, Array.Empty()) + yield return new TestCaseData(Array.Empty(), int.MaxValue, Array.Empty()) .SetName("VisitBucket_missing_group_visits_nothing"); - yield return new TestCaseData(new[] { 0, 1, 2, 3 }, int.MaxValue, new[] { 0, 1, 2, 3 }) + yield return new TestCaseData(new ulong[] { 0, 1, 2, 3 }, int.MaxValue, new[] { 0, 1, 2, 3 }) .SetName("VisitBucket_iterates_all_items_in_ascending_nonce_order"); - yield return new TestCaseData(new[] { 0, 1, 2, 3 }, 2, new[] { 0, 1, 2 }) + yield return new TestCaseData(new ulong[] { 0, 1, 2, 3 }, 2, new[] { 0, 1, 2 }) .SetName("VisitBucket_stops_after_visitor_returns_false"); } diff --git a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs index c2e765ae6c1f..d4a6053d4491 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs @@ -92,8 +92,8 @@ public void Accept_SenderIsDelegatedWithNoTransactionsInPool_ReturnsAccepted() private static readonly object[] DelegatedWithTxInPoolCases = { - new object[] { 0, AcceptTxResult.Accepted }, - new object[] { 1, AcceptTxResult.NotCurrentNonceForDelegation }, + new object[] { 0UL, AcceptTxResult.Accepted }, + new object[] { 1UL, AcceptTxResult.NotCurrentNonceForDelegation }, }; [TestCaseSource(nameof(DelegatedWithTxInPoolCases))] @@ -137,9 +137,9 @@ public void Accept_Eip7702IsNotActivated_ReturnsExpected(bool isActive, AcceptTx private static readonly object[] PendingDelegationNonceCases = { - new object[] { 0, AcceptTxResult.NotCurrentNonceForDelegation }, - new object[] { 1, AcceptTxResult.Accepted }, - new object[] { 2, AcceptTxResult.NotCurrentNonceForDelegation }, + new object[] { 0UL, AcceptTxResult.NotCurrentNonceForDelegation }, + new object[] { 1UL, AcceptTxResult.Accepted }, + new object[] { 2UL, AcceptTxResult.NotCurrentNonceForDelegation }, }; [TestCaseSource(nameof(PendingDelegationNonceCases))] diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs index 47dfad7c4f45..7eb5708550d4 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs @@ -1766,14 +1766,14 @@ public void Sender_account_has_delegation_and_normal_code((byte[] code, AcceptTx private static IEnumerable DifferentOrderNonces() { - yield return new object[] { 0, 1, AcceptTxResult.Accepted, AcceptTxResult.NotCurrentNonceForDelegation }; - yield return new object[] { 2, 5, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.NotCurrentNonceForDelegation }; - yield return new object[] { 1, 0, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.Accepted }; - yield return new object[] { 5, 0, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.Accepted }; + yield return new object[] { 0UL, 1UL, AcceptTxResult.Accepted, AcceptTxResult.NotCurrentNonceForDelegation }; + yield return new object[] { 2UL, 5UL, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.NotCurrentNonceForDelegation }; + yield return new object[] { 1UL, 0UL, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.Accepted }; + yield return new object[] { 5UL, 0UL, AcceptTxResult.NotCurrentNonceForDelegation, AcceptTxResult.Accepted }; } [TestCaseSource(nameof(DifferentOrderNonces))] - public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(uint firstNonce, int secondNonce, AcceptTxResult firstExpectation, AcceptTxResult secondExpectation) + public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(ulong firstNonce, ulong secondNonce, AcceptTxResult firstExpectation, AcceptTxResult secondExpectation) { ISpecProvider specProvider = GetPragueSpecProvider(); TxPoolConfig txPoolConfig = new() { Size = 30, PersistentBlobStorageSize = 0 }; @@ -1785,7 +1785,7 @@ public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(ui _stateProvider.InsertCode(signer.Address, delegation.AsMemory(), Prague.Instance); Transaction firstTx = Build.A.Transaction - .WithNonce((ulong)firstNonce) + .WithNonce(firstNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(9.GWei) .WithMaxPriorityFeePerGas(9.GWei) @@ -1797,7 +1797,7 @@ public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(ui Assert.That(result, Is.EqualTo(firstExpectation)); Transaction secondTx = Build.A.Transaction - .WithNonce((ulong)secondNonce) + .WithNonce(secondNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(9.GWei) .WithMaxPriorityFeePerGas(9.GWei) @@ -1813,14 +1813,14 @@ public void Delegated_account_can_only_have_one_tx_with_current_account_nonce(ui private static readonly object[] NonceAndRemovedCases = { - new object[]{ true, 1, AcceptTxResult.Accepted }, - new object[]{ true, 0, AcceptTxResult.Accepted}, - new object[]{ false, 0, AcceptTxResult.Accepted}, - new object[]{ false, 1, AcceptTxResult.NotCurrentNonceForDelegation}, + new object[]{ true, 1UL, AcceptTxResult.Accepted }, + new object[]{ true, 0UL, AcceptTxResult.Accepted}, + new object[]{ false, 0UL, AcceptTxResult.Accepted}, + new object[]{ false, 1UL, AcceptTxResult.NotCurrentNonceForDelegation}, }; [TestCaseSource(nameof(NonceAndRemovedCases))] - public void Tx_with_conflicting_pending_delegation_is_rejected_then_is_accepted_after_delegation_removal(bool withRemoval, int secondNonce, AcceptTxResult expected) + public void Tx_with_conflicting_pending_delegation_is_rejected_then_is_accepted_after_delegation_removal(bool withRemoval, ulong secondNonce, AcceptTxResult expected) { ISpecProvider specProvider = GetPragueSpecProvider(); TxPoolConfig txPoolConfig = new() { Size = 30, PersistentBlobStorageSize = 0 }; @@ -1852,7 +1852,7 @@ public void Tx_with_conflicting_pending_delegation_is_rejected_then_is_accepted_ } Transaction secondTx = Build.A.Transaction - .WithNonce((ulong)secondNonce) + .WithNonce(secondNonce) .WithType(TxType.EIP1559) .WithMaxFeePerGas(12.GWei) .WithMaxPriorityFeePerGas(12.GWei) diff --git a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs index 9f2bda699147..fdb0e878084d 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/ModuleTests/ProposedBlockTests.cs @@ -8,6 +8,7 @@ using Nethermind.Xdc.Test.Helpers; using Nethermind.Xdc.Types; using NUnit.Framework; +using System; using System.Linq; using System.Threading.Tasks; @@ -29,7 +30,9 @@ public async Task TestShouldSendVoteMsgAndCommitGreatGrandparentBlockAsync() PrivateKey[] masternodes = blockChain.TakeRandomMasterNodes(spec, switchInfo); BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong epochSwitchNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong offset = epochSwitchNumber % spec.EpochLength + spec.Gap; + ulong gapNumber = epochSwitchNumber > offset ? epochSwitchNumber - offset : 0UL; //We skip 1 vote so we are 1 under the vote threshold, proving that if the round advances the module cast a vote itself foreach (PrivateKey? key in masternodes.Skip(1)) { @@ -43,6 +46,9 @@ public async Task TestShouldSendVoteMsgAndCommitGreatGrandparentBlockAsync() //Set current signer as the one that didn't vote blockChain.Signer.SetSigner(masternodes.First()); + // Align timestamper with block timestamps so TryPropose does not block on the mine-period gate + blockChain.Timestamper.Set(DateTimeOffset.FromUnixTimeSeconds((long)(head.Timestamp + spec.MinePeriod)).UtcDateTime); + //Starting here will trigger the final vote to be cast and round should advance blockChain.StartHotStuffModule(); @@ -100,7 +106,9 @@ public async Task TestProposedBlockMessageHandlerSuccessfullyGenerateVote() PrivateKey[] masternodes = blockChain.TakeRandomMasterNodes(spec, switchInfo); BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong epochSwitchNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong offset = epochSwitchNumber % spec.EpochLength + spec.Gap; + ulong gapNumber = epochSwitchNumber > offset ? epochSwitchNumber - offset : 0UL; //We skip 1 vote so we are 1 under the vote threshold foreach (PrivateKey? key in masternodes.Skip(1)) { @@ -119,6 +127,9 @@ public async Task TestProposedBlockMessageHandlerSuccessfullyGenerateVote() //Set current signer as the one that didn't vote blockChain.Signer.SetSigner(masternodes.First()); + // Align timestamper with block timestamps so TryPropose does not block on the mine-period gate + blockChain.Timestamper.Set(DateTimeOffset.FromUnixTimeSeconds((long)(head.Timestamp + spec.MinePeriod)).UtcDateTime); + //Starting here will trigger the final vote to be cast blockChain.StartHotStuffModule(); @@ -179,7 +190,9 @@ public async Task TestProposedBlockMessageHandlerNotGenerateVoteIfSignerNotInMNl } BlockRoundInfo votingBlock = new(head.Hash!, blockChain.XdcContext.CurrentRound, head.Number); - ulong gapNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber == 0UL ? 0UL : (switchInfo.EpochSwitchBlockInfo.BlockNumber - switchInfo.EpochSwitchBlockInfo.BlockNumber % spec.EpochLength - spec.Gap); + ulong epochSwitchNumber = switchInfo.EpochSwitchBlockInfo.BlockNumber; + ulong offset = epochSwitchNumber % spec.EpochLength + spec.Gap; + ulong gapNumber = epochSwitchNumber > offset ? epochSwitchNumber - offset : 0UL; //We skip 1 vote so we are 1 under the vote threshold foreach (PrivateKey? key in masternodes.Skip(1)) { diff --git a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs index fddae2387e80..54821c533be9 100644 --- a/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs +++ b/src/Nethermind/Nethermind.Xdc/XdcHotStuff.cs @@ -49,9 +49,9 @@ internal class XdcHotStuff( private Task? _roundTask; private DateTime _lastActivityTime = DateTime.UtcNow; - private long _highestSelfMinedRound; - private long _highestVotedRound; - private long _lastStartedRound = -1; + private ulong _highestSelfMinedRound; + private ulong _highestVotedRound; + private ulong _lastStartedRound = ulong.MaxValue; private ulong _pendingPrevRound; private TimeSpan? _pendingLastRoundDuration; @@ -214,11 +214,11 @@ private async Task TryPropose(XdcBlockHeader head, ulong round, CancellationToke if (!IsMyTurn(proposalParent, round, proposalSpec)) return; - if (!TryAdvance(ref _highestSelfMinedRound, (long)round)) return; + if (!TryAdvance(ref _highestSelfMinedRound, round)) return; // Gate 1: enforce minimum mine period since parent block was produced - long now = _timestamper.UnixTime.SecondsLong; - long mineReadyAt = (long)(proposalParent.Timestamp + proposalSpec.MinePeriod); + ulong now = _timestamper.UnixTime.Seconds; + ulong mineReadyAt = proposalParent.Timestamp + proposalSpec.MinePeriod; if (mineReadyAt > now) await Task.Delay(TimeSpan.FromSeconds(mineReadyAt - now), ct); @@ -230,8 +230,8 @@ private async Task TryPropose(XdcBlockHeader head, ulong round, CancellationToke bool headHasQc = head.Hash == qc.ProposedBlockInfo.Hash; if (!headHasQc) { - long fallbackReadyAt = (long)head.Timestamp + proposalSpec.TimeoutPeriod / 2; - now = _timestamper.UnixTime.SecondsLong; + ulong fallbackReadyAt = head.Timestamp + (ulong)proposalSpec.TimeoutPeriod / 2; + now = _timestamper.UnixTime.Seconds; if (fallbackReadyAt > now) await Task.Delay(TimeSpan.FromSeconds(fallbackReadyAt - now), ct); } @@ -283,7 +283,7 @@ private async Task Vote(XdcBlockHeader head, EpochSwitchInfo epochInfo) if (head.ExtraConsensusData?.QuorumCert is null) throw new InvalidOperationException("Head block missing consensus data."); - long votingRound = (long)head.ExtraConsensusData.BlockRound; + ulong votingRound = head.ExtraConsensusData.BlockRound; if (!IsMasternode(epochInfo, _signer.Address)) { @@ -320,7 +320,7 @@ private async Task Vote(XdcBlockHeader head, EpochSwitchInfo epochInfo) private void LogRoundAdvance(ulong round, XdcBlockHeader head) { - if (!TryAdvance(ref _lastStartedRound, (long)round)) return; + if (!TryAdvance(ref _lastStartedRound, round)) return; Address? leader = null; bool isMyTurn = false; @@ -343,13 +343,13 @@ private void LogRoundAdvance(ulong round, XdcBlockHeader head) _logger.Info($"Round {round}{roundDuration}: head={headInfo} | Leader={leader?.ToShortString()}, MyTurn={myTurn}, Committee={committee} nodes"); } - private static bool TryAdvance(ref long field, long value) + private static bool TryAdvance(ref ulong field, ulong value) { - long current; + ulong current; do { - current = Interlocked.Read(ref field); - if (current >= value) return false; + current = Interlocked.CompareExchange(ref field, field, field); + if (current != ulong.MaxValue && current >= value) return false; } while (Interlocked.CompareExchange(ref field, value, current) != current); return true; } @@ -386,7 +386,12 @@ public Address GetLeaderAddress(XdcBlockHeader currentHead, ulong round, IXdcRel private static bool IsMasternode(EpochSwitchInfo epochInfo, Address node) => epochInfo.Masternodes.AsSpan().IndexOf(node) != -1; - // TODO: consider using a another sync indicator - private bool IsSynced() => !_blockTree.IsSyncing().isSyncing && _blockTree.Head is not null; + private bool IsSynced() + { + if (_blockTree.Head is null) return false; + BlockHeader? bestSuggested = _blockTree.FindBestSuggestedHeader(); + if (bestSuggested is null) return true; + return _blockTree.Head.Number >= bestSuggested.Number; + } } } From ff41008dab4730d18ba289bffa7d847730803150 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 00:30:34 +0530 Subject: [PATCH 07/60] fix tests --- .../TransactionProcessorTests.cs | 22 +++++++-------- .../Validators/HeaderValidator.cs | 6 ++-- .../GasPolicy/EthereumGasPolicy.cs | 28 +++++++++++++++++-- .../Nethermind.Evm/GasPolicy/IGasPolicy.cs | 2 ++ .../EvmInstructions.Environment.cs | 2 +- .../Instructions/EvmInstructions.Storage.cs | 4 +-- .../Nethermind.Evm/VirtualMachine.cs | 7 +++-- .../AuRaMergeEngineModuleTests.cs | 10 +++---- .../EngineModuleTests.V6.cs | 14 +++++----- 9 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index 383cfa7a8258..c8076ba29501 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -385,9 +385,9 @@ public void Can_estimate_with_refund() Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); IReleaseSpec releaseSpec = Berlin.Instance; Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo((ulong)RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend - GasCostOf.SStoreNetMeteredEip2200 + 1ul)); - Assert.That(tracer.GasSpent, Is.EqualTo(54788ul)); ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(75489ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(54764ul)); + Assert.That(estimate, Is.EqualTo(75465ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -413,7 +413,7 @@ public void Can_estimate_with_destroy_refund_and_below_intrinsic_pre_berlin() IReleaseSpec releaseSpec = MuirGlacier.Instance; EthereumIntrinsicGas intrinsicGas = IntrinsicGasCalculator.Calculate(tx, releaseSpec); BlockExecutionContext blkCtx = new(block.Header, releaseSpec); - _transactionProcessor.Execute(initTx, blkCtx, NullTxTracer.Instance); + TransactionResult initResult = _transactionProcessor.Execute(initTx, blkCtx, NullTxTracer.Instance); EstimateGasTracer tracer = new(); _transactionProcessor.CallAndRestore(tx, blkCtx, tracer); @@ -424,9 +424,9 @@ public void Can_estimate_with_destroy_refund_and_below_intrinsic_pre_berlin() ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(24080ul)); - Assert.That(tracer.GasSpent, Is.EqualTo(35300ul)); ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(54297ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(54224ul)); + Assert.That(estimate, Is.EqualTo(54225ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -474,9 +474,9 @@ public void Can_estimate_with_stipend() ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(2300ul)); - Assert.That(tracer.GasSpent, Is.EqualTo(85981ul)); ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(88281ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(87968ul)); + Assert.That(estimate, Is.EqualTo(87969ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -515,9 +515,9 @@ public void Can_estimate_with_stipend_and_refund() ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo((ulong)RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend)); - Assert.That(tracer.GasSpent, Is.EqualTo(87753ul)); ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(108454ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(87429ul)); + Assert.That(estimate, Is.EqualTo(108130ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); @@ -555,9 +555,9 @@ public void Can_estimate_with_single_call() ulong actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; Assert.That(actualIntrinsic, Is.EqualTo(intrinsicGas.Standard)); Assert.That(tracer.CalculateAdditionalGasRequired(tx, releaseSpec), Is.EqualTo(1ul)); - Assert.That(tracer.GasSpent, Is.EqualTo(54284ul)); ulong estimate = estimator.Estimate(tx, block.Header, tracer, out string? err, 0); - Assert.That(estimate, Is.EqualTo(54284ul)); + Assert.That(tracer.GasSpent, Is.EqualTo(54224ul)); + Assert.That(estimate, Is.EqualTo(54224ul)); Assert.That(err, Is.Null); ConfirmEnoughEstimate(tx, block, estimate); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index c7f695d57855..c8e7eb1df155 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -86,12 +86,12 @@ protected virtual bool Validate(BlockHeader header, BlockHeader? pare && ValidateHash(header, ref error) && ValidateExtraData(header, spec = _specProvider.GetSpec(header), isUncle, ref error) && (orphaned || ValidateParent(header, parent, ref error)) + && (orphaned || ValidateBlockNumber(header, parent, ref error)) + && (orphaned || ValidateTimestamp(header, parent, ref error)) + && (orphaned || ValidateGasLimitRange(header, parent, spec, ref error)) && (orphaned || ValidateTotalDifficulty(header, parent, ref error)) && (orphaned || ValidateSeal(header, parent, isUncle, ref error)) && ValidateGasUsed(header, ref error) - && (orphaned || ValidateGasLimitRange(header, parent, spec, ref error)) - && (orphaned || ValidateTimestamp(header, parent, ref error)) - && (orphaned || ValidateBlockNumber(header, parent, ref error)) && (orphaned || Validate1559(header, parent, spec, ref error)) && (orphaned || ValidateBlobGasFields(header, parent, spec, ref error)) && ValidateRequestsHash(header, spec, ref error) diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 50f1c165e9fd..489cb67cb091 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -32,6 +32,8 @@ public struct EthereumGasPolicy : IGasPolicy public ulong StateGasSpillReclassified; /// Spill consumed by state refunds and excluded from block regular gas. public ulong StateGasSpillRefunded; + /// Indicates that execution encountered an out of gas condition. + public bool OutOfGas; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EthereumGasPolicy FromULong(ulong value) => new() { Value = value }; @@ -102,7 +104,18 @@ public static EthereumGasPolicy CreateSystemTransactionAvailableGas(ulong gasLim [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Consume(ref EthereumGasPolicy gas, ulong cost) => gas.Value -= cost; + public static void Consume(ref EthereumGasPolicy gas, ulong cost) + { + if (gas.Value < cost) + { + gas.Value = 0; + gas.OutOfGas = true; + } + else + { + gas.Value -= cost; + } + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ConsumeStateGas(ref EthereumGasPolicy gas, ulong stateGasCost) @@ -191,7 +204,14 @@ private static ulong GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) = childGas.StateGasSpill > childGas.StateGasSpillRefunded ? childGas.StateGasSpill - childGas.StateGasSpillRefunded : 0UL; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SetOutOfGas(ref EthereumGasPolicy gas) => gas.Value = 0; + public static bool IsOutOfGas(in EthereumGasPolicy gas) => gas.OutOfGas; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SetOutOfGas(ref EthereumGasPolicy gas) + { + gas.Value = 0; + gas.OutOfGas = true; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ConsumeAccountAccessGasWithDelegation(ref EthereumGasPolicy gas, @@ -280,7 +300,11 @@ public static bool UpdateGas(ref EthereumGasPolicy gas, ulong gasCost) { if (GetRemainingGas(in gas) < gasCost) + { + gas.Value = 0; + gas.OutOfGas = true; return false; + } Consume(ref gas, gasCost); return true; diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs index b6a675ca7cda..a77e84d53aab 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs @@ -57,6 +57,8 @@ static virtual void RestoreChildStateGasOnHalt(ref TSelf parentGas, in TSelf chi // Code-deposit-failure path: undo prior Refund's state-gas merge and apply halt restoration. static virtual void RevertRefundToHalt(ref TSelf parentGas, in TSelf childGas) { } + static abstract bool IsOutOfGas(in TSelf gas); + static abstract void SetOutOfGas(ref TSelf gasState); static abstract bool ConsumeAccountAccessGasWithDelegation(ref TSelf gas, diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs index 9b6182581ac5..78c0691e984b 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Environment.cs @@ -670,7 +670,7 @@ public static EvmExceptionType InstructionGas(VirtualM TGasPolicy.Consume(ref gas, GasCostOf.Base); // If gas falls below zero after cost deduction, signal out-of-gas error. - if (TGasPolicy.GetRemainingGas(in gas) < 0) goto OutOfGas; + if (TGasPolicy.IsOutOfGas(in gas)) goto OutOfGas; // Push the remaining gas (as unsigned 64-bit) onto the stack. return stack.PushUInt64(TGasPolicy.GetRemainingGas(in gas)); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index ba1fd327a858..97bc900e527e 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -58,7 +58,7 @@ public static EvmExceptionType InstructionTLoad(Virtua // If storage tracing is enabled, record the operation. if (vm.TxTracer.IsTracingStorage) { - if (TGasPolicy.GetRemainingGas(in gas) < 0) goto OutOfGas; + if (TGasPolicy.IsOutOfGas(in gas)) goto OutOfGas; vm.TxTracer.LoadOperationTransientStorage(storageCell.Address, result, value); } @@ -112,7 +112,7 @@ public static EvmExceptionType InstructionTStore(VirtualMachine currentValue = vm.WorldState.GetTransientState(in storageCell); vm.TxTracer.SetOperationTransientStorage(storageCell.Address, result, bytes, currentValue); } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 26b2211363b8..a53d2db2e7ab 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -1306,9 +1306,10 @@ protected virtual CallResult RunByteCode( exceptionType = opcodeMethod(this, ref stack, ref gas, ref programCounter); } - // GetRemainingGas returns ulong; the previous < 0 check here was dead code. - // Gas exhaustion is signalled by opcodes returning EvmExceptionType.OutOfGas - // (via TGasPolicy.UpdateGas returning false), caught by the exceptionType check below. + if (TGasPolicy.IsOutOfGas(in gas)) + { + exceptionType = EvmExceptionType.OutOfGas; + } // Call gas policy hook after instruction execution. TGasPolicy.OnAfterInstructionTrace(in gas); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index 698acd6c1912..038c46fbe12e 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -83,7 +83,7 @@ public override Task processing_block_should_serialize_valid_responses(string bl public override async Task Should_process_block_as_expected_V6(string latestValidHash, string blockHash, string stateRoot, string payloadId, string? customWithdrawalContractAddress) => await base.Should_process_block_as_expected_V6(latestValidHash, blockHash, stateRoot, payloadId, customWithdrawalContractAddress); - [TestCase("0xff020d96d1b4a772fbaae047f094eced81b15ccb1ed9b538c90ab75f4f39742d", "0xac3989a5349b5efc7f2f6847e76c4d6d4c5fcbf54939c80b05b57142ae1236fb", "0xa666ed23428011d2a577df5a065c19861495f61e8d5d4c6298fbe2d34c211059", false, false)] + [TestCase("0x14d7d22cfaa851f3b79a790d6f961f0cc4da2e714cd15b16bce8468f25152911", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0x3e98244425fbc5413150a01fd823bece9ae66ef182f11597f0abdfd251d9aa16", false, false)] public override async Task NewPayloadV5_accepts_valid_BAL(string? blockHash, string? receiptsRoot, string? stateRoot, bool eip8037Enabled, bool useEnginePipeline) => await NewPayloadV5_via_manual_block(blockHash, receiptsRoot, stateRoot, customWithdrawalContractAddress: _auraWithdrawalContractAddress); @@ -98,10 +98,10 @@ public override async Task NewPayloadV5_accepts_valid_BAL(string? blockHash, str public override Task NewPayloadV5_rejects_invalid_BAL_after_processing(string blockHash, string stateRoot, string invalidBalHash, string expectedBalHash, string? customWithdrawalContractAddress) => base.NewPayloadV5_rejects_invalid_BAL_after_processing(blockHash, stateRoot, invalidBalHash, expectedBalHash, customWithdrawalContractAddress); - [TestCase("0xf23d9e6ccefd3f1223c05cff771c8e733040202871992257c8257cb629d95ee2", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.IncorrectChange)] - [TestCase("0x1b5f2d1e50a4c6322dff93847871a743b6d11c8e7b5218cc9547fe377709561f", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.MissingChange)] - [TestCase("0xe4a4bcd80d82527450d8ced83aa14aa0851d52618fa491bd4218d31c7257f00d", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusChange)] - [TestCase("0x4d85109195f43e0c29ba4d0a403081948fe0e29d0aa57379fc61fe4cea2820ac", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusReads)] + [TestCase("0x5ab84199bdbe0d5806de6bffbbd52cf31ede2248f842395aa9a850a45ad9f4db", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.IncorrectChange)] + [TestCase("0x56f188e232e95462ad7235ca53b336f5f73cc208992d307033210c085ea6f959", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.MissingChange)] + [TestCase("0x1625b8215c5d6ab493105efb8cc20b7409d4957ca46d98996c6cc01e50b69ab3", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusChange)] + [TestCase("0x91e03d0f1b756f6577cab73c9f910f9b18fbe45ac27bb346ada0fa912a71dac8", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0xd2e92dcdc98864f0cf2dbe7112ed1b0246c401eff3b863e196da0bfb0dec8e3b", false, false, BalErrorKind.SurplusReads)] public override Task NewPayloadV5_rejects_invalid_BAL_early(string? blockHash, string? receiptsRoot, string? stateRoot, bool eip8037Enabled, bool useEnginePipeline, BalErrorKind errorKind) => NewPayloadV5_via_manual_block(blockHash, receiptsRoot, stateRoot, GetExpectedBalError(errorKind), errorKind, customWithdrawalContractAddress: _auraWithdrawalContractAddress); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs index 202b352add64..ce15424a7741 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V6.cs @@ -199,7 +199,7 @@ public virtual async Task Should_process_block_as_expected_V6( } - [TestCase("0x6b27ccfc34cb820499507cdb9a995b99076530865f8fa3f566bef04616696717", "0xac3989a5349b5efc7f2f6847e76c4d6d4c5fcbf54939c80b05b57142ae1236fb", "0x037cf8a53c12d06101bdca6d35e8541f5160a481f79f7bfacc7e9db5efe29a48", false, false)] + [TestCase("0x0981253ff1b66ee40650f7fa7efe53f772bc11bd4fef3a3574cf91495a1533dd", "0x3d4548dff4e45f6e7838b223bf9476cd5ba4fd05366e8cb4e6c9b65763209569", "0x42a80ba6d5783c392ffcc6b3c15d7ef06be8ae71c2ff5f42377acdec67a5766c", false, false)] [TestCase(null, null, null, false, true)] [TestCase("0xc7ca0c8c9d0b29e9c432d34bcc6b0dd5adef6732ed94096465847ade2da72aae", "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "0xfad798172a2bbd423c90a023d345c7a7812e067918edb7630c2388736f197f29", true, false)] [TestCase("0xc7ca0c8c9d0b29e9c432d34bcc6b0dd5adef6732ed94096465847ade2da72aae", "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "0xfad798172a2bbd423c90a023d345c7a7812e067918edb7630c2388736f197f29", true, true)] @@ -306,10 +306,10 @@ protected static IEnumerable InvalidBalEarlyTestCases() { (string blockHash, BalErrorKind errorKind)[] perKindCases = [ - ("0x156c33a4bbaaf1897ca35e10da9ad62eb3f17916de93faf8978de3f8e825c82c", BalErrorKind.IncorrectChange), - ("0xd8438b041f741b31cf32f22fa1b260873d6705fef298766d3a8b7a56dd2d1aea", BalErrorKind.MissingChange), - ("0xdb032fbc4d225916a9bd8707ead4bb0d1d440dc08c87d67fb4e8ae3a2ed52b15", BalErrorKind.SurplusChange), - ("0xbdf40c921b753e220ff3075e10f62c0abc1b9462a2dd842b103b6807e3060b9e", BalErrorKind.SurplusReads), + ("0x2753a5a3fe321381e637a7c0d7673b61555a366bdf75359616b0035f9b405fab", BalErrorKind.IncorrectChange), + ("0x9f19c60fe32bb002e4b959abddd1ebfd396ddae2e65e9ff87b1c4a0715ade9ad", BalErrorKind.MissingChange), + ("0x383a5a61b956150bc79762844dc40395c9f85e9caae8930a0de2b9e687902eae", BalErrorKind.SurplusChange), + ("0x66478724575325c99be695cc33d2698b6c87bdc7fe4ee0a54813de367f2bf037", BalErrorKind.SurplusReads), ]; foreach ((string blockHash, BalErrorKind errorKind) in perKindCases) @@ -551,8 +551,8 @@ protected async Task NewPayloadV5_via_manual_block( using MergeTestBlockchain chain = await CreateBlockchain(Amsterdam.NoEip8037Instance); IEngineRpcModule rpc = chain.EngineRpcModule; - const long gasUsed = 167352; - const long gasUsedBeforeFinal = 92112; + const long gasUsed = 167340; + const long gasUsedBeforeFinal = 92100; const ulong gasPrice = 2; const long gasLimit = 100000; const ulong timestamp = 1000000; From 331535ef6e0299fc89d96f990a038a2a9341011f Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 01:02:47 +0530 Subject: [PATCH 08/60] fix build and tests --- .../TrieWarmerTests.cs | 20 ++++++++++++++++--- .../CompactionSchedule.cs | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.State.Flat.Test/TrieWarmerTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/TrieWarmerTests.cs index 3930914f4bca..ea9c91bda429 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/TrieWarmerTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/TrieWarmerTests.cs @@ -35,6 +35,7 @@ public void SetUp() _config = new FlatDbConfig { TrieWarmerWorkerCount = 2 }; } + [Test] public async Task PushAddressJob_CallsWarmUpStateTrie() { @@ -91,12 +92,12 @@ public async Task PushAddressJob_AfterProcessorIdle_ProcessesNextJob() Address address = new("0x2222222222222222222222222222222222222222"); Assert.That(warmer.PushAddressJob(addressWarmer, address, sequenceId: 1), Is.True); - await Eventually.AssertAsync(() => Assert.That(addressWarmer.Calls, Is.EqualTo(1))); + await WaitForConditionAsync(() => addressWarmer.Calls == 1, "addressWarmer.Calls should be 1"); await Task.Delay(50); Assert.That(warmer.PushAddressJob(addressWarmer, address, sequenceId: 2), Is.True); - await Eventually.AssertAsync(() => Assert.That(addressWarmer.Calls, Is.EqualTo(2))); + await WaitForConditionAsync(() => addressWarmer.Calls == 2, "addressWarmer.Calls should be 2"); await warmer.DisposeAsync(); } @@ -124,7 +125,7 @@ public async Task PushSlotJobMpmc_Bursts_FanOutWithoutExceedingWorkerCount() Assert.That(storageWarmer.MaxConcurrency, Is.LessThanOrEqualTo(WorkerCount)); storageWarmer.Release(); - await Eventually.AssertAsync(() => Assert.That(storageWarmer.Calls, Is.EqualTo(JobCount))); + await WaitForConditionAsync(() => storageWarmer.Calls == JobCount, $"storageWarmer.Calls should be {JobCount}"); } finally { @@ -275,4 +276,17 @@ public enum SlotPushMode Spmc, Mpmc } + + private static async Task WaitForConditionAsync(Func condition, string message, int timeoutMs = 1000) + { + int delay = 10; + int elapsed = 0; + while (elapsed < timeoutMs) + { + if (condition()) return; + await Task.Delay(delay); + elapsed += delay; + } + Assert.Fail(message); + } } diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index da270db10357..46a3dcb5de25 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -68,7 +68,7 @@ private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger if (config.CompactionOffset >= 0) { if (logger.IsInfo) logger.Info($"Using configured FlatDb compaction offset {config.CompactionOffset}"); - return config.CompactionOffset; + return (ulong)config.CompactionOffset; } if (config.RegenerateCompactionOffset) From d33b214741d4ade18f16fd2d1437b82afe26f00f Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 02:46:39 +0530 Subject: [PATCH 09/60] fix tests --- .../Validators/HeaderValidatorTests.cs | 17 +- .../Validators/HeaderValidator.cs | 9 +- .../Nethermind.Evm.Test/VmStateTests.cs | 304 ++++++++++++------ .../Modules/DebugRpcModuleTests.TraceBlock.cs | 64 ++-- .../DebugRpcModuleTests.TraceTransaction.cs | 14 +- .../Eth/EthRpcModuleTests.EstimateGas.cs | 6 +- .../Modules/Eth/EthRpcModuleTests.cs | 26 +- .../EthSimulateTestsBlocksAndTransactions.cs | 2 +- .../Modules/TraceRpcModuleTests.cs | 6 +- 9 files changed, 294 insertions(+), 154 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index 7e80273e05ed..b11153be096b 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -241,13 +241,13 @@ public void When_gas_limit_is_long_max_value() { _validator = new HeaderValidator(_blockTree, _ethash, _specProvider, new OneLoggerLogManager(new(_testLogger))); _parentBlock = Build.A.Block.WithDifficulty(1) - .WithGasLimit(ulong.MaxValue) + .WithGasLimit(long.MaxValue) .WithNumber(5) .TestObject; _block = Build.A.Block.WithParent(_parentBlock) .WithDifficulty(131072) .WithMixHash(new Hash256("0xd7db5fdd332d3a65d6ac9c4c530929369905734d3ef7a91e373e81d0f010b8e8")) - .WithGasLimit(ulong.MaxValue) + .WithGasLimit(long.MaxValue) .WithNumber(_parentBlock.Number + 1) .WithNonce(0).TestObject; _block.Header.Hash = _block.CalculateHash(); @@ -342,6 +342,19 @@ public void When_given_parent_is_wrong() Assert.That(error, Does.StartWith("Mismatched parent")); } + [Test] + public void Validate_does_not_mutate_parent_header_on_mismatch() + { + _block.Header.Hash = _block.CalculateHash(); + BlockHeader parentHeader = Build.A.BlockHeader.WithNonce(999).TestObject; + parentHeader.SlotNumber = null; + + bool result = _validator.Validate(_block.Header, parentHeader, false, out string? error); + + Assert.That(result, Is.False); + Assert.That(parentHeader.SlotNumber, Is.Null); + } + [Test] public void BaseFee_validation_must_not_be_bypassed_for_NoProof_seal_engine() { diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index c8e7eb1df155..054a5e8d3afc 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -191,7 +191,6 @@ protected virtual bool ValidateParent(BlockHeader header, BlockHeader? parent, r else if (parent.Hash != header.ParentHash) { error = BlockErrorMessages.MismatchedParent(header.Hash!, header.ParentHash!, parent.Hash!); - parent.SlotNumber = 0; return false; } @@ -240,6 +239,14 @@ protected virtual bool ValidateGasLimitRange(BlockHeader header, BlockHeader par // Gas-limit-vs-parent comparisons don't apply at genesis, so skip them. if (parent is null) return true; + // Ethereum protocol hard-caps block gas limit at 2^63-1 to prevent overflow and ensure compatibility with signed 64-bit systems. + if (header.GasLimit > 0x7FFFFFFFFFFFFFFF) + { + if (_logger.IsWarn) _logger.Warn($"Invalid block header ({header.Hash}) - gas limit higher than 2^63-1. Gas limit: {header.GasLimit}"); + error = BlockErrorMessages.InvalidGasLimit; + return false; + } + ulong adjustedParentGasLimit = Eip1559GasLimitAdjuster.AdjustGasLimit(spec, parent.GasLimit, header.Number); ulong maxGasLimitDifference = adjustedParentGasLimit / spec.GasLimitBoundDivisor; diff --git a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs index 3c8513823a3c..c746e1cf27c4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Threading.Tasks; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; @@ -15,209 +17,327 @@ public class VmStateTests [Test] public void Things_are_cold_to_start_with() { - VmState vmState = CreateEvmState(); - StorageCell storageCell = new(TestItem.AddressA, 1); - Assert.That(vmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); - Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.True); + using VmState vmState = CreateEvmState(); + try + { + StorageCell storageCell = new(TestItem.AddressA, 1); + Assert.That(vmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); + Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.True); + } + finally + { + vmState.Env.Dispose(); + } } [Test] public void Can_warm_address_up_twice() { - VmState vmState = CreateEvmState(); - Address address = TestItem.AddressA; - vmState.AccessTracker.WarmUp(address); - vmState.AccessTracker.WarmUp(address); - Assert.That(vmState.AccessTracker.IsCold(address), Is.False); + using VmState vmState = CreateEvmState(); + try + { + Address address = TestItem.AddressA; + vmState.AccessTracker.WarmUp(address); + vmState.AccessTracker.WarmUp(address); + Assert.That(vmState.AccessTracker.IsCold(address), Is.False); + } + finally + { + vmState.Env.Dispose(); + } } [Test] public void Can_warm_up_many() { - VmState vmState = CreateEvmState(); - for (int i = 0; i < TestItem.Addresses.Length; i++) + using VmState vmState = CreateEvmState(); + try { - vmState.AccessTracker.WarmUp(TestItem.Addresses[i]); - vmState.AccessTracker.WarmUp(new StorageCell(TestItem.Addresses[i], 1)); + for (int i = 0; i < TestItem.Addresses.Length; i++) + { + vmState.AccessTracker.WarmUp(TestItem.Addresses[i]); + vmState.AccessTracker.WarmUp(new StorageCell(TestItem.Addresses[i], 1)); + } + + for (int i = 0; i < TestItem.Addresses.Length; i++) + { + Assert.That(vmState.AccessTracker.IsCold(TestItem.Addresses[i]), Is.False); + Assert.That(vmState.AccessTracker.IsCold(new StorageCell(TestItem.Addresses[i], 1)), Is.False); + } } - - for (int i = 0; i < TestItem.Addresses.Length; i++) + finally { - Assert.That(vmState.AccessTracker.IsCold(TestItem.Addresses[i]), Is.False); - Assert.That(vmState.AccessTracker.IsCold(new StorageCell(TestItem.Addresses[i], 1)), Is.False); + vmState.Env.Dispose(); } } [Test] public void Can_warm_storage_up_twice() { - VmState vmState = CreateEvmState(); - Address address = TestItem.AddressA; - StorageCell storageCell = new(address, 1); - vmState.AccessTracker.WarmUp(storageCell); - vmState.AccessTracker.WarmUp(storageCell); - Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.False); + using VmState vmState = CreateEvmState(); + try + { + Address address = TestItem.AddressA; + StorageCell storageCell = new(address, 1); + vmState.AccessTracker.WarmUp(storageCell); + vmState.AccessTracker.WarmUp(storageCell); + Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.False); + } + finally + { + vmState.Env.Dispose(); + } } [Test] public void Nothing_to_commit() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try + { + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.CommitToParent(parentVmState); + } + } + finally { - vmState.CommitToParent(parentVmState); + parentVmState.Env.Dispose(); } } [Test] public void Nothing_to_restore() { - VmState parentVmState = CreateEvmState(); - using VmState vmState = CreateEvmState(parentVmState); + using VmState parentVmState = CreateEvmState(); + try + { + using VmState vmState = CreateEvmState(parentVmState); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Address_to_commit_keeps_it_warm() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.WarmUp(TestItem.AddressA); - vmState.CommitToParent(parentVmState); - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.WarmUp(TestItem.AddressA); + vmState.CommitToParent(parentVmState); + } - Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.False); + Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.False); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Address_to_restore_keeps_it_cold() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.WarmUp(TestItem.AddressA); - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.WarmUp(TestItem.AddressA); + } - Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); + Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Storage_to_commit_keeps_it_warm() { - VmState parentVmState = CreateEvmState(); - StorageCell storageCell = new(TestItem.AddressA, 1); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.WarmUp(storageCell); - vmState.CommitToParent(parentVmState); + StorageCell storageCell = new(TestItem.AddressA, 1); + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.WarmUp(storageCell); + vmState.CommitToParent(parentVmState); + } + + Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.False); + } + finally + { + parentVmState.Env.Dispose(); } - - Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.False); } [Test] public void Storage_to_restore_keeps_it_cold() { - VmState parentVmState = CreateEvmState(); - StorageCell storageCell = new(TestItem.AddressA, 1); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.WarmUp(storageCell); - } + StorageCell storageCell = new(TestItem.AddressA, 1); + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.WarmUp(storageCell); + } - Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.True); + Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.True); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Logs_are_committed() { - VmState parentVmState = CreateEvmState(); - LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.Logs.Add(logEntry); - vmState.CommitToParent(parentVmState); + LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.Logs.Add(logEntry); + vmState.CommitToParent(parentVmState); + } + + Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.True); + } + finally + { + parentVmState.Env.Dispose(); } - - Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.True); } [Test] public void Logs_are_restored() { - VmState parentVmState = CreateEvmState(); - LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.Logs.Add(logEntry); - } + LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.Logs.Add(logEntry); + } - Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.False); + Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.False); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Destroy_list_is_committed() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.ToBeDestroyed(Address.Zero); - vmState.CommitToParent(parentVmState); - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.ToBeDestroyed(Address.Zero); + vmState.CommitToParent(parentVmState); + } - Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.True); + Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.True); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Destroy_list_is_restored() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.AccessTracker.ToBeDestroyed(Address.Zero); - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.AccessTracker.ToBeDestroyed(Address.Zero); + } - Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.False); + Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.False); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Commit_adds_refunds() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.Refund = 333; - vmState.CommitToParent(parentVmState); - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.Refund = 333; + vmState.CommitToParent(parentVmState); + } - Assert.That(parentVmState.Refund, Is.EqualTo(333)); + Assert.That(parentVmState.Refund, Is.EqualTo(333)); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Restore_does_not_add_refunds() { - VmState parentVmState = CreateEvmState(); - using (VmState vmState = CreateEvmState(parentVmState)) + using VmState parentVmState = CreateEvmState(); + try { - vmState.Refund = 333; - } + using (VmState vmState = CreateEvmState(parentVmState)) + { + vmState.Refund = 333; + } - Assert.That(parentVmState.Refund, Is.EqualTo(0)); + Assert.That(parentVmState.Refund, Is.EqualTo(0)); + } + finally + { + parentVmState.Env.Dispose(); + } } [Test] public void Can_dispose_without_init() { - VmState vmState = CreateEvmState(); - vmState.Dispose(); + using VmState vmState = CreateEvmState(); + vmState.Env.Dispose(); } [Test] public void Can_dispose_after_init() { - VmState vmState = CreateEvmState(); - vmState.InitializeStacks(default, out EvmStack _); - vmState.Dispose(); + using VmState vmState = CreateEvmState(); + try + { + vmState.InitializeStacks(default, out EvmStack _); + } + finally + { + vmState.Env.Dispose(); + } } private static VmState CreateEvmState(VmState parentVmState = null, bool isContinuation = false) => diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs index f5b5b5fc3d43..26aad0db677e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceBlock.cs @@ -119,42 +119,42 @@ private static IEnumerable TraceBlockSource() "result": [ { "result": { - "gas": 88468, + "gas": 87700, "failed": false, "returnValue": "0x", "structLogs": [ - { "pc": 0, "op": "PUSH32", "gas": 45768, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 33, "op": "PUSH1", "gas": 45765, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000"], "storage": {} }, - { "pc": 35, "op": "MSTORE", "gas": 45762, "gasCost": 6, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000", "0x0"], "storage": {} }, - { "pc": 36, "op": "PUSH32", "gas": 45756, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 69, "op": "PUSH1", "gas": 45753, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 71, "op": "PUSH1", "gas": 45750, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6"], "storage": {} }, - { "pc": 73, "op": "PUSH1", "gas": 45747, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0"], "storage": {} }, - { "pc": 75, "op": "CREATE2", "gas": 45744, "gasCost": 32006, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0", "0x0"], "storage": {} }, - { "pc": 0, "op": "PUSH1", "gas": 13524, "gasCost": 3, "depth": 2, "error": null, "stack": [], "storage": {} }, - { "pc": 2, "op": "PUSH1", "gas": 13521, "gasCost": 3, "depth": 2, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 4, "op": "SSTORE", "gas": 13518, "gasCost": 2200, "depth": 2, "error": null, "stack": ["0x0", "0x20"], "storage": {} }, - { "pc": 5, "op": "STOP", "gas": 11318, "gasCost": 0, "depth": 2, "error": null, "stack": [], "storage": {} }, - { "pc": 76, "op": "STOP", "gas": 11532, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} } + { "pc": 0, "op": "PUSH32", "gas": 46536, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 33, "op": "PUSH1", "gas": 46533, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000"], "storage": {} }, + { "pc": 35, "op": "MSTORE", "gas": 46530, "gasCost": 6, "depth": 1, "error": null, "stack": ["0x6000602055000000000000000000000000000000000000000000000000000000", "0x0"], "storage": {} }, + { "pc": 36, "op": "PUSH32", "gas": 46524, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 69, "op": "PUSH1", "gas": 46521, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 71, "op": "PUSH1", "gas": 46518, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6"], "storage": {} }, + { "pc": 73, "op": "PUSH1", "gas": 46515, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0"], "storage": {} }, + { "pc": 75, "op": "CREATE2", "gas": 46512, "gasCost": 32006, "depth": 1, "error": null, "stack": ["0x0", "0x6", "0x0", "0x0"], "storage": {} }, + { "pc": 0, "op": "PUSH1", "gas": 14280, "gasCost": 3, "depth": 2, "error": null, "stack": [], "storage": {} }, + { "pc": 2, "op": "PUSH1", "gas": 14277, "gasCost": 3, "depth": 2, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 4, "op": "SSTORE", "gas": 14274, "gasCost": 2200, "depth": 2, "error": null, "stack": ["0x0", "0x20"], "storage": {} }, + { "pc": 5, "op": "STOP", "gas": 12074, "gasCost": 0, "depth": 2, "error": null, "stack": [], "storage": {} }, + { "pc": 76, "op": "STOP", "gas": 12300, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} } ] }, "txHash": "0xb5a78a1eda0ae98d4f62eec3e0b7f5bf81810cd57bc75006b611982667bcdbe7" }, { "result": { - "gas": 56213, + "gas": 56141, "failed": false, "returnValue": "0x", "structLogs": [ - { "pc": 0, "op": "PUSH1", "gas": 46408, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, - { "pc": 2, "op": "PUSH1", "gas": 46405, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, - { "pc": 4, "op": "PUSH1", "gas": 46402, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0"], "storage": {} }, - { "pc": 6, "op": "PUSH1", "gas": 46399, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 8, "op": "PUSH1", "gas": 46396, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 10, "op": "PUSH20", "gas": 46393, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0"], "storage": {} }, - { "pc": 31, "op": "PUSH3", "gas": 46390, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} }, - { "pc": 35, "op": "CALL", "gas": 46387, "gasCost": 45703, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "0x186a0"], "storage": {} }, - { "pc": 36, "op": "STOP", "gas": 43787, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x1"], "storage": {} } + { "pc": 0, "op": "PUSH1", "gas": 46480, "gasCost": 3, "depth": 1, "error": null, "stack": [], "storage": {} }, + { "pc": 2, "op": "PUSH1", "gas": 46477, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0"], "storage": {} }, + { "pc": 4, "op": "PUSH1", "gas": 46474, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0"], "storage": {} }, + { "pc": 6, "op": "PUSH1", "gas": 46471, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 8, "op": "PUSH1", "gas": 46468, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 10, "op": "PUSH20", "gas": 46465, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0"], "storage": {} }, + { "pc": 31, "op": "PUSH3", "gas": 46462, "gasCost": 3, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837"], "storage": {} }, + { "pc": 35, "op": "CALL", "gas": 46459, "gasCost": 45774, "depth": 1, "error": null, "stack": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "0x186a0"], "storage": {} }, + { "pc": 36, "op": "STOP", "gas": 43859, "gasCost": 0, "depth": 1, "error": null, "stack": ["0x1"], "storage": {} } ] }, "txHash": "0xdb3d8694a97364e8628aeb18993520ea6bac0b65b02eed1abddaaed1ddd04e7b" @@ -174,11 +174,11 @@ private static IEnumerable TraceBlockSource() "jsonrpc": "2.0", "result": [ { - "result": [45768,45765,45762,45756,45753,45750,45747,45744,13524,13521,13518,11318,11532], + "result": [46536,46533,46530,46524,46521,46518,46515,46512,14280,14277,14274,12074,12300], "txHash": "0xb5a78a1eda0ae98d4f62eec3e0b7f5bf81810cd57bc75006b611982667bcdbe7" }, { - "result": [46408,46405,46402,46399,46396,46393,46390,46387,43787], + "result": [46480,46477,46474,46471,46468,46465,46462,46459,43859], "txHash": "0xdb3d8694a97364e8628aeb18993520ea6bac0b65b02eed1abddaaed1ddd04e7b" } ], @@ -228,7 +228,7 @@ private static IEnumerable TraceBlockSource() "to": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0x15994", + "gasUsed": "0x15694", "input": "0x7f60006020550000000000000000000000000000000000000000000000000000006000527f0000000000000000000000000000000000000000000000000000000000000000600660006000f500", "calls": [ { @@ -236,7 +236,7 @@ private static IEnumerable TraceBlockSource() "from": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "to": "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "value": "0x0", - "gas": "0x34d4", + "gas": "0x37c8", "gasUsed": "0x89e", "input": "0x600060205500" } @@ -251,7 +251,7 @@ private static IEnumerable TraceBlockSource() "to": "0x6b5887043de753ecfa6269f947129068263ffbe2", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0xdb95", + "gasUsed": "0xdb4d", "input": "0x600060006000600060007328156f6fdeeffd5667d51bb8d7d5069a920e0837620186a0f100", "calls": [ { @@ -259,7 +259,7 @@ private static IEnumerable TraceBlockSource() "from": "0x6b5887043de753ecfa6269f947129068263ffbe2", "to": "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837", "value": "0x0", - "gas": "0xa85f", + "gas": "0xa8a6", "gasUsed": "0x0", "input": "0x" } @@ -306,7 +306,7 @@ private static IEnumerable TraceBlockSource() { "result": { "0xb7705ae4c6f81b66cdb323c65f4e8133690fc099": { - "balance": "0x3635c9adc5de9db050", + "balance": "0x3635c9adc5de9db350", "nonce": 4, "code": "0xabcd" }, @@ -314,7 +314,7 @@ private static IEnumerable TraceBlockSource() "balance": "0x0" }, "0x475674cb523a0a2736b7f7534390288fce16982c": { - "balance": "0x24fac" + "balance": "0x24cac" }, "0x28156f6fdeeffd5667d51bb8d7d5069a920e0837": { "balance": "0x0", diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs index c935b7554d12..56e84c23f80f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.TraceTransaction.cs @@ -192,14 +192,14 @@ private static IEnumerable TraceTransactionContractSource() { "jsonrpc": "2.0", "result": { - "gas": 55302, + "gas": 55278, "failed": false, "returnValue": "0x", "structLogs": [ { "pc": 0, "op": "PUSH1", - "gas": 46904, + "gas": 46928, "gasCost": 3, "depth": 1, "error": null, @@ -209,7 +209,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 2, "op": "PUSH1", - "gas": 46901, + "gas": 46925, "gasCost": 3, "depth": 1, "error": null, @@ -221,7 +221,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 4, "op": "SSTORE", - "gas": 46898, + "gas": 46922, "gasCost": 2200, "depth": 1, "error": null, @@ -234,7 +234,7 @@ private static IEnumerable TraceTransactionContractSource() { "pc": 5, "op": "STOP", - "gas": 44698, + "gas": 44722, "gasCost": 0, "depth": 1, "error": null, @@ -252,7 +252,7 @@ private static IEnumerable TraceTransactionContractSource() yield return new TestCaseData( contractTransaction, new GethTraceOptions { Tracer = "{gasUsed: [], step: function(log) { this.gasUsed.push(log.getGas()); }, result: function() { return this.gasUsed; }, fault: function(){}}" }, - """{"jsonrpc":"2.0","result":[46904,46901,46898,44698],"id":67}""" + """{"jsonrpc":"2.0","result":[46928,46925,46922,44722],"id":67}""" ) { TestName = "Contract with javaScriptTracer" }; @@ -275,7 +275,7 @@ private static IEnumerable TraceTransactionContractSource() "to": "0x0ffd3e46594919c04bcfd4e146203c8255670828", "value": "0x1", "gas": "0x186a0", - "gasUsed": "0xd806", + "gasUsed": "0xd7ee", "input": "0x600060205500" }, "id": 67 diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs index 2e41224cd56d..53f30d6dca8d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs @@ -215,7 +215,7 @@ public async Task Estimate_gas_with_base_fee_opcode() $"{{\"from\": \"{SecondaryTestAddress}\", \"type\": \"0x2\", \"data\": \"{dataStr}\"}}"); string serialized = await ctx.Test.TestEthRpc("eth_estimateGas", transaction); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0xe8a9\",\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0xe891\",\"id\":67}")); } [Test] @@ -333,13 +333,13 @@ public async Task should_estimate_transaction_with_deployed_code_when_eip3607_en "Executes code from state override", """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0xc200000000000000000000000000000000000000","input":"0x60fe47b1112233445566778899001122334455667788990011223344556677889900112233445566778899001122"}""", """{"0xc200000000000000000000000000000000000000":{"code":"0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632a1afcd914603457806360fe47b114604d575b5f80fd5b603b5f5481565b60405190815260200160405180910390f35b605c6058366004605e565b5f55565b005b5f60208284031215606d575f80fd5b503591905056fea2646970667358221220fd4e5f3894be8e57fc7460afebb5c90d96c3486d79bf47b00c2ed666ab2f82b364736f6c634300081a0033"}}""", - """{"jsonrpc":"2.0","result":"0xac0d","id":67}""" // Store uint256 (cold access) + few other light instructions + intrinsic transaction cost + """{"jsonrpc":"2.0","result":"0xabdd","id":67}""" // Store uint256 (cold access) + few other light instructions + intrinsic transaction cost )] [TestCase( "Executes precompile using overridden address", """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0xc200000000000000000000000000000000000000","input":"0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4000000000000000000000000000000000000000000000000000000000000001C7B8B1991EB44757BC688016D27940DF8FB971D7C87F77A6BC4E938E3202C44037E9267B0AEAA82FA765361918F2D8ABD9CDD86E64AA6F2B81D3C4E0B69A7B055"}""", """{"0x0000000000000000000000000000000000000001":{"movePrecompileToAddress":"0xc200000000000000000000000000000000000000", "code": "0x"}}""", - """{"jsonrpc":"2.0","result":"0x6608","id":67}""" // ECRecover call + intrinsic transaction cost + """{"jsonrpc":"2.0","result":"0x6440","id":67}""" // ECRecover call + intrinsic transaction cost )] public async Task Estimate_gas_with_state_override(string name, string transactionJson, string stateOverrideJson, string expectedResult) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index cfcc2597093f..c679052af3e1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -1315,10 +1315,10 @@ public async Task Eth_tx_count_by_number(string blockParameter, string expectedR Assert.That(serialized, Is.EqualTo($"{{\"jsonrpc\":\"2.0\",\"result\":{expectedResult},\"id\":67}}")); } - [TestCase(false, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xfe8fcd8ff04b74f0c044d2cd424bea426591ea069e839eae3f4e7743c92fa389\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(false, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0xfe8fcd8ff04b74f0c044d2cd424bea426591ea069e839eae3f4e7743c92fa389\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, false, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x16af125b31ba6f33725bffd77d8778121c8b24c3c29a9821d2fc15049a5bdcb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, true, "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x16af125b31ba6f33725bffd77d8778121c8b24c3c29a9821d2fc15049a5bdcb6\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x21b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"step\":0,\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] public async Task Eth_get_block_by_hash(bool aura, bool eip1559, string expected) { using Context ctx = eip1559 ? await Context.CreateWithLondonEnabled() : await Context.Create(); @@ -1344,13 +1344,13 @@ public async Task Eth_get_block_by_hash_with_tx(string blockParameter, bool with Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expectedResult)).Using(JToken.EqualityComparer)); } - [TestCase(false, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[{\"hash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"nonce\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x0\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"},{\"hash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"nonce\":\"0x2\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"}],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "pending", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":null,\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":null,\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[{\"hash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"nonce\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x0\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"},{\"hash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"nonce\":\"0x2\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"blockTimestamp\":\"0x5e47e919\",\"transactionIndex\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"input\":\"0x\",\"chainId\":\"0x1\",\"type\":\"0x0\",\"v\":\"0x25\",\"s\":\"0x575361bb330bf38b9a89dd8279d42a20d34edeaeede9739a7c2bdcbe3242d7bb\",\"r\":\"0xe7c5ff3cba254c4fe8f9f12c3f202150bb9a0aebeee349ff2f4acb23585f56bd\"}],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] - [TestCase(false, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x7a1200\",\"gasUsed\":\"0x0\",\"hash\":\"0x16b111d85efa64c1c8e27f1e59c8ccd6bb6643b1999628ac37294c31158e2245\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x761cfe357802c8a2a68e37ad8325607920e72ce19b5b0d3e1ba01840f7e905ec\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x20b\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"baseFeePerGas\":\"0x2da282a8\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] - [TestCase(true, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(false, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x7a1200\",\"gasUsed\":\"0x0\",\"hash\":\"0x16b111d85efa64c1c8e27f1e59c8ccd6bb6643b1999628ac37294c31158e2245\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x761cfe357802c8a2a68e37ad8325607920e72ce19b5b0d3e1ba01840f7e905ec\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x20b\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"baseFeePerGas\":\"0x2da282a8\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase(true, "0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"baseFeePerGas\":\"0x0\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase(false, "0x20", "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}")] public async Task Eth_get_block_by_number(bool eip1559, string blockParameter, string expectedResult) { @@ -1359,10 +1359,10 @@ public async Task Eth_get_block_by_number(bool eip1559, string blockParameter, s Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expectedResult)).Using(JToken.EqualityComparer)); } - [TestCase("earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase("earliest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase("latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x475674cb523a0a2736b7f7534390288fce16982c\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\"],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] [TestCase("pending", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0x1\",\"extraData\":\"0x4e65746865726d696e64\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0xa410\",\"hash\":null,\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":null,\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":null,\"number\":\"0x3\",\"parentHash\":\"0x49e7d7466be0927347ff2f654c014a768b5a5fcd8c483635210466dd0d6d204c\",\"receiptsRoot\":\"0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x2cb\",\"stateRoot\":\"0x4e786afc8bed76b7299973ca70022b367cbb94c14ec30e9e7273b31b6b968de9\",\"totalDifficulty\":\"0xf4243\",\"timestamp\":\"0x5e47e919\",\"transactions\":[\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\"],\"transactionsRoot\":\"0x2e6e6deb19d24bd48eda6071ab38b1bae64c15ef1998c96f0d153711d3a3efc7\",\"uncles\":[]},\"id\":67}")] - [TestCase("0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] + [TestCase("0x0", "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x201\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"totalDifficulty\":\"0xf4240\",\"timestamp\":\"0xf4240\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":67}")] [TestCase("0x20", "{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":67}")] public async Task Eth_get_block_by_number_no_details(string blockParameter, string expectedResult) { @@ -1477,7 +1477,7 @@ public async Task EthGetHeaderByNumber_WhenEarliest_MatchesExpectedJson() string serialized = await ctx.Test.TestEthRpc("eth_getHeaderByNumber", "earliest"); // Same value set as the genesis row in Eth_get_block_by_number "earliest", minus // size/totalDifficulty/transactions/uncles (header endpoint excludes body-level fields). - const string expected = "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x39113894e6229a7b119912771642978fa575d68375a47a88729d119ff5f0f9df\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"stateRoot\":\"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f\",\"timestamp\":\"0xf4240\",\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\"},\"id\":67}"; + const string expected = "{\"jsonrpc\":\"2.0\",\"result\":{\"difficulty\":\"0xf4240\",\"extraData\":\"0x010203\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"hash\":\"0x2167088a0f0de66028d2b728235af6d467108c1750c3e11a8f6e6cd60fddb0e4\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x00000000000003e8\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"stateRoot\":\"0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f\",\"timestamp\":\"0xf4240\",\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\"},\"id\":67}"; Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse(expected)).Using(JToken.EqualityComparer)); } @@ -1685,7 +1685,7 @@ public async Task Eth_get_block_by_number_with_recovering_sender_from_receipts() ctx.Test = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).WithBlockFinder(blockFinder).WithReceiptFinder(receiptFinder).Build(); string serialized = await ctx.Test.TestEthRpc("eth_getBlockByNumber", TestItem.KeccakA.ToString(), "true"); - Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse("""{"jsonrpc":"2.0","result":{"difficulty":"0xf4240","extraData":"0x010203","gasLimit":"0x3d0900","gasUsed":"0x0","hash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2","nonce":"0x00000000000003e8","number":"0x1","parentHash":"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x221","stateRoot":"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f","timestamp":"0xf4240","transactions":[{"nonce":"0x0","blockHash":"0xe3026a6708b90d5cb25557ac38ddc3f5ef550af10f31e1cf771524da8553fa1c","blockNumber":"0x1","blockTimestamp":"0xf4240","transactionIndex":"0x0","from":"0x2d36e6c27c34ea22620e7b7c45de774599406cf3","to":"0x0000000000000000000000000000000000000000","value":"0x1","gasPrice":"0x1","gas":"0x5208","input":"0x","type":"0x0","v":"0x0","r":"0x0","s":"0x0","hash":null}],"transactionsRoot":"0x29cc403075ed3d1d6af940d577125cc378ee5a26f7746cbaf87f1cf4a38258b5","uncles":[]},"id":67}""")).Using(JToken.EqualityComparer)); + Assert.That(JToken.Parse(serialized), Is.EqualTo(JToken.Parse("""{"jsonrpc":"2.0","result":{"difficulty":"0xf4240","extraData":"0x010203","gasLimit":"0x3d0900","gasUsed":"0x0","hash":"0xd0b838318d6d90b04addc0ba3600a2c21ce390f0f2eacc73eb88c37c23df20fb","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2","nonce":"0x00000000000003e8","number":"0x1","parentHash":"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x221","stateRoot":"0xe4a589578a2838164c89c02e38528d7865b132981a9793a8f0b443fcfe70728f","timestamp":"0xf4240","transactions":[{"nonce":"0x0","blockHash":"0xd0b838318d6d90b04addc0ba3600a2c21ce390f0f2eacc73eb88c37c23df20fb","blockNumber":"0x1","blockTimestamp":"0xf4240","transactionIndex":"0x0","from":"0x2d36e6c27c34ea22620e7b7c45de774599406cf3","to":"0x0000000000000000000000000000000000000000","value":"0x1","gasPrice":"0x1","gas":"0x5208","input":"0x","type":"0x0","v":"0x0","r":"0x0","s":"0x0","hash":null}],"transactionsRoot":"0x29cc403075ed3d1d6af940d577125cc378ee5a26f7746cbaf87f1cf4a38258b5","uncles":[]},"id":67}""")).Using(JToken.EqualityComparer)); } [TestCase(false)] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 04c0b67ba4e8..d64f2283f276 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -157,7 +157,7 @@ public static Transaction GetTransferTxData(ulong nonce, IEthereumEcdsa ethereum Transaction tx = new() { Type = type, - Value = amount > ulong.MaxValue ? ulong.MaxValue : (ulong)amount, + Value = amount, Nonce = nonce, GasLimit = 50_000, SenderAddress = from.Address, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 82eee385e6c6..719c004d9b15 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -522,7 +522,7 @@ public async Task Trace_transaction_with_error_reverted() Assert.That(traces.Data.ElementAt(0).TransactionHash, Is.EqualTo(transaction2.Hash!)); string serialized = new EthereumJsonSerializer().Serialize(traces.Data); - Assert.That(serialized, Is.EqualTo("[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"gas\":\"0x99f4\",\"init\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"value\":\"0x1\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d79\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d02\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeaf4783ec0669f688808a75f3b10dceae95b4f7ec276309defcfada71ccfe5fe\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]"), serialized.Replace("\"", "\\\"")); + Assert.That(serialized, Is.EqualTo("[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"gas\":\"0x9a6c\",\"init\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"value\":\"0x1\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8def\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"callType\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x8d78\",\"input\":\"0x\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"value\":\"0x0\"},\"blockHash\":\"0xeb0d05efb43e565c4a677e64dde4cd1339459310afe8f578acab57ad45dd8f44\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]"), serialized.Replace("\"", "\\\"")); } [Test] public async Task trace_timeout_is_separate_for_rpc_calls() @@ -918,7 +918,7 @@ public async Task Trace_replayBlockTransactions_transactions_deploying_contract( Assert.That(System.Linq.Enumerable.Count(traces.Data), Is.EqualTo(2)); Assert.That(traces.Data.ElementAt(0).Action!.From, Is.EqualTo(traces.Data.ElementAt(1).Action!.From)); string serialized = new EthereumJsonSerializer().Serialize(traces.Data); - Assert.That(serialized, Is.EqualTo("[{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c34\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"code\":\"0x\",\"gasUsed\":\"0x79\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x994d\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0x8513c9083ec27fa8e3ca7e3ffa732d61562e2d17e2e1af6e773bc810dc4c3452\",\"vmTrace\":null},{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c34\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"code\":\"0x\",\"gasUsed\":\"0xa3d\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x8fb0\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0xa6a56c7927deae778a749bcdab7bbf409c0d8a5d2420021a3ba328240ae832d8\",\"vmTrace\":null}]")); + Assert.That(serialized, Is.EqualTo("[{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c70\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"code\":\"0x\",\"gasUsed\":\"0x79\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x9988\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0x8513c9083ec27fa8e3ca7e3ffa732d61562e2d17e2e1af6e773bc810dc4c3452\",\"vmTrace\":null},{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"gas\":\"0x9c70\",\"init\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"value\":\"0x1\"},\"result\":{\"address\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"code\":\"0x\",\"gasUsed\":\"0xa3d\"},\"subtraces\":1,\"traceAddress\":[],\"type\":\"create\"},{\"action\":{\"callType\":\"call\",\"from\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x8feb\",\"input\":\"0x\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"type\":\"call\"}],\"transactionHash\":\"0xa6a56c7927deae778a749bcdab7bbf409c0d8a5d2420021a3ba328240ae832d8\",\"vmTrace\":null}]")); } [Test] @@ -996,7 +996,7 @@ public async Task Trace_replayBlockTransactions_stateDiff() """{"from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","to":"0x0000000000000000000000000000000000123456","input":"0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4000000000000000000000000000000000000000000000000000000000000001C7B8B1991EB44757BC688016D27940DF8FB971D7C87F77A6BC4E938E3202C44037E9267B0AEAA82FA765361918F2D8ABD9CDD86E64AA6F2B81D3C4E0B69A7B055","gas":"0xf4240"}""", "trace", """{"0x0000000000000000000000000000000000000001":{"movePrecompileToAddress":"0x0000000000000000000000000000000000123456", "code": "0x"}}""", - """{"jsonrpc":"2.0","result":{"output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099","stateDiff":null,"trace":[{"action":{"callType":"call","from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","gas":"0xee838","input":"0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4000000000000000000000000000000000000000000000000000000000000001c7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c44037e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055","to":"0x0000000000000000000000000000000000123456","value":"0x0"},"result":{"gasUsed":"0xbb8","output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099"},"subtraces":0,"traceAddress":[],"type":"call"}],"vmTrace":null},"id":67}""" + """{"jsonrpc":"2.0","result":{"output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099","stateDiff":null,"trace":[{"action":{"callType":"call","from":"0x7f554713be84160fdf0178cc8df86f5aabd33397","gas":"0xee9b8","input":"0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4000000000000000000000000000000000000000000000000000000000000001c7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c44037e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055","to":"0x0000000000000000000000000000000000123456","value":"0x0"},"result":{"gasUsed":"0xbb8","output":"0x000000000000000000000000b7705ae4c6f81b66cdb323c65f4e8133690fc099"},"subtraces":0,"traceAddress":[],"type":"call"}],"vmTrace":null},"id":67}""" )] public async Task Trace_call_with_state_override(string name, string transactionJson, string traceType, string stateOverrideJson, string expectedResult) { From 466fd429cf8c66139cefc7e24eb931a9e832ecf1 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 13:57:12 +0530 Subject: [PATCH 10/60] fix Evm and blockchain tests --- .../TransactionProcessorEip7702Tests.cs | 5 ++++- .../Nethermind.Evm.Test/Eip3529Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip8037Tests.cs | 16 ++++++++-------- .../Nethermind.Evm.Test/StateOverridesTests.cs | 6 +++--- .../GasPolicy/EthereumGasPolicy.cs | 8 +++++--- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs index c38aad16bfbb..2dddb557349d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs @@ -834,7 +834,10 @@ public static IEnumerable AccountAccessGasCases() .Done; yield return new TestCaseData( callOpcode, - 34550ul, + GasCostOf.Transaction + + GasCostOf.WarmStateRead + + GasCostOf.ColdAccountAccess + + GasCostOf.VeryLow * 7, true, 100_000ul, false diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs index c07c34ef08c4..9b9759f1404d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3529Tests.cs @@ -148,7 +148,7 @@ public void After_3529_self_destruct_has_zero_refund(bool eip3529Enabled) Transaction tx2 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // self destruct contract Transaction tx3 = Build.A.Transaction.WithCode(byteCode2).WithGasLimit(gasLimit).WithNonce(3).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; - uint gasUsedByTx3 = 37839; + uint gasUsedByTx3 = 37767; ulong blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx0, tx1, tx2, tx3).WithGasLimit(2 * gasLimit).TestObject; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs index 50bbed6bcbe7..5e5c1716c5d7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037Tests.cs @@ -24,17 +24,17 @@ public class Eip8037Tests : VirtualMachineTestsBase private static IEnumerable ConstantsTestCases() { - yield return new TestCaseData(GasCostOf.CostPerStateByte).Returns(1530L).SetName("CostPerStateByte"); - yield return new TestCaseData(GasCostOf.SSetState).Returns(97920L).SetName("SSetState"); - yield return new TestCaseData(GasCostOf.CreateState).Returns(183600L).SetName("CreateState"); - yield return new TestCaseData(GasCostOf.NewAccountState).Returns(183600L).SetName("NewAccountState"); - yield return new TestCaseData(GasCostOf.PerAuthBaseState).Returns(35190L).SetName("PerAuthBaseState"); - yield return new TestCaseData(Eip8037Constants.SystemCallStateReservoir).Returns(1566720L).SetName("SystemCallStateReservoir"); - yield return new TestCaseData(Eip8037Constants.SystemCallGasLimit).Returns(31566720L).SetName("SystemCallGasLimit"); + yield return new TestCaseData(GasCostOf.CostPerStateByte).Returns(1530ul).SetName("CostPerStateByte"); + yield return new TestCaseData(GasCostOf.SSetState).Returns(97920ul).SetName("SSetState"); + yield return new TestCaseData(GasCostOf.CreateState).Returns(183600ul).SetName("CreateState"); + yield return new TestCaseData(GasCostOf.NewAccountState).Returns(183600ul).SetName("NewAccountState"); + yield return new TestCaseData(GasCostOf.PerAuthBaseState).Returns(35190ul).SetName("PerAuthBaseState"); + yield return new TestCaseData(Eip8037Constants.SystemCallStateReservoir).Returns(1566720ul).SetName("SystemCallStateReservoir"); + yield return new TestCaseData(Eip8037Constants.SystemCallGasLimit).Returns(31566720ul).SetName("SystemCallGasLimit"); } [TestCaseSource(nameof(ConstantsTestCases))] - public long Constants_are_calculated_correctly(long actual) => actual; + public ulong Constants_are_calculated_correctly(ulong actual) => actual; [TestCase(1, ExpectedResult = 6ul)] [TestCase(32, ExpectedResult = 6ul)] diff --git a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs index caae3449b13d..3b791fe5d34e 100644 --- a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs @@ -34,9 +34,9 @@ public void SetUp() private static IEnumerable ValidNonceCases() => [ - new TestCaseData((UInt256)ulong.MaxValue).SetName("ulong_max"), - new TestCaseData((UInt256)ulong.MaxValue - 1).SetName("ulong_max_minus_one"), - new TestCaseData(UInt256.Zero).SetName("zero"), + new TestCaseData(ulong.MaxValue).SetName("ulong_max"), + new TestCaseData(ulong.MaxValue - 1).SetName("ulong_max_minus_one"), + new TestCaseData(0ul).SetName("zero"), ]; [TestCaseSource(nameof(ValidNonceCases))] diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 489cb67cb091..cfdd082052b6 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -51,10 +51,11 @@ public static EthereumGasPolicy CreateSystemTransactionAvailableGas(ulong gasLim { if (spec.IsEip8037Enabled) { + ulong reservoir = Math.Min(gasLimit, intrinsicGas.StateReservoir); return new EthereumGasPolicy { - Value = gasLimit - intrinsicGas.StateReservoir, - StateReservoir = intrinsicGas.StateReservoir, + Value = gasLimit - reservoir, + StateReservoir = reservoir, StateGasUsed = intrinsicGas.StateGasUsed, StateGasSpill = 0, }; @@ -128,11 +129,12 @@ public static bool ConsumeStateGas(ref EthereumGasPolicy gas, ulong stateGasCost } ulong spillAmount = stateGasCost - gas.StateReservoir; - if (!UpdateGas(ref gas, spillAmount)) + if (GetRemainingGas(in gas) < spillAmount) { return false; } + Consume(ref gas, spillAmount); gas.StateReservoir = 0; gas.StateGasUsed += stateGasCost; gas.StateGasSpill += spillAmount; From a6fabc504ea9eae897f2f376c97d29fb1e1bb293 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 16:26:33 +0530 Subject: [PATCH 11/60] refactor(evm): introduce `SaturatingSub` helper to simplify `ulong` saturating subtraction --- .../Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index cfdd082052b6..7ac729e17343 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -201,9 +201,12 @@ public static void RevertRefundToHalt(ref EthereumGasPolicy parentGas, in Ethere parentGas.StateGasUsed -= childGas.StateGasUsed; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong SaturatingSub(ulong a, ulong b) => a > b ? a - b : 0UL; + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ulong GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) => - childGas.StateGasSpill > childGas.StateGasSpillRefunded ? childGas.StateGasSpill - childGas.StateGasSpillRefunded : 0UL; + SaturatingSub(childGas.StateGasSpill, childGas.StateGasSpillRefunded); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOutOfGas(in EthereumGasPolicy gas) => gas.OutOfGas; @@ -338,7 +341,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong refundableStateGas = gas.StateGasUsed > stateGasFloor ? gas.StateGasUsed - stateGasFloor : 0UL; + ulong refundableStateGas = SaturatingSub(gas.StateGasUsed, stateGasFloor); ulong appliedRefund = Math.Min(amount, refundableStateGas); if (trackSpillRefund) { @@ -352,7 +355,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong DiscardStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong discardableStateGas = gas.StateGasUsed > stateGasFloor ? gas.StateGasUsed - stateGasFloor : 0UL; + ulong discardableStateGas = SaturatingSub(gas.StateGasUsed, stateGasFloor); ulong appliedRefund = Math.Min(amount, discardableStateGas); if (trackSpillRefund) { @@ -420,7 +423,7 @@ public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, ulong code if (codeInsertRefunds > 0UL && spec.IsEip8037Enabled) { ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * codeInsertRefunds); - ulong refundFloor = stateGasFloor > stateGasRefund ? stateGasFloor - stateGasRefund : 0UL; + ulong refundFloor = SaturatingSub(stateGasFloor, stateGasRefund); RefundStateGas(ref gas, stateGasRefund, refundFloor, trackSpillRefund: false); } @@ -515,7 +518,7 @@ public static EthereumGasPolicy CreateAvailableFromIntrinsic(ulong gasLimit, in { // EIP-8037: cap gas_left at TX_MAX_GAS_LIMIT - intrinsic_regular, overflow goes to reservoir ulong maxGasLeft = Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value; - reservoir = executionGas > maxGasLeft ? executionGas - maxGasLeft : 0UL; + reservoir = SaturatingSub(executionGas, maxGasLeft); executionGas -= reservoir; } From dbb796c2303058f1643df5832d5e738adc558ac8 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 16:42:04 +0530 Subject: [PATCH 12/60] fix blockchain tests --- .../Nethermind.Blockchain.Test/BlockchainProcessorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs index 7838eeef4d8d..fc49728b6281 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs @@ -534,7 +534,7 @@ public ProcessingTestContext Sleep(int milliseconds) public ProcessingTestContext AssertProcessedBlocks(params IEnumerable blocks) { - Assert.That(_branchProcessor.Processed, Is.EqualTo(blocks.Select(b => b.Hash))); + Assert.That(_branchProcessor.Processed, Is.EquivalentTo(blocks.Select(b => b.Hash))); return this; } From 11e1094abcb53d2abc4590c9b85fc80a0b7c98de Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 18:18:40 +0530 Subject: [PATCH 13/60] fix(ethash): align difficulty bomb exponent cap with Geth's 256-bit limit and fix sync test --- .../EthashDifficultyCalculator.cs | 2 +- .../ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs index 94e0b3fdcc7c..7a50f9d5c665 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashDifficultyCalculator.cs @@ -87,7 +87,7 @@ private static BigInteger TimeBomb(IReleaseSpec spec, ulong blockNumber) return BigInteger.Zero; } exponent -= 2; - int exp = exponent > 2000 ? 2000 : (int)exponent; + int exp = exponent > 256 ? 256 : (int)exponent; return BigInteger.Pow(2, exp); } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs index 380e3bffc422..d3e8094960d6 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTestsBase.Scenario.cs @@ -316,9 +316,9 @@ public ScenarioBuilder IfThisNodeIsBehindThePivotInFastSync() () => { SyncProgressResolver.FindBestHeader().Returns(MidWayToPivot.Number); - SyncProgressResolver.FindBestFullBlock().Returns(0); - SyncProgressResolver.FindBestFullState().Returns(0); - SyncProgressResolver.FindBestProcessedBlock().Returns(0); + SyncProgressResolver.FindBestFullBlock().Returns(0UL); + SyncProgressResolver.FindBestFullState().Returns(0UL); + SyncProgressResolver.FindBestProcessedBlock().Returns(0UL); SyncProgressResolver.IsFastBlocksFinished().Returns(FastBlocksState.None); SyncProgressResolver.ChainDifficulty.Returns(UInt256.Zero); return "behind the pivot in fast sync"; From b61f2efab57df913f10588e8ab0743417ec0a444 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 20:12:37 +0530 Subject: [PATCH 14/60] fix(era1): resolve `BlockTreeSuggestPacer` underflow and test boundary check failures --- src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs | 10 +++++----- src/Nethermind/Nethermind.Era1/EraImporter.cs | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs b/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs index 3cc5771b22bf..e81b5ad5a9ca 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraImporterTest.cs @@ -79,7 +79,7 @@ public async Task VerifyEraFiles_VerifyAccumulatorsWithExpected_DoesNotThrow() .Build(); IEraImporter sut = toCtx.Resolve(); - await sut.Import(destinationPath, 0, long.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), default); + await sut.Import(destinationPath, 0, ulong.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), default); } [Test] @@ -103,7 +103,7 @@ public async Task VerifyEraFiles_VerifyAccumulatorsWithUnexpected_ThrowEraVerifi .Build(); IEraImporter sut = inCtx.Resolve(); - Func importTask = () => sut.Import(destinationPath, 0, long.MaxValue, + Func importTask = () => sut.Import(destinationPath, 0, ulong.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), CancellationToken.None); Assert.That(importTask, Throws.TypeOf()); @@ -129,7 +129,7 @@ public async Task VerifyEraFiles_ModifiedChecksum_ThrowEraVerificationException( .Build(); IEraImporter sut = inCtx.Resolve(); - Func importTask = () => sut.Import(destinationPath, 0, long.MaxValue, + Func importTask = () => sut.Import(destinationPath, 0, ulong.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), CancellationToken.None); Assert.That(importTask, Throws.TypeOf()); @@ -166,7 +166,7 @@ public async Task ImportAsArchiveSync_WillPaceSuggestBlock(CancellationToken tok }; EraImporter sut = (EraImporter)inCtx.Resolve(); - Task importTask = sut.Import(destinationPath, 0, long.MaxValue, + Task importTask = sut.Import(destinationPath, 0, ulong.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), token); // Pacer is created when import starts; spin briefly until it's published. @@ -202,7 +202,7 @@ public async Task ImportAsArchiveSync_WhenStartIsLessThanHead_ShouldThrow(Cancel .Build(); IEraImporter sut = inCtx.Resolve(); - Func act = () => sut.Import(destinationPath, 30, long.MaxValue, + Func act = () => sut.Import(destinationPath, 30, ulong.MaxValue, Path.Join(destinationPath, EraExporter.AccumulatorFileName), token); Assert.That(async () => await act(), Throws.TypeOf()); diff --git a/src/Nethermind/Nethermind.Era1/EraImporter.cs b/src/Nethermind/Nethermind.Era1/EraImporter.cs index cc77a18c9d8e..4a3e3d023d51 100644 --- a/src/Nethermind/Nethermind.Era1/EraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraImporter.cs @@ -113,7 +113,10 @@ private async Task ImportInternal( using ProgressReporter progress = new("Era import", logManager, to - from + 1); ulong blocksProcessed = 0; - using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, eraConfig.ImportBlocksBufferSize - 1024UL); + ulong resumeBatchSize = eraConfig.ImportBlocksBufferSize > 1024UL + ? eraConfig.ImportBlocksBufferSize - 1024UL + : eraConfig.ImportBlocksBufferSize / 2; + using BlockTreeSuggestPacer pacer = new(blockTree, eraConfig.ImportBlocksBufferSize, resumeBatchSize); CurrentPacer = pacer; ulong blockNumber = from; From a862cfd4b9be73ba5a6ffad479a474f7fbb47f94 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 11 Jun 2026 20:49:26 +0530 Subject: [PATCH 15/60] fix(init): resolve `ReceiptMigration` ulong countdown loop underflows --- .../Steps/Migrations/ReceiptMigration.cs | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs index 8ac609909910..b3d648db13d5 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs @@ -109,11 +109,17 @@ public async Task Run(CancellationToken cancellationToken) private void RunIfNeeded(CancellationToken cancellationToken) { // Note, it start in decreasing order from this high number. - ulong migrateToBlockNumber = _migrationStore.MigratedBlockNumber == ulong.MaxValue - ? _syncModeSelector.Current.NotSyncing() + ulong migrateToBlockNumber = 0; + if (_migrationStore.MigratedBlockNumber == ulong.MaxValue) + { + migrateToBlockNumber = _syncModeSelector.Current.NotSyncing() ? _blockTree.Head?.Number ?? 0UL - : _blockTree.BestKnownNumber - : _migrationStore.MigratedBlockNumber - 1; + : _blockTree.BestKnownNumber; + } + else if (_migrationStore.MigratedBlockNumber > 0) + { + migrateToBlockNumber = _migrationStore.MigratedBlockNumber - 1; + } if (migrateToBlockNumber > 0) { @@ -242,21 +248,29 @@ bool TryGetMainChainBlockHashFromLevel(ulong number, out Hash256? blockHash) } } - for (ulong i = to; i >= from; i--) + if (to >= from) { - if (token.IsCancellationRequested) + for (ulong i = to; ; i--) { - if (_logger.IsInfo) _logger.Info("Receipt migration cancelled"); - yield break; - } + if (token.IsCancellationRequested) + { + if (_logger.IsInfo) _logger.Info("Receipt migration cancelled"); + yield break; + } - if (TryGetMainChainBlockHashFromLevel(i, out Hash256? blockHash)) - { - yield return (i, blockHash!); - } - else - { - pointerTracker?.ReportCompleted(i); + if (TryGetMainChainBlockHashFromLevel(i, out Hash256? blockHash)) + { + yield return (i, blockHash!); + } + else + { + pointerTracker?.ReportCompleted(i); + } + + if (i == from) + { + break; + } } } } From 1c77acf90e064f246b55b3aaa96284cf5e9b5f5b Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Mon, 15 Jun 2026 18:43:00 +0530 Subject: [PATCH 16/60] fix: resolve type unification build errors and taiko tests and clean style lint warnings --- src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs | 1 - .../Validators/HeaderValidatorTests.cs | 1 - src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs | 1 - .../Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs | 1 - .../Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs | 1 - .../ExecutionRequests/ExecutionRequestsProcessor.cs | 1 - .../Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs | 1 - src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs | 1 - src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs | 1 - src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs | 1 - src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs | 2 -- src/Nethermind/Nethermind.Evm/BlockOverride.cs | 1 - .../Modules/Eth/EthRpcSimulateTestsBase.cs | 1 - .../P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs | 1 - .../P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs | 1 - .../P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs | 1 - .../Nethermind.State.Flat.Test/Persistence/ClearColumnsTests.cs | 2 +- .../Service/StateCompositionServiceTests.cs | 2 +- .../TaikoChainSpecEngineParametersTests.cs | 2 +- src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs | 1 - src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs | 1 - src/Nethermind/Nethermind.TxPool/NonceManager.cs | 1 - src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs | 1 - .../Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs | 1 - .../Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs | 1 - 25 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs index 1c0392f53f43..3b18bb4d7777 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Proofs/TxTrieTests.cs @@ -7,7 +7,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Int256; using Nethermind.Serialization.Rlp; using Nethermind.Specs.Forks; using Nethermind.State.Proofs; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index b88a6b3a6a6c..a0772cd50f0f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Numerics; using Nethermind.Consensus; using Nethermind.Consensus.Ethash; using Nethermind.Consensus.Validators; diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs index 52a767f95d7b..156388c96d6b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/Contract.cs @@ -9,7 +9,6 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Crypto; -using Nethermind.Int256; using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; diff --git a/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs b/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs index 50630c519a02..c2df7ccae063 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReorgDepthFinalizedStateProvider.cs @@ -4,7 +4,6 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Trie.Pruning; -using System; namespace Nethermind.Blockchain; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs index da228fc9ed51..6be7085c52ca 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Transactions/GeneratedTxSource.cs @@ -7,7 +7,6 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; using Nethermind.Core; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.State; using Nethermind.TxPool; diff --git a/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs b/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs index 0e9b45a9f4b5..5f71e3c7f630 100644 --- a/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs @@ -13,7 +13,6 @@ using Nethermind.Evm; using Nethermind.Evm.State; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; using System; using Nethermind.Core.Messages; diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs index 2351112591d2..0f131d948a18 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/BasicTestBlockchain.cs @@ -6,7 +6,6 @@ using Autofac; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Int256; using Nethermind.State; namespace Nethermind.Core.Test.Blockchain; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs index f97956bcbc96..488ad5527c52 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/TrieBuilder.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core.Crypto; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Rlp; using Nethermind.Trie; diff --git a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs index 878ee55cf849..845c12ea7812 100644 --- a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs @@ -17,7 +17,6 @@ using Nethermind.Core.Test.Container; using Nethermind.Core.Test.Encoding; using Nethermind.Core.Test.IO; -using Nethermind.Int256; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Evm.State; using NSubstitute; diff --git a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs index 3b791fe5d34e..69df9e9f1ead 100644 --- a/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/StateOverridesTests.cs @@ -7,7 +7,6 @@ using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Evm.State; -using Nethermind.Int256; using Nethermind.Specs.Forks; using NSubstitute; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs index c746e1cf27c4..f471ef872cbd 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs @@ -1,8 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.Threading.Tasks; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; diff --git a/src/Nethermind/Nethermind.Evm/BlockOverride.cs b/src/Nethermind/Nethermind.Evm/BlockOverride.cs index 99d537cb9857..ef0450ea54f7 100644 --- a/src/Nethermind/Nethermind.Evm/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Evm/BlockOverride.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index 52317a619fed..399138b90d99 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -18,7 +18,6 @@ using Nethermind.Evm; using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Facade.Proxy.Models.Simulate; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs; using Nethermind.Specs.Forks; diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs index f042d587c576..cb76a2202cef 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandlerTests.cs @@ -13,7 +13,6 @@ using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Core.Timers; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Network.P2P; using Nethermind.Network.P2P.Messages; diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs index 53cd69de0883..e1a071205003 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs @@ -9,7 +9,6 @@ using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Core.Timers; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Network.P2P; using Nethermind.Network.P2P.Messages; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs index 9eac5e4a6e60..e265dedc2647 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/StatusMessage69.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core.Crypto; -using Nethermind.Int256; using Nethermind.Network.P2P.Messages; namespace Nethermind.Network.P2P.Subprotocols.Eth.V69.Messages; diff --git a/src/Nethermind/Nethermind.State.Flat.Test/Persistence/ClearColumnsTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/Persistence/ClearColumnsTests.cs index 2346d81da343..67d26c95e0d4 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/Persistence/ClearColumnsTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/Persistence/ClearColumnsTests.cs @@ -35,7 +35,7 @@ public void ClearAllColumns_PreservesFormatMarkers_ResetsStateMetadata_AndWipesD Assert.That(BasePersistence.ReadLayout(metadata), Is.EqualTo(FlatLayout.Flat)); Assert.That(BasePersistence.ReadSlotEncoding(metadata), Is.EqualTo(BasePersistence.SlotEncodingRlp)); Assert.That(BasePersistence.ReadCurrentState(metadata), - Is.EqualTo(new StateId(-1, ValueKeccak.EmptyTreeHash))); + Is.EqualTo(new StateId(ulong.MaxValue, ValueKeccak.EmptyTreeHash))); Assert.That(db.GetColumnDb(FlatDbColumns.Storage).Get(slotKey), Is.Null); } } diff --git a/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceTests.cs b/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceTests.cs index 43dd25c3c24b..178eca651d97 100644 --- a/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceTests.cs +++ b/src/Nethermind/Nethermind.StateComposition.Test/Service/StateCompositionServiceTests.cs @@ -165,7 +165,7 @@ public async Task AnalyzeAsync_PartialScan_PreservesPriorBaseline() Assert.That(harness.StateHolder.HasScanBaseline, Is.True, "complete scan must seed the baseline"); Hash256 priorRoot = harness.StateHolder.LastProcessedStateRoot; - long priorBlock = harness.StateHolder.IncrementalBlock; + ulong priorBlock = harness.StateHolder.IncrementalBlock; TimeSpan priorDuration = harness.StateHolder.LastScanMetadata.Duration; Result partialScan = await harness.Service.AnalyzeAsync(header, CancellationToken.None); diff --git a/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs index 0f18141b183d..b2e91a465a33 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TaikoChainSpecEngineParametersTests.cs @@ -138,7 +138,7 @@ public void Hoodi_chainspec_schedules_Unzen_at_the_upstream_fork_time() Assert.That(parameters.UnzenTimestamp, Is.EqualTo(HoodiUnzenTimestamp)); - SortedSet blockNumbers = []; + SortedSet blockNumbers = []; SortedSet timestamps = []; parameters.AddTransitions(blockNumbers, timestamps); diff --git a/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs b/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs index 5dd979a8e8d5..179c957c4a57 100644 --- a/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/VisitingTests.cs @@ -10,7 +10,6 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test; using Nethermind.Db; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Rlp; using Nethermind.State; diff --git a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs index 07a349f69fd6..aa05827c1547 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs @@ -11,7 +11,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; -using Nethermind.Int256; using Nethermind.Specs; using NSubstitute; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.TxPool/NonceManager.cs b/src/Nethermind/Nethermind.TxPool/NonceManager.cs index 7ae9a7b6160f..548008403965 100644 --- a/src/Nethermind/Nethermind.TxPool/NonceManager.cs +++ b/src/Nethermind/Nethermind.TxPool/NonceManager.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Threading; using Nethermind.Core; -using Nethermind.Int256; namespace Nethermind.TxPool; diff --git a/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs b/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs index 5e7465b0cee1..359ff51b5ef2 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPoolInfoProvider.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Nethermind.Core; -using Nethermind.Int256; namespace Nethermind.TxPool; diff --git a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs index 7d39da1c2b8a..2f691473457a 100644 --- a/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs +++ b/src/Nethermind/Nethermind.Xdc.Test/XdcStateSyncSnapshotManagerTests.cs @@ -3,7 +3,6 @@ using Nethermind.Core; using Nethermind.Xdc.Contracts; -using Nethermind.Xdc.Types; using NSubstitute; using NUnit.Framework; using Nethermind.Xdc.Test.Helpers; diff --git a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs index 219776050277..660fd9efd778 100644 --- a/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs +++ b/src/Nethermind/Nethermind.Xdc/TxPool/XdcTxPoolTxSourceFactory.cs @@ -8,7 +8,6 @@ using Nethermind.Logging; using Nethermind.TxPool; using Nethermind.Core.Specs; -using Nethermind.Xdc.Spec; namespace Nethermind.Xdc.TxPool; From 46a58901e3ed876e63149ca0523c123745ae625e Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Wed, 17 Jun 2026 02:38:29 +0530 Subject: [PATCH 17/60] refactor: unify Geth types and fix EIP-8037/EIP-7702 test regressions --- .../EraFlatStoreTests.cs | 42 ++++++------- .../Nethermind.BalRecorder/SlotStore.cs | 12 ++-- .../Rlp/RlpDecodeBlockBenchmark.cs | 4 +- .../Rlp/RlpEncodeBlockBenchmark.cs | 4 +- .../Rlp/RlpEncodeHeaderBenchmark.cs | 4 +- .../State/ReadOnlySnapshotBundleBenchmark.cs | 6 +- .../State/WriteBatchBenchmark.cs | 6 +- .../Store/PatriciaTreeBenchmarks.cs | 6 +- .../BlockTreeTests.cs | 38 ++++++------ .../BlockhashCacheTests.cs | 24 +++---- .../BlockhashProviderTests.cs | 6 +- .../Eip8037BlockGasIntegrationTests.cs | 12 ++-- .../Filters/LogIndexFilterVisitorTests.cs | 2 - .../Find/LogFinderTests.cs | 1 - .../TransactionProcessorEip7702Tests.cs | 14 ++--- .../TransactionProcessorTests.cs | 2 +- .../TxPoolSourceTests.cs | 4 +- .../Nethermind.Blockchain/BlockhashCache.cs | 28 ++++----- .../BlockhashProvider.cs | 2 +- .../Blocks/BlockStore.cs | 4 +- .../Nethermind.Blockchain/IBlockhashCache.cs | 2 +- .../Stateless/StatelessBlockTree.cs | 4 +- .../Builders/BlockBuilder.cs | 6 ++ .../Builders/BlockHeaderBuilder.cs | 6 ++ .../Builders/BlockTreeBuilder.cs | 9 +++ .../Eip8037BlockGasInclusionCheckTests.cs | 17 +++-- .../Eip8037BlockGasInclusionCheck.cs | 25 +++++--- .../Eth/EthSyncingInfoTests.cs | 62 +++++++++---------- .../Nethermind.Facade/Find/LogIndexBuilder.cs | 17 ++--- 29 files changed, 193 insertions(+), 176 deletions(-) diff --git a/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs b/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs index bd39cc22f36e..5ab94f4a1ec9 100644 --- a/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs +++ b/src/Nethermind/Nethermind.BalRecorder.Test/EraFlatStoreTests.cs @@ -30,9 +30,9 @@ public void WriteAndRead_RoundTrip() using SlotStore store = new(dir); byte[] payload = [1, 2, 3, 4, 5]; - store.Write(100, payload); + store.Write(100UL, payload); - Assert.That(TryReadBytes(store, 100), Is.EqualTo(payload)); + Assert.That(TryReadBytes(store, 100UL), Is.EqualTo(payload)); } finally { Directory.Delete(dir, true); } } @@ -41,7 +41,7 @@ public void WriteAndRead_RoundTrip() public void TryRead_ReturnsFalse_WhenFileDoesNotExist() { using SlotStore store = new(TempDir()); - bool found = store.TryRead(999, static (_, _) => { }, 0); + bool found = store.TryRead(999UL, static (_, _) => { }, 0); Assert.That(found, Is.False); } @@ -52,10 +52,10 @@ public void TryRead_ReturnsFalse_WhenSlotNotWritten() try { using SlotStore store = new(dir); - store.Write(0, [0xAA]); + store.Write(0UL, [0xAA]); // slot 1 is in the same era file but was never written - Assert.That(store.TryRead(1, static (_, _) => { }, 0), Is.False); + Assert.That(store.TryRead(1UL, static (_, _) => { }, 0), Is.False); } finally { Directory.Delete(dir, true); } } @@ -67,11 +67,11 @@ public void MultipleSlots_SameEra_AreIndependent() try { using SlotStore store = new(dir); - store.Write(0, [0xAA]); - store.Write(1, [0xBB, 0xCC]); + store.Write(0UL, [0xAA]); + store.Write(1UL, [0xBB, 0xCC]); - Assert.That(TryReadBytes(store, 0), Is.EqualTo([0xAA])); - Assert.That(TryReadBytes(store, 1), Is.EqualTo([0xBB, 0xCC])); + Assert.That(TryReadBytes(store, 0UL), Is.EqualTo([0xAA])); + Assert.That(TryReadBytes(store, 1UL), Is.EqualTo([0xBB, 0xCC])); } finally { Directory.Delete(dir, true); } } @@ -83,13 +83,13 @@ public void DifferentEras_UsesSeparateFiles() try { using SlotStore store = new(dir); - store.Write(0, [0xAA]); - store.Write(8192, [0xBB]); + store.Write(0UL, [0xAA]); + store.Write(8192UL, [0xBB]); Assert.That(Directory.GetFiles(dir, "*.bin").Length, Is.EqualTo(2)); - Assert.That(TryReadBytes(store, 0), Is.EqualTo([0xAA])); - Assert.That(TryReadBytes(store, 8192), Is.EqualTo([0xBB])); + Assert.That(TryReadBytes(store, 0UL), Is.EqualTo([0xAA])); + Assert.That(TryReadBytes(store, 8192UL), Is.EqualTo([0xBB])); } finally { Directory.Delete(dir, true); } } @@ -101,10 +101,10 @@ public void Write_DoesNotOverwriteExistingSlot() try { using SlotStore store = new(dir); - store.Write(42, [0xAA]); - store.Write(42, [0xBB]); + store.Write(42UL, [0xAA]); + store.Write(42UL, [0xBB]); - Assert.That(TryReadBytes(store, 42), Is.EqualTo([0xAA])); + Assert.That(TryReadBytes(store, 42UL), Is.EqualTo([0xAA])); } finally { Directory.Delete(dir, true); } } @@ -116,7 +116,7 @@ public void CustomExtension_IsUsed() try { using SlotStore store = new(dir, "bal"); - store.Write(0, [0x01]); + store.Write(0UL, [0x01]); Assert.That((Directory.GetFiles(dir, "*.bal")).Length, Is.EqualTo(1)); Assert.That((Directory.GetFiles(dir, "*.bin")).Length, Is.EqualTo(0)); @@ -138,9 +138,9 @@ public void ConcurrentWrites_SameEra_DoNotCorrupt() store.Write((ulong)i, data); }); - for (int i = 0; i < 64; i++) + for (ulong i = 0; i < 64; i++) { - Assert.That(TryReadBytes(store, (ulong)i), Is.EqualTo(new[] { (byte)i }), $"slot {i} should be intact"); + Assert.That(TryReadBytes(store, i), Is.EqualTo(new[] { (byte)i }), $"slot {i} should be intact"); } } finally { Directory.Delete(dir, true); } @@ -152,9 +152,9 @@ public void ReadAfterDispose_ThroughNewInstance_SeesOldData() string dir = TempDir(); try { - using (SlotStore w = new(dir)) w.Write(5, [0xEE]); + using (SlotStore w = new(dir)) w.Write(5UL, [0xEE]); using SlotStore r = new(dir); - Assert.That(TryReadBytes(r, 5), Is.EqualTo([0xEE])); + Assert.That(TryReadBytes(r, 5UL), Is.EqualTo([0xEE])); } finally { Directory.Delete(dir, true); } } diff --git a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs index d10928f15ada..5afee81766b0 100644 --- a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs @@ -15,7 +15,7 @@ namespace Nethermind.BalRecorder; public class SlotStore(string directory, string extension = "bin") : IDisposable { private SlotFile? _file; - private ulong _fileEra = ulong.MinValue; + private long _fileEra = -1; private readonly Lock _lock = new(); private string FilePath(ulong era) => Path.Combine(directory, $"{era:D8}.{extension}"); @@ -26,13 +26,13 @@ public bool TryRead(ulong blockNumber, ReadOnlySpanAction acti int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { - if (_fileEra != era) + if (_fileEra != (long)era) { string path = FilePath(era); if (!File.Exists(path)) return false; _file?.Dispose(); _file = new SlotFile(path); - _fileEra = era; + _fileEra = (long)era; } return _file!.TryRead(slot, action, arg); } @@ -44,12 +44,12 @@ public bool Write(ulong blockNumber, ReadOnlySpan data) int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { - if (_fileEra != era) + if (_fileEra != (long)era) { _file?.Dispose(); Directory.CreateDirectory(directory); _file = new SlotFile(FilePath(era)); - _fileEra = era; + _fileEra = (long)era; } return _file!.TryWrite(slot, data); } @@ -61,7 +61,7 @@ public void Dispose() { _file?.Dispose(); _file = null; - _fileEra = ulong.MinValue; + _fileEra = -1; } } } diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs index f803ed2ff890..bfb5e048b4f5 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpDecodeBlockBenchmark.cs @@ -19,9 +19,9 @@ public class RlpDecodeBlockBenchmark public RlpDecodeBlockBenchmark() { Transaction[] transactions = new Transaction[100]; - for (int i = 0; i < 100; i++) + for (ulong i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[(int)i] = Build.A.Transaction.WithData([(byte)i]).WithNonce(i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs index 289878c21e8b..f3219b91b22d 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeBlockBenchmark.cs @@ -24,9 +24,9 @@ public class RlpEncodeBlockBenchmark public RlpEncodeBlockBenchmark() { Transaction[] transactions = new Transaction[100]; - for (int i = 0; i < 100; i++) + for (ulong i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[(int)i] = Build.A.Transaction.WithData([(byte)i]).WithNonce(i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs index 08f7acdc08e8..8676c04bef3c 100644 --- a/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/Rlp/RlpEncodeHeaderBenchmark.cs @@ -23,9 +23,9 @@ public class RlpEncodeHeaderBenchmark public RlpEncodeHeaderBenchmark() { Transaction[] transactions = new Transaction[100]; - for (int i = 0; i < 100; i++) + for (ulong i = 0; i < 100; i++) { - transactions[i] = Build.A.Transaction.WithData(new byte[] { (byte)i }).WithNonce((ulong)i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; + transactions[(int)i] = Build.A.Transaction.WithData([(byte)i]).WithNonce(i).WithValue((UInt256)i).Signed(new EthereumEcdsa(TestBlockchainIds.ChainId), TestItem.PrivateKeyA).TestObject; } _scenarios = new[] diff --git a/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs index 96d09769f0bd..9091d62d2bc5 100644 --- a/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/State/ReadOnlySnapshotBundleBenchmark.cs @@ -66,7 +66,7 @@ public void Setup() // Track storage account ranges per snapshot for hit distribution List<(int AddressStart, int StorageCount, int SlotsPerAccount)> storageRanges = []; - for (int block = 0; block < SnapshotCount; block++) + for (ulong block = 0; block < SnapshotCount; block++) { int multiplier = block < 6 ? 16 : 1; int accountCount = 1000 * multiplier; @@ -138,7 +138,7 @@ public void Setup() }); } - scope.Commit(blockNumber: (ulong)(block + 1)); + scope.Commit(blockNumber: block + 1); FlatSnapshot snapshot = commitTarget.LastSnapshot ?? throw new InvalidOperationException( @@ -146,7 +146,7 @@ public void Setup() snapshot.TryAcquire(); allSnapshots.Add(snapshot); - currentStateId = new StateId((ulong)(block + 1), scope.RootHash); + currentStateId = new StateId(block + 1, scope.RootHash); storageRanges.Add((totalAccountCount + 1, storageAccountCount, slotsPerStorageAccount)); totalAccountCount += accountCount; totalStorageAccountCount += storageAccountCount; diff --git a/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs b/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs index 3bfc2330777c..191068de55cc 100644 --- a/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs +++ b/src/Nethermind/Nethermind.Benchmark/State/WriteBatchBenchmark.cs @@ -51,7 +51,7 @@ public void GlobalSetup() int totalAccountCount = 0; - for (int block = 0; block < SnapshotCount; block++) + for (ulong block = 0; block < SnapshotCount; block++) { int accountCount = 500; int storageAccountCount = 10; @@ -116,7 +116,7 @@ public void GlobalSetup() }); } - scope.Commit(blockNumber: (ulong)(block + 1)); + scope.Commit(blockNumber: block + 1); FlatSnapshot snapshot = commitTarget.LastSnapshot ?? throw new InvalidOperationException( @@ -124,7 +124,7 @@ public void GlobalSetup() snapshot.TryAcquire(); _baseSnapshots.Add(snapshot); - _currentStateId = new StateId((ulong)(block + 1), scope.RootHash); + _currentStateId = new StateId(block + 1, scope.RootHash); totalAccountCount += accountCount; } diff --git a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs index cf04457e29e6..cef3011dec3f 100644 --- a/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs +++ b/src/Nethermind/Nethermind.Benchmark/Store/PatriciaTreeBenchmarks.cs @@ -351,15 +351,15 @@ public void InsertAndCommitRepeatedlyTimes() Persist.EveryNBlock(2), NullLogManager.Instance); StateTree tempTree = new(trieStore, NullLogManager.Instance); - for (int i = 0; i < _largerEntryCount; i++) + for (ulong i = 0; i < _largerEntryCount; i++) { if (i % _repeatedlyFactor == 0) { - using IBlockCommitter _ = trieStore.BeginBlockCommit((ulong)(i / _repeatedlyFactor)); + using IBlockCommitter _ = trieStore.BeginBlockCommit(i / _repeatedlyFactor); tempTree.Commit(); } - (bool isWrite, Hash256 address, Account value) = _largerEntriesAccess[i]; + (bool isWrite, Hash256 address, Account value) = _largerEntriesAccess[(int)i]; if (isWrite) { tempTree.Set(address, value); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs index 3566fc97534d..7e183f33009a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs @@ -1368,7 +1368,7 @@ public void When_lowestInsertedHeaderWasNotPersisted_useBinarySearchToLoadLowest for (ulong i = beginIndex; i > beginIndex - insertedBlocks; i--) { - tree.Insert(Build.A.BlockHeader.WithNumber(i).WithTotalDifficulty((long)i).TestObject); + tree.Insert(Build.A.BlockHeader.WithNumber(i).WithTotalDifficulty(i).TestObject); } builder.MetadataDb.Delete(MetadataDbKeys.LowestInsertedFastHeaderHash); @@ -1911,17 +1911,18 @@ public void Can_block_and_unblock_adding_blocks() } [MaxTime(Timeout.MaxTestTime)] - [TestCase(10, false, 10000000ul)] - [TestCase(4, false, 4000000ul)] - [TestCase(10, true, 10000000ul)] - public void Recovers_total_difficulty(int chainLength, bool deleteAllLevels, ulong expectedTotalDifficulty) + [TestCase(10ul, false, 10000000ul)] + [TestCase(4ul, false, 4000000ul)] + [TestCase(10ul, true, 10000000ul)] + public void Recovers_total_difficulty(ulong chainLength, bool deleteAllLevels, ulong expectedTotalDifficulty) { BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree().OfChainLength(chainLength); BlockTree blockTree = blockTreeBuilder.TestObject; - int chainLeft = deleteAllLevels ? 0 : 1; - for (int i = chainLength - 1; i >= chainLeft; i--) + ulong chainLeft = deleteAllLevels ? 0UL : 1UL; + for (ulong i = chainLength; i > chainLeft;) { - ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i); + i--; + ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i); if (level is not null) { for (int j = 0; j < level.BlockInfos.Length; j++) @@ -1934,15 +1935,16 @@ public void Recovers_total_difficulty(int chainLength, bool deleteAllLevels, ulo } } - blockTreeBuilder.ChainLevelInfoRepository.Delete((ulong)i); + blockTreeBuilder.ChainLevelInfoRepository.Delete(i); } } Assert.That(blockTree.FindBlock(blockTree.Head!.Hash, BlockTreeLookupOptions.None)!.TotalDifficulty, Is.EqualTo(new UInt256(expectedTotalDifficulty))); - for (int i = chainLength - 1; i >= 0; i--) + for (ulong i = chainLength; i > 0;) { - ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel((ulong)i); + i--; + ChainLevelInfo? level = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i); Assert.That(level, Is.Not.Null); Assert.That(level!.BlockInfos.Length, Is.EqualTo(1)); @@ -2171,7 +2173,7 @@ public void Can_insert_headers_in_batch() { currentHeader = Build.A.BlockHeader .WithDifficulty(1) - .WithTotalDifficulty((long)(currentHeader.TotalDifficulty + 1)!) + .WithTotalDifficulty((ulong)(currentHeader.TotalDifficulty + 1)!) .WithParent(currentHeader) .TestObject; batch.Add(currentHeader); @@ -2454,11 +2456,11 @@ public void UpdateMainChain_WhenCalledWithWereProcessedFalse_MarksBlockCanonical } } - [TestCase(1, false, TestName = "SingleDescendant")] - [TestCase(3, false, TestName = "MultipleDescendants")] - [TestCase(3, true, TestName = "MultipleDescendantsWithGap")] + [TestCase(1ul, false, TestName = "SingleDescendant")] + [TestCase(3ul, false, TestName = "MultipleDescendants")] + [TestCase(3ul, true, TestName = "MultipleDescendantsWithGap")] [MaxTime(Timeout.MaxTestTime)] - public void UpdateMainChain_WhenBeaconSyncMarksThenReorgsToSibling_ClearsStaleMarkers(int descendantCount, bool simulateGap) + public void UpdateMainChain_WhenBeaconSyncMarksThenReorgsToSibling_ClearsStaleMarkers(ulong descendantCount, bool simulateGap) { // Beacon sync marks N descendants canonical (wereProcessed=false, Head stays stale at H=1). // FCU reorgs to sibling at the same height. All stale markers must be cleared. @@ -2469,7 +2471,7 @@ public void UpdateMainChain_WhenBeaconSyncMarksThenReorgsToSibling_ClearsStaleMa Block headBlock = Build.A.Block.WithNumber(1).WithParent(genesis).WithExtraData([0xAA]).TestObject; blockTree.SuggestBlock(headBlock); - Block[] descendants = BuildAndSuggestChain(blockTree, headBlock, descendantCount); + Block[] descendants = BuildAndSuggestChain(blockTree, headBlock, (int)descendantCount); // FCU sets Head to headBlock at H=1 blockTree.UpdateMainChain(new[] { headBlock }, wereProcessed: true, forceUpdateHeadBlock: true); @@ -2508,7 +2510,7 @@ public void UpdateMainChain_WhenBeaconSyncMarksThenReorgsToSibling_ClearsStaleMa } // FindCanonicalBlockInfo must return null for all orphaned heights - for (ulong h = 2ul; h <= (ulong)descendantCount + 1ul; h++) + for (ulong h = 2; h <= descendantCount + 1; h++) { Assert.That(blockTree.FindCanonicalBlockInfo(h), Is.Null, $"H={h} must return null — orphaned after reorg"); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs index 9ae05c142afb..8aa424ba06a0 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashCacheTests.cs @@ -18,7 +18,7 @@ namespace Nethermind.Blockchain.Test; [Parallelizable(ParallelScope.All)] public class BlockhashCacheTests { - private const int FlatCacheItemLength = (int)BlockhashCache.MaxDepth + 1; + private const ulong FlatCacheItemLength = BlockhashCache.MaxDepth + 1ul; [Test] public void GetHash_with_depth_zero_returns_block_hash() @@ -192,10 +192,10 @@ public void Sequential_queries_work_correctly() { BlockHeader? block = tree.FindHeader(blockNum, BlockTreeLookupOptions.None); - for (int depth = 1; depth <= 100; depth += 25) + for (ulong depth = 1ul; depth <= 100ul; depth += 25ul) { Hash256? result = cache.GetHash(block!, depth); - BlockHeader? expected = tree.FindHeader(blockNum - (ulong)depth, BlockTreeLookupOptions.None); + BlockHeader? expected = tree.FindHeader(blockNum - depth, BlockTreeLookupOptions.None); Assert.That(result, Is.EqualTo(expected!.Hash!), $"block {blockNum} depth {depth}"); } } @@ -236,7 +236,7 @@ public void Can_stitch_block_ranges() for (ulong i = 100ul; i <= 500ul; i += 100ul) { BlockHeader block = tree.FindHeader(i, BlockTreeLookupOptions.None)!; - cache.GetHash(block, (int)BlockhashCache.MaxDepth); + cache.GetHash(block, BlockhashCache.MaxDepth); } Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(501, 1, 5))); @@ -265,16 +265,16 @@ public async Task Can_support_multiple_forks() public async Task Can_prune_old_forks() { const ulong depth = BlockhashCache.MaxDepth * 5 + 1; - (BlockTree tree, BlockhashCache cache) = BuildTest((int)depth); + (BlockTree tree, BlockhashCache cache) = BuildTest(depth); for (ulong i = BlockhashCache.MaxDepth; i < depth; i += BlockhashCache.MaxDepth) { - cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, (int)BlockhashCache.MaxDepth); + cache.GetHash(tree.FindHeader(i, BlockTreeLookupOptions.RequireCanonical)!, BlockhashCache.MaxDepth); } - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)depth, 1, 5))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(depth, 1, 5))); await cache.Prefetch(tree.FindHeader(depth - 1ul, BlockTreeLookupOptions.RequireCanonical)!); await Task.Delay(100); - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)BlockhashCache.MaxDepth * 2 + 1, 1, 3))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(BlockhashCache.MaxDepth * 2ul + 1ul, 1, 3))); } [Test] @@ -300,13 +300,13 @@ public async Task Prefetch_prunes() [TestCase(50ul)] public async Task Prefetch_reuses_parent_data(ulong chainDepth) { - (BlockTree tree, BlockhashCache cache) = BuildTest((int)chainDepth); + (BlockTree tree, BlockhashCache cache) = BuildTest(chainDepth); BlockHeader head = tree.FindHeader(chainDepth - 1ul, BlockTreeLookupOptions.None)!; BlockHeader prev = tree.FindHeader(chainDepth - 2ul, BlockTreeLookupOptions.None)!; Hash256[] prevHashes = (await cache.Prefetch(prev, CancellationToken.None))!; Hash256[] headHashes = (await cache.Prefetch(head, CancellationToken.None))!; - Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats((int)Math.Min(chainDepth - 1ul, FlatCacheItemLength), 1, 2))); + Assert.That(cache.GetStats(), Is.EqualTo(new BlockhashCache.Stats(Math.Min(chainDepth - 1ul, FlatCacheItemLength), 1, 2))); Assert.Multiple(() => { int compareLength = headHashes.Length - 1; @@ -352,7 +352,7 @@ public async Task Prefetch_with_null_hash_does_not_cache([Values] bool prefetchP await cache.Prefetch(parent); } - int cacheCountBefore = cache.GetStats().FlatCache; + ulong cacheCountBefore = cache.GetStats().FlatCache; BlockHeader production = Build.A.BlockHeader.WithParent(parent).WithNumber(10).TestObject; production.Hash = null; @@ -367,7 +367,7 @@ public async Task Prefetch_with_null_hash_does_not_cache([Values] bool prefetchP } } - private static (BlockTree, BlockhashCache) BuildTest(int chainLength, IHeaderStore? headerStore = null) + private static (BlockTree, BlockhashCache) BuildTest(ulong chainLength, IHeaderStore? headerStore = null) { Block genesis = Build.A.Block.Genesis.TestObject; BlockTreeBuilder builder = Build.A.BlockTree(genesis); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs index 559f878f3562..2dec36581ba6 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs @@ -181,7 +181,7 @@ public void Can_handle_non_main_chain_in_fast_sync() public void Blockhash_lookup_with_full_chain(ulong chainLength, int lookupOffset, bool expectNonNull) { Block genesis = Build.A.Block.Genesis.TestObject; - BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfChainLength((int)chainLength); + BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfChainLength(chainLength); BlockTree tree = blockTreeBuilder.TestObject; BlockhashProvider provider = CreateBlockHashProvider(blockTreeBuilder.HeaderStore, Frontier.Instance); @@ -225,7 +225,7 @@ public void UInt_256_overflow() public void Eip2935_enabled_Eip7709_disabled_and_then_get_hash(ulong chainLength) { Block genesis = Build.A.Block.Genesis.TestObject; - BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength((int)chainLength); + BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength); BlockTree tree = blockTreeBuilder.TestObject; BlockHeader? head = tree.FindHeader(chainLength - 1ul, BlockTreeLookupOptions.None); @@ -273,7 +273,7 @@ public void Eip2935_poc_trimmed_hashes() { ulong chainLength = 42ul; Block genesis = Build.A.Block.Genesis.TestObject; - BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength((int)chainLength).TestObject; + BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; BlockHeader? head = tree.FindHeader(chainLength - 1ul, BlockTreeLookupOptions.None); // number = chainLength diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs index 961d13961e35..5b54353cfb38 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs @@ -107,13 +107,11 @@ public void Eip8037_boundary_state(ulong blockStateGasUsed, bool accepts) } /// - /// Creation tx is accepted at inclusion because the EIP-8037 formula subtracts - /// intrinsic.state. With actual post-execution gas modest - /// (the create succeeds well under cap), IncrementalValidation also accepts. - /// This test verifies acceptance. + /// Creation tx is rejected at inclusion because the corrected EIP-8037 formula + /// does not subtract intrinsic.state from the raw tx.gas. /// [Test] - public void Eip8037_creation_tx_regular_check_actual_usage_modest_accepts() + public void Eip8037_creation_tx_regular_check_without_subtraction_rejects() { ulong blockGasLimit = 16_777_216ul + 53_000ul + 1ul; // cap + intrinsic_regular + 1 Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; @@ -128,7 +126,7 @@ public void Eip8037_creation_tx_regular_check_actual_usage_modest_accepts() results[0].TrySetResult(GasResult(block, 0, 16_777_216ul, 0ul)); results[1].TrySetResult(GasResult(block, 1, 53_000ul, IntrinsicNewAccountState)); - Assert.DoesNotThrow(() => + Assert.Throws(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None)); } @@ -157,7 +155,7 @@ public void Eip8037_single_tx_state_check_exceeds_block_limit_rejects() Assert.Throws(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[1], null, CancellationToken.None), - "EIP-8037 requires rejection at inclusion when tx.gas - intrinsic.regular > block_gas_limit"); + "EIP-8037 requires rejection at inclusion when tx.gas > state_gas_available"); } /// diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs index 099425ecf792..82da021fb94f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Filters/LogIndexFilterVisitorTests.cs @@ -386,7 +386,6 @@ private static Ranges GenerateLogIndexRanges() Dictionary> addressRanges = []; foreach (Address address in new[] { TestItem.AddressA, TestItem.AddressB, TestItem.AddressC, TestItem.AddressD, TestItem.AddressE }) { - // Narrowing ulong -> int is safe here: FromBlock/ToBlock are small test constants (0..99), no overflow risk. List range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.3).ToList(); addressRanges.Add(address, range); } @@ -399,7 +398,6 @@ private static Ranges GenerateLogIndexRanges() { foreach (Hash256 topic in new[] { TestItem.KeccakA, TestItem.KeccakB, TestItem.KeccakC, TestItem.KeccakD, TestItem.KeccakE }) { - // Narrowing ulong -> int is safe here: FromBlock/ToBlock are small test constants (0..99), no overflow risk. List range = Enumerable.Range((int)FromBlock, (int)(ToBlock + 1)).Where(_ => random.NextDouble() < 0.2).ToList(); ranges.Add(topic, range); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs index c0e61cabddb7..942e44eefb51 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs @@ -389,7 +389,6 @@ public void filter_throws_descriptive_exception_when_receipts_exist_in_compact_e private static FilterBuilder AllBlockFilter() => FilterBuilder.New().FromEarliestBlock().ToPendingBlock(); - private LogFinder CreateLogFinder(IBlockFinder? blockFinder = null, IReceiptStorage? receiptStorage = null) => new(blockFinder ?? _blockTree, receiptStorage ?? _receiptStorage, receiptStorage ?? _receiptStorage, LimboLogs.Instance, _receiptsRecovery); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs index 2dddb557349d..9e84812e47a3 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs @@ -333,10 +333,10 @@ public void Execute_AuthorityNonceHasMaxValueOrBelow_MaxValueNonceIsNotAllowed(u Assert.That(Eip7702Constants.IsDelegatedCode(actual), Is.EqualTo(expectDelegation)); } - [TestCase(1)] - [TestCase(10)] - [TestCase(99)] - public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int count) + [TestCase(1ul)] + [TestCase(10ul)] + [TestCase(99ul)] + public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(ulong count) { PrivateKey sender = TestItem.PrivateKeyA; PrivateKey signer = TestItem.PrivateKeyB; @@ -345,8 +345,8 @@ public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int c Transaction tx = Build.A.Transaction .WithType(TxType.SetCode) .WithTo(signer.Address) - .WithGasLimit(GasCostOf.Transaction + GasCostOf.NewAccount * (ulong)count) - .WithAuthorizationCode(Enumerable.Range(0, count) + .WithGasLimit(GasCostOf.Transaction + GasCostOf.NewAccount * count) + .WithAuthorizationCode(Enumerable.Range(0, (int)count) .Select(i => _ethereumEcdsa.Sign( signer, _specProvider.ChainId, @@ -363,7 +363,7 @@ public void Execute_TxHasDifferentAmountOfAuthorizedCode_UsedGasIsExpected(int c _transactionProcessor.Execute(tx, new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)), tracer); - Assert.That(tracer.GasSpent, Is.EqualTo(GasCostOf.Transaction + GasCostOf.NewAccount * (ulong)count)); + Assert.That(tracer.GasSpent, Is.EqualTo(GasCostOf.Transaction + GasCostOf.NewAccount * count)); } public void Execute_TxHasDifferentAmount() diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index c8076ba29501..f96ddc2117d1 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -162,7 +162,7 @@ public void Can_handle_quick_fail_on_not_enough_balance_on_reserved_gas_payment( .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, eip155Enabled) .TestObject; - tx.Value = (ulong)(AccountBalance - GasCostOf.Transaction); + tx.Value = AccountBalance - GasCostOf.Transaction; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.BerlinBlockNumber).WithTransactions(tx).TestObject; TransactionResult result = Execute(tx, block); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs index 1cb22746e917..727c17077440 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs @@ -48,9 +48,9 @@ public void GetTransactions_should_respect_customizable_blob_gas_limit(int[] blo TxPoolTxSource transactionSelector = new(txPool, specProvider, transactionComparerProvider, LimboLogs.Instance, txFilterPipeline, new BlocksConfig { SecondsPerSlot = 12, BlockProductionBlobLimit = customBlobLimit }); IEnumerable txs = transactionSelector.GetTransactions(new BlockHeader(), long.MaxValue); - int blobsCount = (int)txs.Sum(tx => (long)tx.GetBlobCount()); + ulong blobsCount = txs.Aggregate(0UL, (sum, tx) => sum + tx.GetBlobCount()); - Assert.That(blobsCount, Is.LessThanOrEqualTo(Cancun.Instance.MaxProductionBlobCount(customBlobLimit))); + Assert.That(blobsCount, Is.LessThanOrEqualTo((ulong)Cancun.Instance.MaxProductionBlobCount(customBlobLimit))); } public static IEnumerable BlobTransactionsWithBlobGasLimitPerBlockCombinations() diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs index eafe20329f29..1da4f510011f 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashCache.cs @@ -27,31 +27,31 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) private ulong _minBlock = ulong.MaxValue; private Task _pruningTask = Task.CompletedTask; - public Hash256? GetHash(BlockHeader headBlock, int depth) => + public Hash256? GetHash(BlockHeader headBlock, ulong depth) => depth == 0 ? headBlock.Hash : depth == 1 ? headBlock.ParentHash - : (ulong)depth > MaxDepth ? null - : _flatCache.TryGet(headBlock.ParentHash!, out Hash256[] array) ? array[depth - 2] + : depth > MaxDepth ? null + : _flatCache.TryGet(headBlock.ParentHash!, out Hash256[] array) ? array[(int)depth - 2] : Load(headBlock, depth, out _)?.Hash; - private CacheNode? Load(BlockHeader blockHeader, int depth, out Hash256[]? hashes, CancellationToken cancellationToken = default) + private CacheNode? Load(BlockHeader blockHeader, ulong depth, out Hash256[]? hashes, CancellationToken cancellationToken = default) { hashes = null; - if ((ulong)depth > MaxDepth) return null; - bool alwaysAdd = (ulong)depth == MaxDepth; - using ArrayPoolListRef<(CacheNode Node, bool NeedToAdd)> blocks = new(depth + 1); + if (depth > MaxDepth) return null; + bool alwaysAdd = depth == MaxDepth; + using ArrayPoolListRef<(CacheNode Node, bool NeedToAdd)> blocks = new((int)depth + 1); Hash256 currentHash = blockHeader.Hash!; CacheNode currentNode = null; bool needToAddAny = false; - int skipped = 0; - for (int i = 0; i <= depth && !cancellationToken.IsCancellationRequested; i++) + ulong skipped = 0; + for (ulong i = 0; i <= depth && !cancellationToken.IsCancellationRequested; i++) { bool needToAdd = false; if (currentNode is null) { if (!_blocks.TryGetValue(currentHash, out currentNode)) { - BlockHeader? currentHeader = i == 0 ? blockHeader : headerFinder.Get(currentHash, blockHeader.Number - (ulong)i); + BlockHeader? currentHeader = i == 0 ? blockHeader : headerFinder.Get(currentHash, blockHeader.Number - i); if (currentHeader is null) { break; @@ -115,7 +115,7 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) } } - int index = depth - skipped; + int index = (int)depth - (int)skipped; return index < 0 ? currentNode // if index <0 then we skipped everything and got it from cache : blocks.Count > index ? blocks[index].Node @@ -148,7 +148,7 @@ public class BlockhashCache(IHeaderFinder headerFinder, ILogManager logManager) } else { - Load(blockHeader, (int)MaxDepth, out hashes, cancellationToken); + Load(blockHeader, MaxDepth, out hashes, cancellationToken); } } } @@ -266,7 +266,7 @@ public Stats GetStats() nodes++; } - return new Stats(nodes, parents.Values.Count(p => p == 0), _flatCache.Count); + return new Stats((ulong)nodes, (ulong)parents.Values.Count(p => p == 0), (ulong)_flatCache.Count); } /// @@ -280,5 +280,5 @@ private class CacheNode(BlockHeader blockHeader, CacheNode? parent = null) public CacheNode? Parent { get; set; } = parent; } - public record struct Stats(int Nodes, int Roots, int FlatCache); + public record struct Stats(ulong Nodes, ulong Roots, ulong FlatCache); } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index 2a5f1edec08d..34f9764fc3fc 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -47,7 +47,7 @@ public class BlockhashProvider( 1UL => currentBlock.ParentHash, _ => hashes is not null ? hashes[(int)(depth - 1)] - : blockhashCache.GetHash(currentBlock, (int)depth) + : blockhashCache.GetHash(currentBlock, depth) ?? throw new InvalidDataException("Hash cannot be found when executing BLOCKHASH operation") }; } diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs index 1151157686e7..4f8b05e8ea56 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs @@ -14,13 +14,13 @@ namespace Nethermind.Blockchain.Blocks; public class BlockStore([KeyFilter(DbNames.Blocks)] IDb blockDb, IHeaderDecoder? headerDecoder = null) : IBlockStore, IClearableCache { - public const ulong CacheSize = 128 + 32; + public const int CacheSize = 128 + 32; private readonly IDb _blockDb = blockDb; private readonly BlockDecoder _blockDecoder = new(headerDecoder ?? new HeaderDecoder()); private readonly AssociativeCache - _blockCache = new((int)CacheSize); + _blockCache = new(CacheSize); public void SetMetadata(byte[] key, byte[] value) => _blockDb.Set(key, value); diff --git a/src/Nethermind/Nethermind.Blockchain/IBlockhashCache.cs b/src/Nethermind/Nethermind.Blockchain/IBlockhashCache.cs index 4605f3e9d57e..64d34a56a930 100644 --- a/src/Nethermind/Nethermind.Blockchain/IBlockhashCache.cs +++ b/src/Nethermind/Nethermind.Blockchain/IBlockhashCache.cs @@ -10,7 +10,7 @@ namespace Nethermind.Blockchain; public interface IBlockhashCache { - Hash256? GetHash(BlockHeader headBlock, int depth); + Hash256? GetHash(BlockHeader headBlock, ulong depth); Task Prefetch(BlockHeader blockHeader, CancellationToken cancellationToken); /// Drops all cached block-hash chains. diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs index 144ca75761cd..f315dfdafff6 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs @@ -217,10 +217,10 @@ public event EventHandler? OnForkChoiceUpd remove => throw new NotSupportedException(); } - public Hash256? GetHash(BlockHeader headBlock, int depth) => + public Hash256? GetHash(BlockHeader headBlock, ulong depth) => depth == 0 ? headBlock.Hash - : _numberToHeader.TryGetValue(headBlock.Number - (ulong)depth, out BlockHeader? header) + : _numberToHeader.TryGetValue(headBlock.Number - depth, out BlockHeader? header) ? header?.Hash : null; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs index 8912426ffe3f..8476e11acd4f 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs @@ -138,6 +138,12 @@ public BlockBuilder WithTotalDifficulty(long difficulty) return this; } + public BlockBuilder WithTotalDifficulty(ulong difficulty) + { + TestObjectInternal.Header.TotalDifficulty = difficulty; + return this; + } + public BlockBuilder WithTotalDifficulty(UInt256? difficulty) { TestObjectInternal.Header.TotalDifficulty = difficulty; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs index 06668236a285..feb3fc06279c 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs @@ -134,6 +134,12 @@ public BlockHeaderBuilder WithTotalDifficulty(long totalDifficulty) return this; } + public BlockHeaderBuilder WithTotalDifficulty(ulong totalDifficulty) + { + TestObjectInternal.TotalDifficulty = totalDifficulty; + return this; + } + public BlockHeaderBuilder WithGasLimit(ulong gasLimit) { TestObjectInternal.GasLimit = gasLimit; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs index b1e608563fae..1e5a5bfb2508 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockTreeBuilder.cs @@ -197,6 +197,15 @@ public BlockTreeBuilder WithStateRoot(Func stateRootGen) return this; } + public BlockTreeBuilder OfChainLength(ulong chainLength, int splitVariant = 0, int splitFrom = 0, bool withWithdrawals = false, params Address[] blockBeneficiaries) + { + OfChainLength(out _, (int)chainLength, splitVariant, splitFrom, withWithdrawals, blockBeneficiaries); + return this; + } + + public BlockTreeBuilder OfChainLength(out Block headBlock, ulong chainLength, int splitVariant = 0, int splitFrom = 0, bool withWithdrawals = false, params Address[] blockBeneficiaries) => + OfChainLength(out headBlock, (int)chainLength, splitVariant, splitFrom, withWithdrawals, blockBeneficiaries); + public BlockTreeBuilder OfChainLength(int chainLength, int splitVariant = 0, int splitFrom = 0, bool withWithdrawals = false, params Address[] blockBeneficiaries) { OfChainLength(out _, chainLength, splitVariant, splitFrom, withWithdrawals, blockBeneficiaries); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs index e607076c3512..56524314210a 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs @@ -33,7 +33,7 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp ulong cumS_afterTx1 = tx1State; ulong stateAvailable = blockGasLimit - cumS_afterTx1; - ulong tx2Gas = (ulong)((long)(BaseIntrinsicRegular + stateAvailable) + delta); + ulong tx2Gas = (ulong)((long)stateAvailable + delta); Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, cumR_afterTx1, cumS_afterTx1, tx2Gas, BaseIntrinsicRegular, intrinsicState: 0); @@ -41,9 +41,9 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp Assert.That(outcome, Is.EqualTo(expected)); } - // Creation tx: tx.gas > regular_available but (tx.gas - intrinsic.state) fits. + // Creation tx: tx.gas > regular_available and is rejected on regular dimension without subtraction. [Test] - public void Creation_tx_regular_check_subtracts_intrinsic_state_accepts() + public void Creation_tx_regular_check_without_subtraction_rejects() { ulong intrinsicState = IntrinsicNewAccountState; ulong intrinsicRegular = CreateIntrinsicRegular; @@ -55,19 +55,16 @@ public void Creation_tx_regular_check_subtracts_intrinsic_state_accepts() ulong cumR_afterFiller = blockGasLimit - remainingRegular; ulong cumS_afterFiller = 0; - // Creation tx: tx.gas = intrinsic_total. Raw tx.gas > remaining_regular - // but tx.gas - intrinsic_state = intrinsic_regular <= remaining_regular. + // Creation tx: tx.gas = intrinsic_total. Raw tx.gas > remaining_regular. + // Under the corrected EIP-8037 logic, this must be rejected as no intrinsic gas subtraction is performed. ulong createTxGas = intrinsicTotal; - Assert.That(createTxGas, Is.GreaterThan(remainingRegular), - "old formula must reject -> proves new formula behaves differently"); - Assert.That(createTxGas - intrinsicState, Is.LessThanOrEqualTo(remainingRegular), - "new formula must accept"); + Assert.That(Math.Min(Eip7825Constants.DefaultTxGasLimitCap, createTxGas), Is.GreaterThan(remainingRegular)); Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, cumR_afterFiller, cumS_afterFiller, createTxGas, intrinsicRegular, intrinsicState); - Assert.That(outcome, Is.EqualTo(Eip8037BlockGasInclusionCheck.Outcome.Ok)); + Assert.That(outcome, Is.EqualTo(Eip8037BlockGasInclusionCheck.Outcome.RegularDimensionExceeded)); } // Single tx state contribution > block_gas_limit -> reject. diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs index c200a3fdfdfa..13bef07bcfa2 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs @@ -13,6 +13,22 @@ public static class Eip8037BlockGasInclusionCheck { public enum Outcome { Ok, RegularDimensionExceeded, StateDimensionExceeded } + /// + /// Validates if a transaction can be included in a block under EIP-8037 pre-inclusion check. + /// + /// + /// Checks that the transaction's maximum possible contribution to both regular and state gas dimensions + /// does not exceed the remaining available space for those dimensions in the block. + /// Refer to EIP-8037 section "Transaction validation": + /// min(TX_MAX_GAS_LIMIT, tx.gas) <= regular_gas_available and tx.gas <= state_gas_available. + /// + /// The block's gas limit. + /// The block's cumulative regular gas used. + /// The block's cumulative state gas used. + /// The transaction's gas limit. + /// Unused. Kept for backward compatibility. + /// Unused. Kept for backward compatibility. + /// An Outcome representing the validation result. public static Outcome Validate( ulong blockGasLimit, ulong cumulativeBlockRegular, @@ -24,16 +40,11 @@ public static Outcome Validate( ulong regularAvailable = blockGasLimit - cumulativeBlockRegular; ulong stateAvailable = blockGasLimit - cumulativeBlockState; - // Keep below-intrinsic txs from producing a negative worst-case regular dimension. - ulong worstCaseRegular = txGas > intrinsicState ? txGas - intrinsicState : 0UL; - if (worstCaseRegular > Eip7825Constants.DefaultTxGasLimitCap) - worstCaseRegular = Eip7825Constants.DefaultTxGasLimitCap; + ulong worstCaseRegular = Math.Min(Eip7825Constants.DefaultTxGasLimitCap, txGas); if (worstCaseRegular > regularAvailable) return Outcome.RegularDimensionExceeded; - // The state dimension has no per-tx equivalent of EIP-7825's DefaultTxGasLimitCap; - // state-heavy work may be funded by the state reservoir above that regular-dimension cap. - ulong worstCaseState = txGas > intrinsicRegular ? txGas - intrinsicRegular : 0UL; + ulong worstCaseState = txGas; if (worstCaseState > stateAvailable) return Outcome.StateDimensionExceeded; diff --git a/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs b/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs index 2aa00fecb030..53b1739dcd48 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Eth/EthSyncingInfoTests.cs @@ -28,15 +28,15 @@ public void GetFullInfo_WhenNotSyncing() ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178001L).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000L).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178001UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000UL).TestObject).TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, syncConfig, new StaticSelector(SyncMode.All), syncProgressResolver, LimboLogs.Instance); SyncingResult syncingResult = ethSyncingInfo.GetFullInfo(); Assert.That(syncingResult.IsSyncing, Is.EqualTo(false)); - Assert.That(syncingResult.CurrentBlock, Is.EqualTo(0)); - Assert.That(syncingResult.HighestBlock, Is.EqualTo(0)); - Assert.That(syncingResult.StartingBlock, Is.EqualTo(0)); + Assert.That(syncingResult.CurrentBlock, Is.EqualTo(0UL)); + Assert.That(syncingResult.HighestBlock, Is.EqualTo(0UL)); + Assert.That(syncingResult.StartingBlock, Is.EqualTo(0UL)); Assert.That(syncingResult.SyncMode, Is.EqualTo(SyncMode.None)); } @@ -49,29 +49,29 @@ public void GetFullInfo_WhenSyncing() ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178010L).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000L).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178010UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000UL).TestObject).TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, syncConfig, new StaticSelector(SyncMode.All), syncProgressResolver, LimboLogs.Instance); SyncingResult syncingResult = ethSyncingInfo.GetFullInfo(); Assert.That(syncingResult.IsSyncing, Is.EqualTo(true)); - Assert.That(syncingResult.CurrentBlock, Is.EqualTo(6178000L)); - Assert.That(syncingResult.HighestBlock, Is.EqualTo(6178010)); - Assert.That(syncingResult.StartingBlock, Is.EqualTo(0)); + Assert.That(syncingResult.CurrentBlock, Is.EqualTo(6178000UL)); + Assert.That(syncingResult.HighestBlock, Is.EqualTo(6178010UL)); + Assert.That(syncingResult.StartingBlock, Is.EqualTo(0UL)); Assert.That(syncingResult.SyncMode, Is.EqualTo(SyncMode.All)); } - [TestCase(6178001L, 6178000L, false)] - [TestCase(6178010L, 6178000L, true)] - public void IsSyncing_ReturnsExpectedResult(long bestHeader, long currentHead, bool expectedResult) + [TestCase(6178001UL, 6178000UL, false)] + [TestCase(6178010UL, 6178000UL, true)] + public void IsSyncing_ReturnsExpectedResult(ulong bestHeader, ulong currentHead, bool expectedResult) { IBlockTree blockTree = Substitute.For(); ISyncPointers syncPointers = Substitute.For(); ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber((ulong)bestHeader).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber((ulong)currentHead).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(bestHeader).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(currentHead).TestObject).TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, new SyncConfig(), new StaticSelector(SyncMode.All), syncProgressResolver, LimboLogs.Instance); SyncingResult syncingResult = ethSyncingInfo.GetFullInfo(); @@ -103,13 +103,13 @@ public void IsSyncing_AncientBarriers(bool resolverDownloadingBodies, syncProgressResolver.IsFastBlocksBodiesFinished().Returns(resolverDownloadingBodies); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(resolverDownloadingReceipts); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178001L).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000L).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(6178001UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(6178000UL).TestObject).TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, syncConfig, new StaticSelector(SyncMode.FastBlocks), syncProgressResolver, LimboLogs.Instance); SyncingResult syncingResult = ethSyncingInfo.GetFullInfo(); - Assert.That(syncingResult, Is.EqualTo(CreateSyncingResult(expectedResult, 6178000L, 6178001L, SyncMode.FastBlocks))); + Assert.That(syncingResult, Is.EqualTo(CreateSyncingResult(expectedResult, 6178000UL, 6178001UL, SyncMode.FastBlocks))); } [Test] @@ -122,8 +122,8 @@ public void Should_calculate_sync_time() syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(100).TestObject) + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(100UL).TestObject) .TestObject); EthSyncingInfo ethSyncingInfo = new(blockTree, syncPointers, syncConfig, @@ -132,8 +132,8 @@ public void Should_calculate_sync_time() Assert.That(ethSyncingInfo.IsSyncing(), Is.EqualTo(false)); Assert.That(ethSyncingInfo.UpdateAndGetSyncTime().TotalMicroseconds, Is.EqualTo(0)); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(80).TestObject) + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(80UL).TestObject) .TestObject); // First call starting timer @@ -147,25 +147,25 @@ public void Should_calculate_sync_time() Assert.That(ethSyncingInfo.UpdateAndGetSyncTime().TotalMicroseconds, Is.Not.EqualTo(0)); // Sync ended time should be zero - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(100).TestObject) + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(100UL).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(100UL).TestObject) .TestObject); Assert.That(ethSyncingInfo.IsSyncing(), Is.EqualTo(false)); Assert.That(ethSyncingInfo.UpdateAndGetSyncTime().TotalMicroseconds, Is.EqualTo(0)); } - [TestCase(6178001L, 6178000L)] - [TestCase(8001L, 8000L)] - public void IsSyncing_ReturnsFalseOnFastSyncWithoutPivot(long bestHeader, long currentHead) + [TestCase(6178001UL, 6178000UL)] + [TestCase(8001UL, 8000UL)] + public void IsSyncing_ReturnsFalseOnFastSyncWithoutPivot(ulong bestHeader, ulong currentHead) { IBlockTree blockTree = Substitute.For(); ISyncPointers syncPointers = Substitute.For(); ISyncProgressResolver syncProgressResolver = Substitute.For(); syncProgressResolver.IsFastBlocksBodiesFinished().Returns(false); syncProgressResolver.IsFastBlocksReceiptsFinished().Returns(false); - blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber((ulong)bestHeader).TestObject); - blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber((ulong)currentHead).TestObject).TestObject); + blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(bestHeader).TestObject); + blockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithNumber(currentHead).TestObject).TestObject); SyncConfig syncConfig = new() { FastSync = true, @@ -179,10 +179,10 @@ public void IsSyncing_ReturnsFalseOnFastSyncWithoutPivot(long bestHeader, long c Assert.That(syncingResult.IsSyncing, Is.False); } - private SyncingResult CreateSyncingResult(bool isSyncing, long currentBlock, long highestBlock, SyncMode syncMode) + private SyncingResult CreateSyncingResult(bool isSyncing, ulong currentBlock, ulong highestBlock, SyncMode syncMode) { if (!isSyncing) return SyncingResult.NotSyncing; - return new SyncingResult { CurrentBlock = (ulong)currentBlock, HighestBlock = (ulong)highestBlock, IsSyncing = true, StartingBlock = 0, SyncMode = syncMode }; + return new SyncingResult { CurrentBlock = currentBlock, HighestBlock = highestBlock, IsSyncing = true, StartingBlock = 0, SyncMode = syncMode }; } } } diff --git a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs index 7410fab5eba7..32618d159f3a 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs @@ -351,19 +351,10 @@ private async Task DoQueueBlocks(bool isForward) ProcessingQueue queue = Direction(isForward).Queue!; - int? next = GetNextBlockNumber(isForward); - int start; - if (next is not { } startFromStorage) - { - // Cast to int is safe here: LogIndex storage uses int block numbers for performance. - // pivotNumber is bounded by MaxTargetBlockNumber which is derived from BestKnownNumber - // and will not exceed int.MaxValue in practice (~2 billion blocks). - start = isForward ? (int)pivotNumber : (int)pivotNumber - 1; - } - else - { - start = startFromStorage; - } + // Cast to int is safe here: LogIndex storage uses int block numbers for performance. + // pivotNumber is bounded by MaxTargetBlockNumber which is derived from BestKnownNumber + // and will not exceed int.MaxValue in practice (~2 billion blocks). + int start = GetNextBlockNumber(isForward) ?? (isForward ? (int)pivotNumber : (int)pivotNumber - 1); BlockReceipts[] buffer = new BlockReceipts[_config.MaxBatchSize]; while (!CancellationToken.IsCancellationRequested) From b781898e5992b65d854f0860f4ec231382ccb629 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 10:10:07 +0200 Subject: [PATCH 18/60] =?UTF-8?q?fix(geth-types):=20address=20review=20fin?= =?UTF-8?q?dings=20=E2=80=94=20unsigned-underflow=20guards=20and=20dead=20?= =?UTF-8?q?checks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HIGH (consensus / correctness): - EvmInstructions.Storage SSTORE refund: saturating subtract to prevent the ulong wrap that would silently grant the maximum post-cap refund - StateSyncPivot.Diff: precedence bug returned the absolute number instead of the difference; reroute through SaturatingSub - BlockTree.AcceptVisitor: bail on empty/inverted range instead of looping ~2^64 - BlockTreeSuggestPacer.WaitForQueue: guard the subtract so a head overtake doesn't pause the pacer indefinitely - BinarySearchBlockNumber: bail at index==0 in the Down branch - WitnessGeneratingHeaderFinder: count-driven loop; old i-- looped forever when _lowestRequestedHeader == 0 MEDIUM: - SaturatingSub promoted to a shared UInt64Extensions; TransactionProcessor and EthereumGasPolicy now use it - SszNumericChecks deleted; ulong fields no longer narrow to long - ReceiptMigration.tx-index expiry: explicit-guard intent, no more (long?) wrap trick - EraStore.GetEpochNumber: throw on blockNumber < FirstBlock - ReceiptFixMigration: SaturatingSub Head?.Number - 2 - EraAdminRpcModule / EraE.AdminEraService: reject negative start/end before the (ulong) cast turns -1 into MaxValue - E2StoreReader: reject negative starting_number from on-disk int64 - BlockParameter JSON Read: TryGetUInt64 path instead of throwing FormatException Xdc (flcl42): - SubnetPenaltyHandler.minBlockNumber / startRange: guard underflows before clamp - EpochSwitchManager.estBlockNum: SaturatingSub before Math.Max - Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas: saturate the multi-step subtraction so a bookkeeping bug doesn't silently blow the block gas limit Cleanups: - NewPayloadHandler emoji: explicit if-tree (the < 0 branch was dead on ulong) - DebugRpcModule.debug_getBlockRlp: remove dead blockNumber >= 0 check - TraceStorePruner: early-return on block.Number <= _blockToKeep - XdcRpcModule: dead BlockNumber < 0 checks → BlockNumber is null - StateSyncPivot.TrySetNewBestHeader: drop the no-op Math.Max(x, 0) - PowForwardHeaderProvider: drop the no-op outer Math.Max and the stale comment - BlockDownloaderTests: drop the no-op Math.Max(0UL, …) noise - SurgeGasPriceOracle.GetAverageGasUsagePerBlock: dead currentBlockNumber >= 0 and the unguarded i-- at i==0 - BlockhashStore.GetBlockHashFromState: drop dead requiredBlockNumber < 0 - ISurgeConfig.FeeHistoryBlockCount, L2GasUsageWindowSize, MaxGasLimitRatio: int → ulong (eliminates the casts at call sites) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../BlockTree.AcceptVisitor.cs | 2 ++ .../BlockTree.Initializer.cs | 1 + .../BlockTreeSuggestPacer.cs | 5 +++- .../Blocks/BlockhashStore.cs | 3 +- .../Find/BlockParameter.cs | 5 +++- .../WitnessGeneratingHeaderFinder.cs | 6 +++- .../Extensions/UInt64Extensions.cs | 6 ++++ src/Nethermind/Nethermind.Era1/EraStore.cs | 4 +-- .../JsonRpc/EraAdminRpcModule.cs | 10 +++++-- .../Nethermind.EraE/Admin/AdminEraService.cs | 6 ++++ .../Nethermind.EraE/E2Store/E2StoreReader.cs | 7 +++-- .../Eip8037BlockGasInclusionCheck.cs | 5 +++- .../GasPolicy/EthereumGasPolicy.cs | 14 ++++----- .../Instructions/EvmInstructions.Storage.cs | 7 +++-- .../TransactionProcessor.cs | 23 ++++++++------- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Steps/Migrations/ReceiptFixMigration.cs | 4 ++- .../Steps/Migrations/ReceiptMigration.cs | 8 +++-- .../TraceStorePruner.cs | 18 +++++------- .../Modules/DebugModule/DebugRpcModule.cs | 2 +- .../Handlers/NewPayloadHandler.cs | 10 +++---- .../SszRest/SszCodec.cs | 12 -------- .../SszRest/SszExecutionPayload.cs | 6 ++-- .../SszRest/SszNumericChecks.cs | 29 ------------------- .../BlockDownloaderTests.cs | 6 ++-- .../Blocks/PowForwardHeaderProvider.cs | 2 +- .../FastSync/StateSyncPivot.cs | 6 ++-- .../SurgeGasPriceOracleTests.cs | 20 ++++++------- .../TxPoolContentListsTests.cs | 12 ++++---- .../Nethermind.Taiko/Config/ISurgeConfig.cs | 6 ++-- .../Nethermind.Taiko/Config/SurgeConfig.cs | 6 ++-- .../Rpc/SurgeGasPriceOracle.cs | 7 +++-- .../Rpc/TaikoEngineRpcModule.cs | 2 +- .../Nethermind.Xdc/EpochSwitchManager.cs | 5 +++- .../Nethermind.Xdc/RPC/XdcRpcModule.cs | 20 ++++++------- .../Nethermind.Xdc/SubnetPenaltyHandler.cs | 7 +++-- 36 files changed, 147 insertions(+), 147 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs index ca6050177e7c..0b20fa1bcf86 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.AcceptVisitor.cs @@ -20,6 +20,8 @@ public async Task Accept(IBlockTreeVisitor visitor, CancellationToken cancellati try { + if (visitor.EndLevelExclusive <= visitor.StartLevelInclusive) return; + ulong levelNumber = visitor.StartLevelInclusive; ulong blocksToVisit = visitor.EndLevelExclusive - visitor.StartLevelInclusive; for (ulong i = 0; i < blocksToVisit; i++) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs index 5ab0c6122008..0532c8a6a0fd 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.Initializer.cs @@ -47,6 +47,7 @@ public void RecalculateTreeLevels() } else { + if (index == 0) break; // avoid ulong wrap right = index - 1; } } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs index 120f3a9d2762..863b53301b98 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeSuggestPacer.cs @@ -56,7 +56,10 @@ private void BlockTreeOnNewHeadBlock(object sender, BlockEventArgs e) public async Task WaitForQueue(ulong currentBlockNumber, CancellationToken token) { ulong currentHeadNumber = _blockTree.Head?.Number ?? 0; - if (currentBlockNumber - currentHeadNumber > _stopBatchSize && _dbBatchProcessed is null) + // Head can transiently overtake the suggestion (parallel-import advance, post-FCU); wrap would pause indefinitely. + if (currentBlockNumber > currentHeadNumber + && currentBlockNumber - currentHeadNumber > _stopBatchSize + && _dbBatchProcessed is null) { _blockNumberReachedToUnlock = currentBlockNumber - _stopBatchSize + _resumeBatchSize; TaskCompletionSource completionSource = new(TaskCreationOptions.RunContinuationsAsynchronously); diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs index d7b483ace53c..b65d9d785546 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockhashStore.cs @@ -34,8 +34,7 @@ public void ApplyBlockhashStateChanges(BlockHeader blockHeader, IReleaseSpec spe public Hash256? GetBlockHashFromState(BlockHeader currentHeader, ulong requiredBlockNumber, IReleaseSpec spec) { - if (requiredBlockNumber < 0 || - requiredBlockNumber >= currentHeader.Number || + if (requiredBlockNumber >= currentHeader.Number || requiredBlockNumber + spec.Eip2935RingBufferSize < currentHeader.Number) { return null; diff --git a/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs b/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs index c62a71de7993..f7d3ce837f73 100644 --- a/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs +++ b/src/Nethermind/Nethermind.Blockchain/Find/BlockParameter.cs @@ -151,7 +151,10 @@ public override void Write(Utf8JsonWriter writer, BlockParameter value, JsonSeri ReadStringFormatValueSequence(ref reader, options), JsonTokenType.StartObject => ReadObjectFormat(ref reader, typeToConvert, options), JsonTokenType.Null => BlockParameter.Latest, - JsonTokenType.Number when !EthereumJsonSerializer.StrictHexFormat => new BlockParameter(reader.GetUInt64()), + JsonTokenType.Number when !EthereumJsonSerializer.StrictHexFormat => + reader.TryGetUInt64(out ulong parsed) + ? new BlockParameter(parsed) + : throw new JsonException("block number must be a non-negative integer"), _ => throw new FormatException("unknown block parameter type") }; diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs index 47c3a210d259..2fd4b5648ebb 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/WitnessGeneratingHeaderFinder.cs @@ -55,12 +55,16 @@ public IOwnedReadOnlyList GetWitnessHeaders(Hash256 parentHash) if (index >= 0) { - for (ulong i = parentHeader.Number - 1; i >= _lowestRequestedHeader; i--) + // Count-driven: ulong i-- wraps past 0 when _lowestRequestedHeader == 0. + ulong i = parentHeader.Number - 1; + while (index >= 0) { currentHash = parentHeader.ParentHash!; parentHeader = inner.Get(currentHash, i) ?? throw new ArgumentException($"Unable to get requested header at hash {currentHash} and number {i} during witness generation"); headers[index--] = _decoder.Encode(parentHeader).Bytes; + if (index < 0 || i == 0) break; + i--; } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs index e0189c5bdbe8..d27a08e08fec 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/UInt64Extensions.cs @@ -4,12 +4,18 @@ using System; using System.Buffers.Binary; using System.Numerics; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Nethermind.Core.Extensions; public static class UInt64Extensions { + /// Returns max(0, a - b) without wrapping around 2^64. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong SaturatingSub(this ulong a, ulong b) => a > b ? a - b : 0UL; + + public static ReadOnlySpan ToBigEndianSpanWithoutLeadingZeros(this ulong value, out ulong buffer) { // Min 7 bytes as we still want a byte if the value is 0. diff --git a/src/Nethermind/Nethermind.Era1/EraStore.cs b/src/Nethermind/Nethermind.Era1/EraStore.cs index 1e9e7bab23d8..ac8032835e19 100644 --- a/src/Nethermind/Nethermind.Era1/EraStore.cs +++ b/src/Nethermind/Nethermind.Era1/EraStore.cs @@ -120,8 +120,8 @@ public EraStore( private long GetEpochNumber(ulong blockNumber) { - // This seems to be the geth way of encoding blocks. - // Cast to long is safe here: epoch numbers are small integers well within long range. + if (blockNumber < FirstBlock) + throw new EraException($"Block number {blockNumber} is below era store's first block {FirstBlock}."); long epochOffset = (long)((blockNumber - FirstBlock) / _maxEraFile); return FirstEpoch + epochOffset; } diff --git a/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs b/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs index f314e16879b4..bf6853cac084 100644 --- a/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs +++ b/src/Nethermind/Nethermind.Era1/JsonRpc/EraAdminRpcModule.cs @@ -7,7 +7,13 @@ namespace Nethermind.Era1.JsonRpc; public class EraAdminRpcModule(IAdminEraService eraService) : IEraAdminRpcModule { - public Task> admin_exportHistory(string destination, int start = 0, int end = 0) => ResultWrapper.Success(eraService.ExportHistory(destination, (ulong)start, (ulong)end)); + public Task> admin_exportHistory(string destination, int start = 0, int end = 0) => + start < 0 || end < 0 + ? ResultWrapper.Fail("start and end must be non-negative", ErrorCodes.InvalidParams) + : ResultWrapper.Success(eraService.ExportHistory(destination, (ulong)start, (ulong)end)); - public Task> admin_importHistory(string source, int start = 0, int end = 0, string? accumulatorFile = null) => ResultWrapper.Success(eraService.ImportHistory(source, (ulong)start, (ulong)end, accumulatorFile)); + public Task> admin_importHistory(string source, int start = 0, int end = 0, string? accumulatorFile = null) => + start < 0 || end < 0 + ? ResultWrapper.Fail("start and end must be non-negative", ErrorCodes.InvalidParams) + : ResultWrapper.Success(eraService.ImportHistory(source, (ulong)start, (ulong)end, accumulatorFile)); } diff --git a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs index 78b3721e60bc..d374a468bd46 100644 --- a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs +++ b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs @@ -21,6 +21,9 @@ public sealed class AdminEraService( public ResultWrapper ExportHistory(string destination, long from, long to) { + if (from < 0 || to < 0) + return ResultWrapper.Fail("from and to must be non-negative.", ErrorCodes.InvalidParams); + if (Interlocked.Exchange(ref _canEnterExport, 0) != 1) return ResultWrapper.Fail("An export job is already running."); @@ -37,6 +40,9 @@ public ResultWrapper ExportHistory(string destination, long from, long t public ResultWrapper ImportHistory(string source, long from, long to, string? accumulatorFile) { + if (from < 0 || to < 0) + return ResultWrapper.Fail("from and to must be non-negative.", ErrorCodes.InvalidParams); + if (Interlocked.Exchange(ref _canEnterImport, 0) != 1) return ResultWrapper.Fail("An import job is already running."); diff --git a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs index b2e6c4f40c0a..8276e751de07 100644 --- a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs +++ b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs @@ -179,8 +179,11 @@ private void EnsureIndexLoaded() _componentIndexTlvStart = indexEntryStart; - // Read starting block number (first field of index data) - _startBlock = (ulong)ReadInt64(indexEntryStart + EntryHeaderSize); + // ComponentIndex is int64 on disk; negative starting_number is an invalid archive. + long startingNumberRaw = ReadInt64(indexEntryStart + EntryHeaderSize); + if (startingNumberRaw < 0) + throw new EraFormatException($"Negative starting block number {startingNumberRaw} in EraE ComponentIndex."); + _startBlock = (ulong)startingNumberRaw; _indexLoaded = true; } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs index 13bef07bcfa2..681eceaf82e9 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Core; +using Nethermind.Core.Extensions; namespace Nethermind.Evm.GasPolicy; @@ -59,7 +60,9 @@ public static ulong CalculateBlockRegularGas( ulong stateGasSpillReclassified, ulong floorGas) { - ulong executionRegularGasUsed = initialRegularGas - remainingRegularGas - stateGasSpill + stateGasSpillReclassified; + // Saturating: a stale invariant would otherwise wrap and silently blow the block gas limit. + ulong consumedAfterRefund = initialRegularGas.SaturatingSub(remainingRegularGas); + ulong executionRegularGasUsed = consumedAfterRefund.SaturatingSub(stateGasSpill) + stateGasSpillReclassified; ulong blockRegularGas = intrinsicRegularGas + executionRegularGasUsed; return Math.Max(blockRegularGas, floorGas); } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 7ac729e17343..8984b5e85b58 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Int256; @@ -201,12 +202,9 @@ public static void RevertRefundToHalt(ref EthereumGasPolicy parentGas, in Ethere parentGas.StateGasUsed -= childGas.StateGasUsed; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong SaturatingSub(ulong a, ulong b) => a > b ? a - b : 0UL; - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ulong GetUnrefundedStateGasSpill(in EthereumGasPolicy childGas) => - SaturatingSub(childGas.StateGasSpill, childGas.StateGasSpillRefunded); + childGas.StateGasSpill.SaturatingSub(childGas.StateGasSpillRefunded); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOutOfGas(in EthereumGasPolicy gas) => gas.OutOfGas; @@ -341,7 +339,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong refundableStateGas = SaturatingSub(gas.StateGasUsed, stateGasFloor); + ulong refundableStateGas = gas.StateGasUsed.SaturatingSub(stateGasFloor); ulong appliedRefund = Math.Min(amount, refundableStateGas); if (trackSpillRefund) { @@ -355,7 +353,7 @@ public static void RefundStateGas(ref EthereumGasPolicy gas, ulong amount, ulong [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong DiscardStateGas(ref EthereumGasPolicy gas, ulong amount, ulong stateGasFloor, bool trackSpillRefund) { - ulong discardableStateGas = SaturatingSub(gas.StateGasUsed, stateGasFloor); + ulong discardableStateGas = gas.StateGasUsed.SaturatingSub(stateGasFloor); ulong appliedRefund = Math.Min(amount, discardableStateGas); if (trackSpillRefund) { @@ -423,7 +421,7 @@ public static ulong ApplyCodeInsertRefunds(ref EthereumGasPolicy gas, ulong code if (codeInsertRefunds > 0UL && spec.IsEip8037Enabled) { ulong stateGasRefund = checked(GetNewAccountStateCost(in gas) * codeInsertRefunds); - ulong refundFloor = SaturatingSub(stateGasFloor, stateGasRefund); + ulong refundFloor = stateGasFloor.SaturatingSub(stateGasRefund); RefundStateGas(ref gas, stateGasRefund, refundFloor, trackSpillRefund: false); } @@ -518,7 +516,7 @@ public static EthereumGasPolicy CreateAvailableFromIntrinsic(ulong gasLimit, in { // EIP-8037: cap gas_left at TX_MAX_GAS_LIMIT - intrinsic_regular, overflow goes to reservoir ulong maxGasLeft = Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value; - reservoir = SaturatingSub(executionGas, maxGasLeft); + reservoir = executionGas.SaturatingSub(maxGasLeft); executionGas -= reservoir; } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index 97bc900e527e..e3215e9f6ca8 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -550,9 +550,12 @@ internal static EvmExceptionType InstructionSStoreMetered= sClearRefunds here, but a wrap would + // grant the maximum refund post-cap. Consensus-relevant. + ulong refundBefore = vmState.Refund; + vmState.Refund = refundBefore.SaturatingSub(sClearRefunds); if (vm.TxTracer.IsTracingRefunds) - vm.TxTracer.ReportRefund(-(long)sClearRefunds); ///????? + vm.TxTracer.ReportRefund(-(long)(refundBefore - vmState.Refund)); } if (newIsZero) diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index d5846988db68..faef0155108d 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -11,6 +11,7 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Messages; using Nethermind.Core.Specs; using Nethermind.Core.Validation; @@ -607,7 +608,7 @@ private TransactionResult Apply8037DelegationRefunds( return TransactionResult.ErrorType.MalformedTransaction.WithDetail("authorization refund gas overflow"); } - ulong refundFloor = stateGasFloor > stateGasRefund ? stateGasFloor - stateGasRefund : 0UL; + ulong refundFloor = stateGasFloor.SaturatingSub(stateGasRefund); TGasPolicy.RefundStateGas(ref gasAvailable, stateGasRefund, refundFloor, trackSpillRefund: false); delegationRefunds = 0; delegationAuthBaseRefunds = 0; @@ -1350,8 +1351,8 @@ private GasConsumed CompleteEip8037Halt( ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); ulong refundedTopLevelCreateStateGas = CalculateTopLevelCreateIntrinsicStateRefund(tx, in intrinsicGasStandard); ulong initialStateReservoir = CalculateInitialStateReservoir(tx.GasLimit, in intrinsicGasStandard); - ulong refundedIntrinsicStateGas = (postIntrinsicStateReservoir > initialStateReservoir ? postIntrinsicStateReservoir - initialStateReservoir : 0UL) + refundedTopLevelCreateStateGas; - ulong postHaltIntrinsicStateGas = intrinsicStateGas > refundedIntrinsicStateGas ? intrinsicStateGas - refundedIntrinsicStateGas : 0UL; + ulong refundedIntrinsicStateGas = postIntrinsicStateReservoir.SaturatingSub(initialStateReservoir) + refundedTopLevelCreateStateGas; + ulong postHaltIntrinsicStateGas = intrinsicStateGas.SaturatingSub(refundedIntrinsicStateGas); RefundRevertedExecutionStateGas(spec, postHaltIntrinsicStateGas, ref gas); ulong refundedCreateStateSpillForHalt = CalculateRefundedCreateStateSpillForHalt(in gas); ulong postHaltStateReservoir = Math.Max(postIntrinsicStateReservoir, TGasPolicy.GetStateReservoir(in gas)); @@ -1374,7 +1375,7 @@ protected virtual GasConsumed RefundOnFail( ulong remainingRegularGas = TGasPolicy.GetRemainingGas(in gas); ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); ulong totalSub = remainingRegularGas + stateReservoir; - ulong spentGas = Math.Max(tx.GasLimit > totalSub ? tx.GasLimit - totalSub : 0UL, floorGas); + ulong spentGas = Math.Max(tx.GasLimit.SaturatingSub(totalSub), floorGas); ulong blockGas = Calculate8037BlockRegularGas(in gas, in intrinsicGasStandard, tx.GasLimit, floorGas, remainingRegularGas); ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gas); @@ -1404,7 +1405,7 @@ protected virtual GasConsumed RefundOnContractCollision( TGasPolicy.SetOutOfGas(ref gasAfterCollision); ulong reservoirAfterCollision = TGasPolicy.GetStateReservoir(in gasAfterCollision); - ulong spentGas = Math.Max(tx.GasLimit > reservoirAfterCollision ? tx.GasLimit - reservoirAfterCollision : 0UL, floorGas); + ulong spentGas = Math.Max(tx.GasLimit.SaturatingSub(reservoirAfterCollision), floorGas); ulong blockStateGas = TGasPolicy.GetStateGasUsed(in gasAfterCollision); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, spentGas, blockStateGas); @@ -1424,12 +1425,12 @@ protected virtual GasConsumed RefundOnTopLevelHalt( return tx.GasLimit; ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); - ulong spentGas = Math.Max(tx.GasLimit > stateReservoir ? tx.GasLimit - stateReservoir : 0UL, floorGas); + ulong spentGas = Math.Max(tx.GasLimit.SaturatingSub(stateReservoir), floorGas); ulong intrinsicStateGas = TGasPolicy.GetStateGasUsed(in gas); ulong spillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); - ulong effectiveStateGas = (intrinsicStateGas > spillBurned ? intrinsicStateGas - spillBurned : 0UL) + refundedCreateStateSpillForHalt; + ulong effectiveStateGas = intrinsicStateGas.SaturatingSub(spillBurned) + refundedCreateStateSpillForHalt; ulong totalSub = stateReservoir + effectiveStateGas; - ulong blockGas = Math.Max(tx.GasLimit > totalSub ? tx.GasLimit - totalSub : 0UL, floorGas); + ulong blockGas = Math.Max(tx.GasLimit.SaturatingSub(totalSub), floorGas); return RefundFailedEip8037Gas(tx, spec, opts, in gasPrice, spentGas, blockGas, effectiveStateGas); } @@ -1597,7 +1598,7 @@ private static ulong CalculateInitialStateReservoir( { ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); ulong totalCap = intrinsicStateGas + Eip7825Constants.DefaultTxGasLimitCap; - return txGasLimit > totalCap ? txGasLimit - totalCap : 0UL; + return txGasLimit.SaturatingSub(totalCap); } private (ulong spentGas, ulong refund) CalculateSpentGasAndRefund( @@ -1670,9 +1671,9 @@ private static ulong Calculate8037BlockRegularGas( ulong intrinsicRegularGas = TGasPolicy.GetRemainingGas(in intrinsicGasStandard); ulong intrinsicStateGas = TGasPolicy.GetStateReservoir(in intrinsicGasStandard); ulong totalCap = intrinsicStateGas + Eip7825Constants.DefaultTxGasLimitCap; - ulong initialReservoir = txGasLimit > totalCap ? txGasLimit - totalCap : 0UL; + ulong initialReservoir = txGasLimit.SaturatingSub(totalCap); ulong totalSub = intrinsicRegularGas + intrinsicStateGas + initialReservoir; - ulong initialRegularGas = txGasLimit > totalSub ? txGasLimit - totalSub : 0UL; + ulong initialRegularGas = txGasLimit.SaturatingSub(totalSub); ulong stateGasSpill = TGasPolicy.GetStateGasSpill(in gasAfterExecution); ulong stateGasSpillReclassified = TGasPolicy.GetStateGasSpillReclassified(in gasAfterExecution); return Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 0034a4703433..8a2191ca814a 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -434,7 +434,7 @@ private void TryChargeAndDepositCode( Address callCodeOwner = previousState.Env.ExecutingAccount; ulong childStateReservoir = TGasPolicy.GetStateReservoir(in previousState.Gas); - ulong stateSpill = stateDepositCost > childStateReservoir ? stateDepositCost - childStateReservoir : 0UL; + ulong stateSpill = stateDepositCost.SaturatingSub(childStateReservoir); bool hasEnoughGas = gasAvailableForCodeDeposit >= regularDepositCost + stateSpill; bool chargedCodeDeposit = false; diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs index 2facaf675027..67240ff04e6d 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptFixMigration.cs @@ -11,6 +11,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Visitors; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Logging; @@ -34,9 +35,10 @@ public async Task Run(CancellationToken cancellationToken) { if (syncConfig.FixReceipts) { + ulong endLevelExclusive = (blockTree.Head?.Number ?? 0UL).SaturatingSub(2UL); using MissingReceiptsFixVisitor visitor = new( syncConfig.AncientReceiptsBarrierCalc, - blockTree.Head?.Number - 2 ?? 0UL, + endLevelExclusive, receiptStorage, logManager, syncPeerPool, diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs index b3d648db13d5..695e5cd56447 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs @@ -296,8 +296,12 @@ private void MigrateBlock(Block block) // Receipts are now prefixed with block number. _receiptsBlockDb.Delete(block.Hash!); - // Remove old tx index - bool txIndexExpired = _receiptConfig.TxLookupLimit != 0 && (long?)(_blockTree.Head?.Number - block.Number) > _receiptConfig.TxLookupLimit; + // Guarded: block.Number can transiently exceed head during reorgs. + ulong? headNumber = _blockTree.Head?.Number; + bool txIndexExpired = _receiptConfig.TxLookupLimit > 0 + && headNumber is ulong h + && h > block.Number + && h - block.Number > (ulong)_receiptConfig.TxLookupLimit.Value; bool neverIndexTx = _receiptConfig.TxLookupLimit == -1; if (neverIndexTx || txIndexExpired) { diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs index 099b4eb16f59..67dc82174b44 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs @@ -38,19 +38,15 @@ public TraceStorePruner(IBlockTree blockTree, IDb db, ulong blockToKeep, ILogMan private void OnBlockAddedToMain(object? sender, BlockReplacementEventArgs e) => Task.Run((() => { + if (e.Block.Number <= _blockToKeep) return; ulong levelToDelete = e.Block.Number - _blockToKeep; - if (levelToDelete > 0) + ChainLevelInfo? level = _blockTree.FindLevel(levelToDelete); + if (level is null) return; + for (int i = 0; i < level.BlockInfos.Length; i++) { - ChainLevelInfo? level = _blockTree.FindLevel(levelToDelete); - if (level is not null) - { - for (int i = 0; i < level.BlockInfos.Length; i++) - { - BlockInfo blockInfo = level.BlockInfos[i]; - if (_logger.IsTrace) _logger.Trace($"Removing traces from TraceStore on level {levelToDelete} for block {blockInfo}."); - _db.Delete(blockInfo.BlockHash); - } - } + BlockInfo blockInfo = level.BlockInfos[i]; + if (_logger.IsTrace) _logger.Trace($"Removing traces from TraceStore on level {levelToDelete} for block {blockInfo}."); + _db.Delete(blockInfo.BlockHash); } })); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index 2252d8629ca8..150b8a9ef6d0 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -466,7 +466,7 @@ public ResultWrapper> debug_intermediateRoots(Hash2 public ResultWrapper debug_gcStats() => throw new NotImplementedException(); public ResultWrapper debug_getBlockRlp(ulong blockNumber) => - GetBlockRlpOrFail(new BlockParameter(blockNumber >= 0 ? blockNumber : 0UL)); + GetBlockRlpOrFail(new BlockParameter(blockNumber)); public ResultWrapper debug_getBlockRlpByHash(Hash256 hash) => GetBlockRlpOrFail(new BlockParameter(hash)); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs index b7423525ec5c..07b1bc392cd9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs @@ -96,12 +96,10 @@ public NewPayloadHandler( _processingQueue.BlockRemoved += GetProcessingQueueOnBlockRemoved; } - private string GetGasChange(ulong blockGasLimit) => (blockGasLimit - _lastBlockGasLimit) switch - { - > 0 => "👆", - // < 0 => "👇", - _ => " " - }; + private string GetGasChange(ulong blockGasLimit) => + blockGasLimit > _lastBlockGasLimit ? "👆" + : blockGasLimit < _lastBlockGasLimit ? "👇" + : " "; /// /// Processes the execution payload and returns the diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs index 67f54a832a15..fa67cb2041a5 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs @@ -217,18 +217,6 @@ public static Hash256[] DecodeGetPayloadBodiesByHashRequest(ReadOnlySequence - /// Decodes an SSZ-encoded GetPayloadBodiesByRange request and returns the - /// start block number and count as ulong values. - /// - /// - /// Previously returned (long start, long count) and went through - /// SszNumericChecks.CheckedLong to guard against overflow when narrowing - /// uint64 wire values to long. Now that BlockHeader.Number - /// (and the engine-API handler signatures) are ulong, no narrowing is - /// required: the wire values are used directly. SszNumericChecks.CheckedLong - /// has no remaining callers and should be deleted. - /// public static (ulong start, ulong count) DecodeGetPayloadBodiesByRangeRequest(ReadOnlySequence buf) { GetPayloadBodiesByRangeRequestWire.Decode(buf, out GetPayloadBodiesByRangeRequestWire wire); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs index d467aa9465dc..1b3fce7798b8 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszExecutionPayload.cs @@ -80,19 +80,19 @@ public Hash256 PrevRandao public ulong BlockNumber { get => Inner.BlockNumber; - set => Inner.BlockNumber = SszNumericChecks.CheckedLong(value); + set => Inner.BlockNumber = value; } public ulong GasLimit { get => Inner.GasLimit; - set => Inner.GasLimit = SszNumericChecks.CheckedLong(value); + set => Inner.GasLimit = value; } public ulong GasUsed { get => Inner.GasUsed; - set => Inner.GasUsed = SszNumericChecks.CheckedLong(value); + set => Inner.GasUsed = value; } public ulong Timestamp diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs deleted file mode 100644 index c41a0c2ee4d4..000000000000 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszNumericChecks.cs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Runtime.CompilerServices; - -namespace Nethermind.Merge.Plugin.SszRest; - -internal static class SszNumericChecks -{ - /// - /// Converts an SSZ uint64 value to , throwing - /// when the value exceeds . - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong CheckedLong(ulong value) - { - if (value > long.MaxValue) - ThrowLongOutOfRange(value); - - return value; - - [DoesNotReturn, StackTraceHidden] - static void ThrowLongOutOfRange(ulong value) => - throw new InvalidDataException($"SSZ uint64 value {value} exceeds valid range for long"); - } -} diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index ad6af5a5d396..9afa7f41fe5f 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -109,7 +109,7 @@ public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSync syncPeer.ExtendTree(chainLength * 2); await ctx.FullSyncUntilNoRequest(peerInfo); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0UL, peerInfo.HeadNumber))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(peerInfo.HeadNumber)); // full sync does not set main chain, but triggers it processing which eventually set main chain Assert.That(ctx.BlockTree.IsMainChain(ctx.BlockTree.BestSuggestedHeader!.Hash!), Is.EqualTo(false)); @@ -358,8 +358,8 @@ public async Task Can_sync_with_peer_when_it_times_out(int ignoredBlocks, bool m PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); - await ctx.FullDispatcherSync(Math.Max(0UL, peerInfo.HeadNumber)); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(Math.Max(0UL, peerInfo.HeadNumber))); + await ctx.FullDispatcherSync(peerInfo.HeadNumber); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(peerInfo.HeadNumber)); } [TestCase(32UL, 32UL, 0, true)] diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs index fa4fa37abd9f..0564a9326793 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs @@ -133,7 +133,7 @@ private void OnNewBestPeer(PeerInfo newBestPeer) _ancestorLookupLevel = 0; ulong bestKnown = blockTree.BestKnownNumber; ulong headNum = newBestPeer.HeadNumber; - _currentNumber = Math.Max(0UL, Math.Min(bestKnown, headNum > 0 ? headNum - 1 : 0)); // Remember, _currentNumber is -1 than what we want. + _currentNumber = Math.Min(bestKnown, headNum > 0 ? headNum - 1 : 0); _currentBestPeer = newBestPeer; } diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs index 937bb5fe0294..b12c2835736b 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Logging; namespace Nethermind.Synchronization.FastSync @@ -16,8 +17,7 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa private BlockHeader? _bestHeader; private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - // BestSuggestedHeader.Number and _bestHeader.Number are ulong. Diff is long (can be negative during reorgs). - public ulong Diff => blockTree.BestSuggestedHeader?.Number ?? 0UL - (_bestHeader?.Number ?? 0UL); + public ulong Diff => (blockTree.BestSuggestedHeader?.Number ?? 0UL).SaturatingSub(_bestHeader?.Number ?? 0UL); public BlockHeader? GetPivotHeader() { @@ -42,9 +42,7 @@ public void UpdateHeaderForcefully() private void TrySetNewBestHeader(string msg) { BlockHeader bestSuggestedHeader = blockTree.BestSuggestedHeader; // Note: Best suggested header is always `syncConfig.StateMinDistanceFromHead`. behind from actual head. - // bestSuggestedHeader.Number is ulong; target is long for Math.Max and FindHeader. ulong targetBlockNumber = bestSuggestedHeader?.Number ?? 0UL; - targetBlockNumber = Math.Max(targetBlockNumber, 0); // The new pivot must be at least one block after the sync pivot as the forward downloader does not // download the block at the sync pivot which may cause state not found error if state was downloaded // at exactly sync pivot. diff --git a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs index 7f79ff892ecb..2baf88274c4f 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs @@ -86,10 +86,10 @@ private void SetupBlockFinderWithBlocks(ulong headBlockNumber, ulong gasUsed = 1 Block headBlock = Build.A.Block.WithNumber(headBlockNumber).WithGasUsed(gasUsed).TestObject; _blockFinder.Head.Returns(headBlock); - for (ulong i = headBlockNumber; i >= Math.Max(0UL, headBlockNumber - (ulong)_surgeConfig.L2GasUsageWindowSize + 1UL); i--) + ulong windowSize = _surgeConfig.L2GasUsageWindowSize; + ulong lowestBlock = headBlockNumber + 1 > windowSize ? headBlockNumber - windowSize + 1 : 0UL; + for (ulong i = lowestBlock; i <= headBlockNumber; i++) { - // Safe: i is bounded to [headBlockNumber - windowSize + 1, headBlockNumber], - // which is always a valid non-negative block range for the test inputs used. _blockFinder.FindBlock(i, BlockTreeLookupOptions.RequireCanonical) .Returns(Build.A.Block.WithNumber(i).WithGasUsed(gasUsed).TestObject); } @@ -318,11 +318,10 @@ public async ValueTask GetGasPriceEstimate_ComputesAverageGasFromRecentBlocks() // Scenario 1: Low gas usage blocks (average = 100k) const ulong headBlockNumber1 = 10; _blockFinder.Head.Returns(Build.A.Block.WithNumber(headBlockNumber1).WithGasUsed(100000).TestObject); - for (int i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) + for (ulong i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) { - // Safe: i < L2GasUsageWindowSize (5) and headBlockNumber1 = 10, so result >= 5; no underflow. - _blockFinder.FindBlock(headBlockNumber1 - (ulong)i, BlockTreeLookupOptions.RequireCanonical) - .Returns(Build.A.Block.WithNumber(headBlockNumber1 - (ulong)i).WithGasUsed(100000).TestObject); + _blockFinder.FindBlock(headBlockNumber1 - i, BlockTreeLookupOptions.RequireCanonical) + .Returns(Build.A.Block.WithNumber(headBlockNumber1 - i).WithGasUsed(100000).TestObject); } SurgeGasPriceOracle oracleLowGas = new( @@ -332,11 +331,10 @@ public async ValueTask GetGasPriceEstimate_ComputesAverageGasFromRecentBlocks() // Scenario 2: High gas usage blocks (average = 500k) const ulong headBlockNumber2 = 20; _blockFinder.Head.Returns(Build.A.Block.WithNumber(headBlockNumber2).WithGasUsed(500000).TestObject); - for (int i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) + for (ulong i = 0; i < _surgeConfig.L2GasUsageWindowSize; i++) { - // Safe: i < L2GasUsageWindowSize (5) and headBlockNumber2 = 20, so result >= 15; no underflow. - _blockFinder.FindBlock(headBlockNumber2 - (ulong)i, BlockTreeLookupOptions.RequireCanonical) - .Returns(Build.A.Block.WithNumber(headBlockNumber2 - (ulong)i).WithGasUsed(500000).TestObject); + _blockFinder.FindBlock(headBlockNumber2 - i, BlockTreeLookupOptions.RequireCanonical) + .Returns(Build.A.Block.WithNumber(headBlockNumber2 - i).WithGasUsed(500000).TestObject); } SurgeGasPriceOracle oracleHighGas = new( diff --git a/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs index a7e12805cf33..dfe798f6a6bc 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TxPoolContentListsTests.cs @@ -131,9 +131,9 @@ static object[] MakeTestData(Dictionary txs, int[] localAccounts, ul } } - [TestCase(10, 0)] - [TestCase(0, 1)] - public void MaxGasLimitRatio_FiltersHighGasLimitTransactions(int maxGasLimitRatio, int expectedTxCount) + [TestCase(10UL, 0)] + [TestCase(0UL, 1)] + public void MaxGasLimitRatio_FiltersHighGasLimitTransactions(ulong maxGasLimitRatio, int expectedTxCount) { Transaction tx = Build.A.Transaction .WithType(TxType.EIP1559) @@ -178,11 +178,11 @@ public void MaxGasLimitRatio_FiltersHighGasLimitTransactions(int maxGasLimitRati Assert.That(totalTxCount, Is.EqualTo(expectedTxCount)); } - [TestCase(21_000UL, 120, 0, 2, TestName = "Batch is full by bytes")] - [TestCase(2_100_000UL, 100_000, 10, 1, TestName = "Surge filter rejects transaction")] + [TestCase(21_000UL, 120, 0UL, 2, TestName = "Batch is full by bytes")] + [TestCase(2_100_000UL, 100_000, 10UL, 1, TestName = "Surge filter rejects transaction")] public void GasUsed_IsNotInflated_WhenTxIsRejectedAfterExecution( ulong tx1GasLimit, int maxBytesPerTxList, - int surgeMaxGasLimitRatio, int expectedBatchCount) + ulong surgeMaxGasLimitRatio, int expectedBatchCount) { // tx1 is rejected after successful execution, tx2 is accepted Transaction tx1 = Build.A.Transaction diff --git a/src/Nethermind/Nethermind.Taiko/Config/ISurgeConfig.cs b/src/Nethermind/Nethermind.Taiko/Config/ISurgeConfig.cs index 887de02ebd6b..8558176b6789 100644 --- a/src/Nethermind/Nethermind.Taiko/Config/ISurgeConfig.cs +++ b/src/Nethermind/Nethermind.Taiko/Config/ISurgeConfig.cs @@ -29,10 +29,10 @@ public interface ISurgeConfig : IConfig ulong FixedProvingGas { get; set; } [ConfigItem(Description = "Number of blocks to consider for computing the L1 average base fee.", DefaultValue = "200")] - int FeeHistoryBlockCount { get; set; } + ulong FeeHistoryBlockCount { get; set; } [ConfigItem(Description = "Number of recent L2 blocks to consider for computing the moving average of gas usage.", DefaultValue = "20")] - int L2GasUsageWindowSize { get; set; } + ulong L2GasUsageWindowSize { get; set; } [ConfigItem(Description = "Estimated offchain proving cost per batch in wei (~$5.5 @ $3000/ETH).", DefaultValue = "1833333333333333")] ulong EstimatedOffchainProvingCost { get; set; } @@ -53,7 +53,7 @@ public interface ISurgeConfig : IConfig int GasPriceRefreshTimeoutSeconds { get; set; } [ConfigItem(Description = "Filter transactions exceeding the max allowed ratio of gas limit to the actual gas used (e.g. 1, 2 etc.). Set to 0 to disable.", DefaultValue = "0")] - int MaxGasLimitRatio { get; set; } + ulong MaxGasLimitRatio { get; set; } [ConfigItem(Description = "Enable TDX attestation support.", DefaultValue = "false")] bool TdxEnabled { get; set; } diff --git a/src/Nethermind/Nethermind.Taiko/Config/SurgeConfig.cs b/src/Nethermind/Nethermind.Taiko/Config/SurgeConfig.cs index b59877f8ea66..ff6860de8842 100644 --- a/src/Nethermind/Nethermind.Taiko/Config/SurgeConfig.cs +++ b/src/Nethermind/Nethermind.Taiko/Config/SurgeConfig.cs @@ -12,15 +12,15 @@ public class SurgeConfig : ISurgeConfig public ulong FixedProposalGas { get; set; } = 75_000; public ulong FixedProposalGasWithFullInboxBuffer { get; set; } = 50_000; public ulong FixedProvingGas { get; set; } = 30_000; - public int FeeHistoryBlockCount { get; set; } = 200; - public int L2GasUsageWindowSize { get; set; } = 20; + public ulong FeeHistoryBlockCount { get; set; } = 200; + public ulong L2GasUsageWindowSize { get; set; } = 20; public ulong EstimatedOffchainProvingCost { get; set; } = 1_833_333_333_333_333; public string? TaikoInboxAddress { get; set; } public int AverageGasUsagePercentage { get; set; } = 80; public int SharingPercentage { get; set; } = 75; public int BoostBaseFeePercentage { get; set; } = 5; public int GasPriceRefreshTimeoutSeconds { get; set; } = 12; - public int MaxGasLimitRatio { get; set; } = 0; + public ulong MaxGasLimitRatio { get; set; } = 0; public bool TdxEnabled { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs b/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs index 44cdc140680d..c5c6b569e8da 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/SurgeGasPriceOracle.cs @@ -193,10 +193,10 @@ private ulong GetAverageGasUsagePerBlock() } ulong totalGasUsed = 0; - int count = 0; + ulong count = 0; ulong currentBlockNumber = headBlock.Number; - while (count < _surgeConfig.L2GasUsageWindowSize && currentBlockNumber >= 0) + while (count < _surgeConfig.L2GasUsageWindowSize) { Block? block = _blockFinder.FindBlock(currentBlockNumber, BlockTreeLookupOptions.RequireCanonical); if (block != null) @@ -204,10 +204,11 @@ private ulong GetAverageGasUsagePerBlock() totalGasUsed += block.GasUsed; count++; } + if (currentBlockNumber == 0) break; currentBlockNumber--; } - ulong average = totalGasUsed > 0 ? totalGasUsed / (ulong)count : _surgeConfig.L2BlockGasTarget; + ulong average = totalGasUsed > 0 ? totalGasUsed / count : _surgeConfig.L2BlockGasTarget; if (_logger.IsTrace) { diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs index e6b77ca9ef89..51e81b0f8619 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoEngineRpcModule.cs @@ -272,7 +272,7 @@ void Restore(Snapshot snapshot, ulong gasUsed) } // For Surge, filter out any transaction with very high gas limit - if (surgeConfig.MaxGasLimitRatio > 0 && tx.GasLimit > tx.SpentGas * (ulong)surgeConfig.MaxGasLimitRatio) + if (surgeConfig.MaxGasLimitRatio > 0 && tx.GasLimit > tx.SpentGas * surgeConfig.MaxGasLimitRatio) { Restore(snapshot, gasUsedBefore); while (i < txSource.Length && txSource[i].SenderAddress == tx.SenderAddress) i++; diff --git a/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs b/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs index aa3193382ab6..9c99a0a90dc9 100644 --- a/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs +++ b/src/Nethermind/Nethermind.Xdc/EpochSwitchManager.cs @@ -7,6 +7,7 @@ using Nethermind.Core; using Nethermind.Core.Caching; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; using Nethermind.Xdc.Types; @@ -276,7 +277,9 @@ private bool TryBinarySearchBlockByEpochNumber(ulong targetEpochNumber, ulong st ulong epoch = xdcSpec.EpochLength; ulong estBlockNumDiff = epoch * (epochNumber - targetEpoch); - ulong estBlockNum = Math.Max(xdcSpec.SwitchBlock, epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber - estBlockNumDiff); + ulong estBlockNum = Math.Max( + xdcSpec.SwitchBlock, + epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber.SaturatingSub(estBlockNumDiff)); ulong closeEpochNum = 2ul; diff --git a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs index 862c5b0b2dec..09a83b567066 100644 --- a/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs +++ b/src/Nethermind/Nethermind.Xdc/RPC/XdcRpcModule.cs @@ -181,9 +181,9 @@ public ResultWrapper GetMasternodesByNumber(BlockParameter bl return ResultWrapper.Fail("No finalized block found from consensus"); } } - else if (blockNumber.BlockNumber < 0) + else if (blockNumber.BlockNumber is null) { - return ResultWrapper.Fail($"Invalid block number {blockNumber.BlockNumber}"); + return ResultWrapper.Fail("Block number is required."); } else { @@ -244,9 +244,9 @@ public ResultWrapper GetMissedRoundsInEpochByBloc { header = tree.Head?.Header; } - else if (blockNumber.BlockNumber < 0) + else if (blockNumber.BlockNumber is null) { - return ResultWrapper.Fail($"Invalid block number {blockNumber.BlockNumber}"); + return ResultWrapper.Fail("Block number is required."); } else { @@ -370,9 +370,9 @@ public ResultWrapper GetSigners(BlockParameter blockParam) { header = tree.Head?.Header; } - else if (blockParam.BlockNumber < 0) + else if (blockParam.BlockNumber is null) { - return ResultWrapper.Fail($"Invalid block number {blockParam.BlockNumber}"); + return ResultWrapper.Fail("Block number is required."); } else { @@ -443,9 +443,9 @@ public ResultWrapper GetSnapshot(BlockParameter blockParam) { header = tree.Head?.Header; } - else if (blockParam.BlockNumber < 0) + else if (blockParam.BlockNumber is null) { - return ResultWrapper.Fail($"Invalid block number {blockParam.BlockNumber}"); + return ResultWrapper.Fail("Block number is required."); } else { @@ -611,9 +611,9 @@ public ResultWrapper GetV2BlockByNumber(BlockParameter blockNumber) { header = tree.Head?.Header; } - else if (blockNumber.BlockNumber < 0) + else if (blockNumber.BlockNumber is null) { - return ResultWrapper.Fail($"Invalid block number {blockNumber.BlockNumber}"); + return ResultWrapper.Fail("Block number is required."); } else { diff --git a/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs b/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs index c680bded2a49..cc6dc33ad421 100644 --- a/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs +++ b/src/Nethermind/Nethermind.Xdc/SubnetPenaltyHandler.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Xdc.Spec; @@ -30,7 +31,7 @@ public Address[] HandlePenalties(ulong number, Hash256 parentHash, Address[] can ulong parentNumber = number - 1; - ulong minBlockNumber = Math.Max(1UL, number - currentSpec.EpochLength); + ulong minBlockNumber = Math.Max(1UL, number.SaturatingSub(currentSpec.EpochLength)); while (true) { @@ -73,7 +74,9 @@ public Address[] HandlePenalties(ulong number, Hash256 parentHash, Address[] can HashSet blockHashes = []; - ulong startRange = Math.Max(number - currentSpec.RangeReturnSigner + 1, 0); + ulong startRange = number + 1 > currentSpec.RangeReturnSigner + ? number - currentSpec.RangeReturnSigner + 1 + : 1UL; for (int i = listBlockNumber.Count - 1; i >= 0; i--) { ulong blockNumber = listBlockNumber[i]; From ce4b80560d23c5c0aa18cde861e2a27ccd53ea80 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 11:02:17 +0200 Subject: [PATCH 19/60] refactor(geth-types): cast cleanup pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Type changes that eliminate casts at multiple sites: - HeadersSyncBatch.RequestSize: ulong → int (14 (int) casts dropped in callers; one (ulong) cast added in EndNumber). Sync request sizes are inherently small. - EraPathUtils.Filename (Era1 + EraE): long epoch → ulong epoch (4 cast sites) - IOpcodeTracingConfig.{StartBlock,EndBlock,RecentBlocks}: long? → ulong?, cascading through TraceConfiguration / FromConfig / BlockRangeValidator and the recorder's currentChainTip (~12 cast sites) - ProcessingStats: _chunkBlobs and BlockData.BlobCount long → ulong - MinBlockInCachePruneStrategyTests / MaxBlockInCachePruneStrategyTests: const long → const ulong for PruneBoundary and {Min,Max}BlockFromPersisted Per-site cleanups: - BlockHeaderTests: hex literals (0x2fefbaUL) instead of (ulong)Bytes.FromHexString(...).ToUnsignedBigInteger() - Int64Extensions.ToLongFromBigEndianByteArrayWithoutLeadingZeros: cast internally once so call sites drop their (long) cast - ProcessedTransactionsDbCleaner: switch to ToULongFromBigEndian... directly - SyncConfig / RocksDbConfigFactoryTests / SyncPeerProtocolHandlerBase: N.MB / N.MiB ulong-extension forms drop the outer (ulong) cast - BlockAccessListsSyncFeedTests: ToULongFromBigEndian... directly Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Synchronization/SyncConfig.cs | 2 +- .../Processing/ProcessingStats.cs | 10 ++--- .../Nethermind.Core.Test/BlockHeaderTests.cs | 20 +++++----- .../Nethermind.Core.Test/Int64Tests.cs | 20 +++++----- .../Extensions/Int64Extensions.cs | 26 +++---------- .../KeyValueStoreExtensions.cs | 4 +- .../RocksDbConfigFactoryTests.cs | 2 +- .../Nethermind.Era1.Test/EraPathUtilsTests.cs | 12 ++---- src/Nethermind/Nethermind.Era1/EraExporter.cs | 4 +- .../Nethermind.Era1/EraPathUtils.cs | 3 +- .../Export/EraPathUtilsTests.cs | 17 ++++----- .../Nethermind.EraE/Export/EraExporter.cs | 4 +- .../Nethermind.EraE/Export/EraPathUtils.cs | 3 +- .../Synchronization/BeaconHeadersSyncTests.cs | 12 +++--- .../ProcessedTransactionsDbCleaner.cs | 2 +- .../SyncPeerProtocolHandlerBase.cs | 4 +- .../IOpcodeTracingConfig.cs | 6 +-- .../OpcodeTracingConfig.cs | 6 +-- .../TraceConfiguration.cs | 38 +++++++++---------- .../Tracing/OpcodeTraceRecorder.cs | 16 ++++---- .../Utilities/BlockRangeValidator.cs | 35 +++-------------- .../BlockAccessListsSyncFeedTests.cs | 2 +- .../FastBlocks/FastHeadersSyncTests.cs | 18 ++++----- .../FastBlocks/HeadersSyncBatch.cs | 4 +- .../FastBlocks/HeadersSyncDownloader.cs | 2 +- .../FastBlocks/HeadersSyncFeed.cs | 28 +++++++------- .../MaxBlockInCachePruneStrategyTests.cs | 8 ++-- .../MinBlockInCachePruneStrategyTests.cs | 8 ++-- 28 files changed, 134 insertions(+), 182 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index d80bfe92759d..27fd98af6f17 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -90,7 +90,7 @@ public string? PivotHash /// public ulong HeaderStateDistance { get; set; } = 0; - public ulong FastHeadersMemoryBudget { get; set; } = (ulong)128.MB; + public ulong FastHeadersMemoryBudget { get; set; } = 128UL.MB; public bool EnableSnapSyncStorageRangeSplit { get; set; } = false; public bool EnableSnapDoubleWriteCheck { get; set; } = false; public long ForwardSyncDownloadBufferMemoryBudget { get; set; } = 200.MiB; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 265cee0f8d0f..d3610f5a22ef 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -103,7 +103,7 @@ public class ProcessingStats : IProcessingStats private double _chunkMGas; private long _chunkProcessingMicroseconds; private long _chunkTx; - private long _chunkBlobs; + private ulong _chunkBlobs; private long _chunkBlocks; private ulong _chunkFirstBlockNumber = ulong.MaxValue; private long _opCodes; @@ -216,7 +216,7 @@ public void UpdateStats(IReadOnlyList blocks, BlockHeader? baseBlock, lon Block lastBlock = blocks[^1]; ulong gasUsed = 0; long transactionCount = 0; - long blobCount = 0; + ulong blobCount = 0; for (int i = 0; i < blocks.Count; i++) { Block block = blocks[i]; @@ -225,7 +225,7 @@ public void UpdateStats(IReadOnlyList blocks, BlockHeader? baseBlock, lon transactionCount += transactions.Length; for (int j = 0; j < transactions.Length; j++) { - blobCount += (long)transactions[j].GetBlobCount(); + blobCount += transactions[j].GetBlobCount(); } } @@ -402,7 +402,7 @@ protected virtual void GenerateReport(BlockData data) } _chunkBlobs += data.BlobCount; - long blobs = _chunkBlobs; + ulong blobs = _chunkBlobs; if (blobs > 0) { _showBlobs = true; @@ -851,7 +851,7 @@ protected class BlockData public ulong FirstBlockNumber; public ulong GasUsed; public long TransactionCount; - public long BlobCount; + public ulong BlobCount; public long CurrentOpCodes; public long CurrentSLoadOps; public long CurrentSStoreOps; diff --git a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs index 635b45c61477..ab17317a7a97 100644 --- a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs @@ -27,15 +27,15 @@ public void Hash_as_expected() Beneficiary = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1"), Difficulty = Bytes.FromHexString("0x020000").ToUInt256(), ExtraData = [], - GasLimit = (ulong)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), - GasUsed = (ulong)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), + GasLimit = 0x2fefbaUL, + GasUsed = 0x5208UL, MixHash = new Hash256(Bytes.FromHexString("0x00be1f287e0911ea2f070b3650a1a0346535895b6c919d7e992a0c255a83fc8b")), - Nonce = (ulong)Bytes.FromHexString("0xa0ddc06c6d7b9f48").ToUnsignedBigInteger(), - Number = (ulong)Bytes.FromHexString("0x01").ToUInt256(), + Nonce = 0xa0ddc06c6d7b9f48UL, + Number = 0x01UL, ParentHash = new Hash256(Bytes.FromHexString("0x5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae")), ReceiptsRoot = new Hash256(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2")), StateRoot = new Hash256(Bytes.FromHexString("0x5c2e5a51a79da58791cdfe572bcfa3dfe9c860bf7fad7d9738a1aace56ef9332")), - Timestamp = (ulong)Bytes.FromHexString("0x59d79f18").ToUnsignedBigInteger(), + Timestamp = 0x59d79f18UL, TxRoot = new Hash256(Bytes.FromHexString("0x5c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516")), UnclesHash = new Hash256(Bytes.FromHexString("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) }; @@ -53,15 +53,15 @@ public void Hash_as_expected_2() Beneficiary = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1"), Difficulty = Bytes.FromHexString("0x020080").ToUInt256(), ExtraData = [], - GasLimit = (ulong)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger(), - GasUsed = (ulong)Bytes.FromHexString("0x5208").ToUnsignedBigInteger(), + GasLimit = 0x2fefbaUL, + GasUsed = 0x5208UL, MixHash = new Hash256(Bytes.FromHexString("0x615bbf44eb133eab3cb24d5766ae9617d9e45ee00e7a5667db30672b47d22149")), - Nonce = (ulong)Bytes.FromHexString("0x4c4f3d3e055cb264").ToUnsignedBigInteger(), - Number = (ulong)Bytes.FromHexString("0x03").ToUInt256(), + Nonce = 0x4c4f3d3e055cb264UL, + Number = 0x03UL, ParentHash = new Hash256(Bytes.FromHexString("0xde1457da701ef916533750d46c124e9ae50b974410bd590fbcf4c935a4d19465")), ReceiptsRoot = new Hash256(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2")), StateRoot = new Hash256(Bytes.FromHexString("0xfb4084a7f8b57e370fefe24a3da3aaea6c4dd8b6f6251916c32440336035160b")), - Timestamp = (ulong)Bytes.FromHexString("0x59d79f1c").ToUnsignedBigInteger(), + Timestamp = 0x59d79f1cUL, TxRoot = new Hash256(Bytes.FromHexString("0x1722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1a")), UnclesHash = new Hash256(Bytes.FromHexString("0xe676a42c388d2d24bb2927605d5d5d82fba50fb60d74d44b1cd7d1c4e4eee3c0")) }; diff --git a/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs b/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs index 27154316d194..7d04f84927b5 100644 --- a/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Int64Tests.cs @@ -14,8 +14,8 @@ public class Int64Tests public void ToLongFromBytes() { byte[] bytes = Bytes.FromHexString("7fffffffffffffff"); - ulong number = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); - Assert.That(number, Is.EqualTo((ulong)long.MaxValue)); + long number = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + Assert.That(number, Is.EqualTo(long.MaxValue)); } [TestCase("0000", 0L)] @@ -29,8 +29,8 @@ public void ToLongFromBytes() public void ToLongFromBytes_Vectors_match_for_array_and_span(string hexBytes, long expected) { byte[] bytes = Bytes.FromHexString(hexBytes); - long viaArray = (long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); - long viaSpan = (long)bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long viaArray = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long viaSpan = bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(); using (Assert.EnterMultipleScope()) { Assert.That(viaArray, Is.EqualTo(expected)); @@ -45,8 +45,8 @@ public void ToLongFromBytes_Exact_sequence_0102030405060708() long expected = unchecked((long)0x0102030405060708UL); using (Assert.EnterMultipleScope()) { - Assert.That((long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); - Assert.That((long)bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); + Assert.That(bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); + Assert.That(bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); } } @@ -57,8 +57,8 @@ public void ToLongFromBytes_Oversized_inputs_keep_last_8_bytes(string hexBytes, byte[] bytes = Bytes.FromHexString(hexBytes); using (Assert.EnterMultipleScope()) { - Assert.That((long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); - Assert.That((long)bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); + Assert.That(bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); + Assert.That(bytes.AsSpan().ToLongFromBigEndianByteArrayWithoutLeadingZeros(), Is.EqualTo(expected)); } } @@ -66,7 +66,7 @@ public void ToLongFromBytes_Oversized_inputs_keep_last_8_bytes(string hexBytes, public void ToLongFromBytes_Empty_span_is_zero() { ReadOnlySpan span = ReadOnlySpan.Empty; - long number = (long)span.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long number = span.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); Assert.That(number, Is.EqualTo(0L)); } @@ -74,7 +74,7 @@ public void ToLongFromBytes_Empty_span_is_zero() public void ToLongFromBytes_Null_array_is_zero() { byte[]? bytes = null; - long number = (long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long number = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); Assert.That(number, Is.EqualTo(0L)); } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs index 618c8686c20d..902864aa6d8d 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs @@ -88,26 +88,12 @@ public static string ToHexString(this in UInt256 value, bool skipLeadingZeros) return bytes.ToHexString(true, skipLeadingZeros, false); } - public static ulong ToLongFromBigEndianByteArrayWithoutLeadingZeros(this ReadOnlySpan bytes) - { - if (bytes.IsEmpty) - { - return 0UL; - } - - return UInt64Extensions.ToULongFromBigEndianByteArrayWithoutLeadingZeros(bytes); - } + public static long ToLongFromBigEndianByteArrayWithoutLeadingZeros(this ReadOnlySpan bytes) => + (long)UInt64Extensions.ToULongFromBigEndianByteArrayWithoutLeadingZeros(bytes); - public static ulong ToLongFromBigEndianByteArrayWithoutLeadingZeros(this Span bytes) - => ToLongFromBigEndianByteArrayWithoutLeadingZeros((ReadOnlySpan)bytes); + public static long ToLongFromBigEndianByteArrayWithoutLeadingZeros(this Span bytes) => + (long)UInt64Extensions.ToULongFromBigEndianByteArrayWithoutLeadingZeros(bytes); - public static ulong ToLongFromBigEndianByteArrayWithoutLeadingZeros(this byte[]? bytes) - { - if (bytes is null) - { - return 0UL; - } - - return ToLongFromBigEndianByteArrayWithoutLeadingZeros(bytes.AsSpan()); - } + public static long ToLongFromBigEndianByteArrayWithoutLeadingZeros(this byte[]? bytes) => + (long)UInt64Extensions.ToULongFromBigEndianByteArrayWithoutLeadingZeros(bytes); } diff --git a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs index f438facead01..eb0b69b8e5eb 100644 --- a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs +++ b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs @@ -77,7 +77,7 @@ public ulong GetULongFromBigEndianByteArrayWithoutLeadingZeros(ulong key) public long GetLongFromBigEndianByteArrayWithoutLeadingZeros(Hash256 key, long defaultValue) { Span bytes = db.GetSpan(key); - long value = bytes.IsNull() ? defaultValue : (long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long value = bytes.IsNull() ? defaultValue : bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); db.DangerousReleaseMemory(bytes); return value; } @@ -85,7 +85,7 @@ public long GetLongFromBigEndianByteArrayWithoutLeadingZeros(Hash256 key, long d public long GetLongFromBigEndianByteArrayWithoutLeadingZeros(long key) { Span bytes = db.GetSpan(key); - long value = (long)bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + long value = bytes.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); db.DangerousReleaseMemory(bytes); return value; } diff --git a/src/Nethermind/Nethermind.Db.Test/RocksDbConfigFactoryTests.cs b/src/Nethermind/Nethermind.Db.Test/RocksDbConfigFactoryTests.cs index 2e9e6070d274..7d11cc779ce0 100644 --- a/src/Nethermind/Nethermind.Db.Test/RocksDbConfigFactoryTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/RocksDbConfigFactoryTests.cs @@ -51,7 +51,7 @@ public void WillOverrideStateConfigWhenDirtyCachesTooHigh() pruningConfig.DirtyCacheMb = 10000; RocksDbConfigFactory factory = new(dbConfig, pruningConfig, new TestHardwareInfo(0), LimboLogs.Instance); IRocksDbConfig config = factory.GetForDatabase("State0", null); - Assert.That(config.WriteBufferSize, Is.EqualTo((ulong)500.MB)); + Assert.That(config.WriteBufferSize, Is.EqualTo(500UL.MB)); } [TestCase(1024, ExpectedResult = 819, TestName = "Caps to 80% on low limit")] diff --git a/src/Nethermind/Nethermind.Era1.Test/EraPathUtilsTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraPathUtilsTests.cs index 2fd23eea0b6f..b7021dbc4f32 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraPathUtilsTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraPathUtilsTests.cs @@ -7,10 +7,10 @@ namespace Nethermind.Era1.Test; public class EraPathUtilsTests { - [TestCase("test", 0, "0x0000000000000000000000000000000000000000000000000000000000000000", "test-00000-00000000.era1")] - [TestCase("goerli", 1, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "goerli-00001-ffffffff.era1")] - [TestCase("sepolia", 2, "0x1122ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sepolia-00002-1122ffff.era1")] - public void Filename_ValidParameters_ReturnsExpected(string network, int epoch, string hash, string expected) => Assert.That(EraPathUtils.Filename(network, epoch, new Hash256(hash)), Is.EqualTo(expected)); + [TestCase("test", 0UL, "0x0000000000000000000000000000000000000000000000000000000000000000", "test-00000-00000000.era1")] + [TestCase("goerli", 1UL, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "goerli-00001-ffffffff.era1")] + [TestCase("sepolia", 2UL, "0x1122ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "sepolia-00002-1122ffff.era1")] + public void Filename_ValidParameters_ReturnsExpected(string network, ulong epoch, string hash, string expected) => Assert.That(EraPathUtils.Filename(network, epoch, new Hash256(hash)), Is.EqualTo(expected)); [Test] public void Filename_NetworkIsNull_ReturnsException() => @@ -22,13 +22,9 @@ public void Filename_NetworkIsNull_ReturnsException() => [Test] public void Filename_NetworkIsEmpty_ReturnsException() => Assert.That(() => EraPathUtils.Filename("", 0, new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000")), Throws.ArgumentException); - [Test] - public void Filename_EpochIsNegative_ReturnsException() => Assert.That(() => EraPathUtils.Filename("test", -1, new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000")), Throws.TypeOf()); - [Test] public void Filename_RootIsNull_ReturnsException() => #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. Assert.That(() => EraPathUtils.Filename("test", 0, null), Throws.ArgumentNullException); #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } diff --git a/src/Nethermind/Nethermind.Era1/EraExporter.cs b/src/Nethermind/Nethermind.Era1/EraExporter.cs index 144caca49c37..0b1df9da3e8c 100644 --- a/src/Nethermind/Nethermind.Era1/EraExporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraExporter.cs @@ -109,7 +109,7 @@ async Task WriteEpoch(ulong epochIdx) string filePath = Path.Combine( destinationPath, // Cast to long is safe: epoch ordinals are small and well within long range. - EraPathUtils.Filename(_networkName, (long)epoch, Keccak.Zero)); + EraPathUtils.Filename(_networkName, epoch, Keccak.Zero)); ValueHash256 accumulator; ValueHash256 sha256; @@ -146,7 +146,7 @@ async Task WriteEpoch(ulong epochIdx) fileNames[(int)epochIdx] = Path.GetFileName(filePath); string rename = Path.Combine( destinationPath, - EraPathUtils.Filename(_networkName, (long)epoch, new Hash256(accumulator))); + EraPathUtils.Filename(_networkName, epoch, new Hash256(accumulator))); // Retry to handle transient file locks on Windows (e.g. antivirus scanning). for (int attempt = 0; ; attempt++) { diff --git a/src/Nethermind/Nethermind.Era1/EraPathUtils.cs b/src/Nethermind/Nethermind.Era1/EraPathUtils.cs index 8e6066ad33b7..5a5962cfdd02 100644 --- a/src/Nethermind/Nethermind.Era1/EraPathUtils.cs +++ b/src/Nethermind/Nethermind.Era1/EraPathUtils.cs @@ -40,11 +40,10 @@ public static IEnumerable GetAllEraFiles(string directoryPath, string ne public static IEnumerable GetAllEraFiles(string directoryPath, string network) => GetAllEraFiles(directoryPath, network, new RealFileSystem()); - public static string Filename(string network, long epoch, Hash256 root) + public static string Filename(string network, ulong epoch, Hash256 root) { ArgumentNullException.ThrowIfNullOrEmpty(network); ArgumentNullException.ThrowIfNull(root); - ArgumentOutOfRangeException.ThrowIfLessThan(epoch, 0); return $"{network}-{epoch:D5}-{root.ToString(true)[2..10]}.era1"; } diff --git a/src/Nethermind/Nethermind.EraE.Test/Export/EraPathUtilsTests.cs b/src/Nethermind/Nethermind.EraE.Test/Export/EraPathUtilsTests.cs index d0d57e7fc165..00a623456897 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Export/EraPathUtilsTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Export/EraPathUtilsTests.cs @@ -14,14 +14,14 @@ public class EraPathUtilsTests private const string SampleChecksumHash = "aabbccdd00000000000000000000000000000000000000000000000000000000"; private static readonly Hash256 ZeroHash = new(ZeroHashHex); - [TestCase("test", 0, "0x0000000000000000000000000000000000000000000000000000000000000000", "test-00000-00000000-noproofs.ere", TestName = "Genesis")] - [TestCase("goerli", 1, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "goerli-00001-ffffffff-noproofs.ere", TestName = "MaxHash")] - [TestCase("mainnet", 2, "0x1122ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "mainnet-00002-1122ffff-noproofs.ere", TestName = "Mainnet")] - public void Filename_WithValidParameters_ReturnsExpected(string network, int epoch, string hash, string expected) => + [TestCase("test", 0UL, "0x0000000000000000000000000000000000000000000000000000000000000000", "test-00000-00000000-noproofs.ere", TestName = "Genesis")] + [TestCase("goerli", 1UL, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "goerli-00001-ffffffff-noproofs.ere", TestName = "MaxHash")] + [TestCase("mainnet", 2UL, "0x1122ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "mainnet-00002-1122ffff-noproofs.ere", TestName = "Mainnet")] + public void Filename_WithValidParameters_ReturnsExpected(string network, ulong epoch, string hash, string expected) => Assert.That(EraPathUtils.Filename(network, epoch, new Hash256(hash)), Is.EqualTo(expected)); [TestCaseSource(nameof(InvalidFilenameArguments))] - public void Filename_WithInvalidArguments_Throws(string? network, long epoch, Hash256? lastBlockHash, Type expected) => + public void Filename_WithInvalidArguments_Throws(string? network, ulong epoch, Hash256? lastBlockHash, Type expected) => Assert.That(() => EraPathUtils.Filename(network!, epoch, lastBlockHash!), Throws.TypeOf(expected)); [TestCase("mainnet-00000-aabbccdd-noproofs.ere", ExpectedResult = true, TestName = "EreWithProfile")] @@ -78,9 +78,8 @@ public void ExtractHashFromChecksumEntry_ReturnsCorrectHash(string input) => private static IEnumerable InvalidFilenameArguments() { - yield return new TestCaseData(null, 0L, ZeroHash, typeof(ArgumentNullException)) { TestName = "NullNetwork" }; - yield return new TestCaseData("", 0L, ZeroHash, typeof(ArgumentException)) { TestName = "EmptyNetwork" }; - yield return new TestCaseData("test", -1L, ZeroHash, typeof(ArgumentOutOfRangeException)) { TestName = "NegativeEpoch" }; - yield return new TestCaseData("test", 0L, null, typeof(ArgumentNullException)) { TestName = "NullHash" }; + yield return new TestCaseData(null, 0UL, ZeroHash, typeof(ArgumentNullException)) { TestName = "NullNetwork" }; + yield return new TestCaseData("", 0UL, ZeroHash, typeof(ArgumentException)) { TestName = "EmptyNetwork" }; + yield return new TestCaseData("test", 0UL, null, typeof(ArgumentNullException)) { TestName = "NullHash" }; } } diff --git a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs index 636c9a8d7425..d649130d76b6 100644 --- a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs +++ b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs @@ -122,7 +122,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) if (TrySkipExistingEpoch(destinationPath, epoch, idx, writeFrom, writeTo, accumulators, checksums, fileNames, cachedChecksums, cachedAccumulators, ref totalProcessed)) return; - string placeholderPath = Path.Combine(destinationPath, EraPathUtils.Filename(_networkName, (long)epoch, Keccak.Zero)); + string placeholderPath = Path.Combine(destinationPath, EraPathUtils.Filename(_networkName, epoch, Keccak.Zero)); ValueHash256 accumulator; ValueHash256 sha256; @@ -168,7 +168,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) accumulators[idx] = accumulator; checksums[idx] = sha256; // Filename uses the last block hash as the epoch identifier — same convention as go-ethereum execdb. - string finalName = EraPathUtils.Filename(_networkName, (long)epoch, lastBlockHash); + string finalName = EraPathUtils.Filename(_networkName, epoch, lastBlockHash); fileNames[idx] = finalName; string finalPath = Path.Combine(destinationPath, finalName); diff --git a/src/Nethermind/Nethermind.EraE/Export/EraPathUtils.cs b/src/Nethermind/Nethermind.EraE/Export/EraPathUtils.cs index 7b79406a3716..7584d39106fe 100644 --- a/src/Nethermind/Nethermind.EraE/Export/EraPathUtils.cs +++ b/src/Nethermind/Nethermind.EraE/Export/EraPathUtils.cs @@ -55,11 +55,10 @@ public static IEnumerable GetAllEraFiles(string directoryPath, string ne public static IEnumerable GetAllEraFiles(string directoryPath, string network) => GetAllEraFiles(directoryPath, network, new RealFileSystem()); - public static string Filename(string network, long epoch, Hash256 lastBlockHash) + public static string Filename(string network, ulong epoch, Hash256 lastBlockHash) { ArgumentException.ThrowIfNullOrEmpty(network); ArgumentNullException.ThrowIfNull(lastBlockHash); - ArgumentOutOfRangeException.ThrowIfLessThan(epoch, 0); return $"{network}-{epoch:D5}-{lastBlockHash.ToString(true)[2..10]}-{NoProofsProfile}{FileExtension}"; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs index a4c48e2807cc..bd771e870b19 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/BeaconHeadersSyncTests.cs @@ -294,7 +294,7 @@ public void Feed_connect_invalid_chain() syncedBlockTree.FindHeader(99, BlockTreeLookupOptions.None)); ctx.Feed.InitializeFeed(); using HeadersSyncBatch batch = ctx.Feed.PrepareRequest().Result!; - batch.Response = syncedBlockTree.FindHeaders(syncedBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, false)!; + batch.Response = syncedBlockTree.FindHeaders(syncedBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; ctx.Feed.HandleResponse(batch); Hash256 lastHeader = syncedBlockTree.FindHeader(batch.EndNumber, BlockTreeLookupOptions.None)!.GetOrCalculateHash(); @@ -373,9 +373,9 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n // First batch, should be enough to merge chain HeadersSyncBatch? request = await ctx.Feed.PrepareRequest(); Assert.That(request!, Is.Not.Null); - request!.Response = ULongRange(request.StartNumber, (int)request.RequestSize) + request!.Response = ULongRange(request.StartNumber, request.RequestSize) .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) - .ToPooledList((int)request.RequestSize); + .ToPooledList(request.RequestSize); ctx.Feed.HandleResponse(request); @@ -389,9 +389,9 @@ public async Task When_pivot_changed_during_header_sync_after_chain_merged__do_n Assert.That(request, Is.Not.Null); // We respond it again - request!.Response = ULongRange(request.StartNumber, (int)request.RequestSize) + request!.Response = ULongRange(request.StartNumber, request.RequestSize) .Select(blockNumber => ctx.RemoteBlockTree.FindHeader(blockNumber)) - .ToPooledList((int)request.RequestSize); + .ToPooledList(request.RequestSize); ctx.Feed.HandleResponse(request); request.Dispose(); @@ -476,7 +476,7 @@ private static void BuildHeadersSyncBatchResponse(HeadersSyncBatch? batch, IBloc return; } - using IOwnedReadOnlyList headers = blockTree.FindHeaders(startHeader.Hash!, (int)batch.RequestSize, 0, false); + using IOwnedReadOnlyList headers = blockTree.FindHeaders(startHeader.Hash!, batch.RequestSize, 0, false); batch.Response = new ArrayPoolList(headers.Count, headers); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs b/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs index acd5d6088bc9..12446f41abbc 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/ProcessedTransactionsDbCleaner.cs @@ -44,7 +44,7 @@ private void CleanProcessedTransactionsDb(ulong newlyFinalizedBlockNumber) { foreach (byte[] key in _processedTxsDb.GetAllKeys()) { - ulong blockNumber = key.ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + ulong blockNumber = key.ToULongFromBigEndianByteArrayWithoutLeadingZeros(); if (newlyFinalizedBlockNumber >= blockNumber) { if (_logger.IsTrace) _logger.Trace($"Cleaning processed blob txs from block {blockNumber}"); diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs index 5c751f68d6e6..1d78bd26a587 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs @@ -29,8 +29,8 @@ namespace Nethermind.Network.P2P.ProtocolHandlers { public abstract class SyncPeerProtocolHandlerBase : ZeroProtocolHandlerBase, ISyncPeer { - internal static ulong SoftOutgoingMessageSizeLimit = (ulong)2.MiB; - internal static ulong HardOutgoingReceiptsMessageSizeLimit = (ulong)10.MiB; + internal static ulong SoftOutgoingMessageSizeLimit = 2UL.MiB; + internal static ulong HardOutgoingReceiptsMessageSizeLimit = 10UL.MiB; public Node Node => Session?.Node; public string ClientId => Node?.ClientId; public virtual UInt256? TotalDifficulty { get; set; } = UInt256.Zero; // for compatibility with old code, which relies on 0 being the default value diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/IOpcodeTracingConfig.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/IOpcodeTracingConfig.cs index e579e4274a8d..44c69fb72401 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/IOpcodeTracingConfig.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/IOpcodeTracingConfig.cs @@ -33,20 +33,20 @@ public interface IOpcodeTracingConfig : IConfig /// Gets or sets the start block number for tracing (inclusive). Used with EndBlock to define an explicit range. /// [ConfigItem(Description = "Start block number for tracing (inclusive). Used with EndBlock to define explicit range.", DefaultValue = "null")] - long? StartBlock { get; set; } + ulong? StartBlock { get; set; } /// /// Gets or sets the end block number for tracing (inclusive). Used with StartBlock to define an explicit range. /// [ConfigItem(Description = "End block number for tracing (inclusive). Used with StartBlock to define explicit range.", DefaultValue = "null")] - long? EndBlock { get; set; } + ulong? EndBlock { get; set; } /// /// Gets or sets the number of recent blocks to trace from the chain tip. /// Alternative to StartBlock/EndBlock for convenience. If both are specified, explicit range takes precedence. /// [ConfigItem(Description = "Number of recent blocks to trace from chain tip. Alternative to StartBlock/EndBlock.", DefaultValue = "null")] - long? RecentBlocks { get; set; } + ulong? RecentBlocks { get; set; } /// /// Gets or sets the tracing mode: "RealTime" traces blocks as they are processed during sync/new blocks, diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs index 0b91a5e8af80..b9ded59b70e5 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs @@ -11,8 +11,8 @@ public class OpcodeTracingConfig : IOpcodeTracingConfig public bool Enabled { get; set; } public string OutputDirectory { get; set; } = "traces/opcodes"; public int MaxDegreeOfParallelism { get; set; } = 0; - public long? StartBlock { get; set; } - public long? EndBlock { get; set; } - public long? RecentBlocks { get; set; } + public ulong?StartBlock { get; set; } + public ulong?EndBlock { get; set; } + public ulong?RecentBlocks { get; set; } public string Mode { get; set; } = "RealTime"; } diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs index bfbaad2d9fcc..0d7c436006de 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs @@ -21,9 +21,9 @@ public sealed record TraceConfiguration public TraceConfiguration( bool enabled, string outputDirectory, - long? startBlock, - long? endBlock, - long? recentBlocks, + ulong? startBlock, + ulong? endBlock, + ulong? recentBlocks, TracingMode mode, int maxDegreeOfParallelism) { @@ -49,17 +49,17 @@ public TraceConfiguration( /// /// Gets the start block number (nullable). /// - public long? StartBlock { get; } + public ulong? StartBlock { get; } /// /// Gets the end block number (nullable). /// - public long? EndBlock { get; } + public ulong? EndBlock { get; } /// /// Gets the number of recent blocks to trace (nullable). /// - public long? RecentBlocks { get; } + public ulong? RecentBlocks { get; } /// /// Gets the tracing mode. @@ -93,7 +93,7 @@ public TraceConfiguration( /// The current chain tip block number. /// A validated trace configuration. /// Thrown when configuration is invalid. - public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long currentChainTip) + public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, ulong currentChainTip) { ArgumentNullException.ThrowIfNull(config); @@ -119,14 +119,14 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu if (config.StartBlock.HasValue && config.EndBlock.HasValue && config.RecentBlocks.HasValue) { warnings.Add("Both explicit range (StartBlock/EndBlock) and RecentBlocks specified. Using explicit range, ignoring RecentBlocks."); - effectiveStart = (ulong)config.StartBlock.Value; - effectiveEnd = (ulong)config.EndBlock.Value; + effectiveStart = config.StartBlock.Value; + effectiveEnd = config.EndBlock.Value; } else if (config.StartBlock.HasValue && config.EndBlock.HasValue) { // Explicit range - effectiveStart = (ulong)config.StartBlock.Value; - effectiveEnd = (ulong)config.EndBlock.Value; + effectiveStart = config.StartBlock.Value; + effectiveEnd = config.EndBlock.Value; } else if (config.RecentBlocks.HasValue) { @@ -135,18 +135,18 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu if (mode == TracingMode.RealTime) { // RealTime: next N blocks starting from current chain tip + 1 - effectiveStart = (ulong)currentChainTip + 1; - effectiveEnd = (ulong)currentChainTip + (ulong)config.RecentBlocks.Value; + effectiveStart = currentChainTip + 1; + effectiveEnd = currentChainTip + config.RecentBlocks.Value; } else { // Retrospective and RetrospectiveExecution: recent N blocks from chain tip - effectiveEnd = (ulong)currentChainTip; + effectiveEnd = currentChainTip; effectiveStart = currentChainTip >= config.RecentBlocks.Value - 1 - ? (ulong)(currentChainTip - config.RecentBlocks.Value + 1) + ? currentChainTip - config.RecentBlocks.Value + 1 : 0; - if (effectiveStart == 0 && config.RecentBlocks.Value > currentChainTip + 1L) + if (effectiveStart == 0 && config.RecentBlocks.Value > currentChainTip + 1) { warnings.Add($"Requested {config.RecentBlocks.Value} blocks but only {currentChainTip + 1} available. Tracing all available blocks."); } @@ -155,15 +155,15 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, long cu else if (config.StartBlock.HasValue) { // Start block only, use current chain tip as end - effectiveStart = (ulong)config.StartBlock.Value; - effectiveEnd = (ulong)currentChainTip; + effectiveStart = config.StartBlock.Value; + effectiveEnd = currentChainTip; warnings.Add($"Only StartBlock specified, using current chain tip ({currentChainTip}) as EndBlock."); } else if (config.EndBlock.HasValue) { // End block only, use 0 as start effectiveStart = 0; - effectiveEnd = (ulong)config.EndBlock.Value; + effectiveEnd = config.EndBlock.Value; warnings.Add("Only EndBlock specified, using 0 as StartBlock."); } else diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs index 50f3af6b5e84..3d7b096d4e2c 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs @@ -59,7 +59,7 @@ public Task PrepareAsync(INethermindApi api, CancellationToken cancellationToken try { // Get current chain tip - long currentChainTip = (long)(api.BlockTree?.Head?.Number ?? 0UL); + ulong currentChainTip = api.BlockTree?.Head?.Number ?? 0UL; // Parse mode for validation TracingMode mode = TracingMode.RealTime; @@ -172,21 +172,21 @@ public void Attach(INethermindApi api) // For RealTime mode with Blocks parameter, recalculate range based on current chain tip // This ensures we trace the NEXT N blocks from when the tracer attaches, not from init time - long effectiveStart = (long)_traceConfig.EffectiveStartBlock; - long effectiveEnd = (long)_traceConfig.EffectiveEndBlock; + ulong effectiveStart = _traceConfig.EffectiveStartBlock; + ulong effectiveEnd = _traceConfig.EffectiveEndBlock; if (_config.RecentBlocks.HasValue && !_config.StartBlock.HasValue && !_config.EndBlock.HasValue) { - long currentTip = (long)(api.BlockTree?.Head?.Number ?? 0UL); + ulong currentTip = api.BlockTree?.Head?.Number ?? 0UL; effectiveStart = currentTip + 1; effectiveEnd = currentTip + _config.RecentBlocks.Value; // Update progress tracker and trace config with new range - _progress = new TracingProgress((ulong)effectiveStart, (ulong)effectiveEnd); + _progress = new TracingProgress(effectiveStart, effectiveEnd); _traceConfig = _traceConfig with { - EffectiveStartBlock = (ulong)effectiveStart, - EffectiveEndBlock = (ulong)effectiveEnd + EffectiveStartBlock = effectiveStart, + EffectiveEndBlock = effectiveEnd }; if (_logger.IsInfo) @@ -195,7 +195,7 @@ public void Attach(INethermindApi api) } } - BlockRange range = new((ulong)effectiveStart, (ulong)effectiveEnd); + BlockRange range = new(effectiveStart, effectiveEnd); _realTimeTracer = new RealTimeTracer( _counter, range, diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRangeValidator.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRangeValidator.cs index f56b36074490..41ab7902b963 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRangeValidator.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Utilities/BlockRangeValidator.cs @@ -15,7 +15,7 @@ public static class BlockRangeValidator /// The current chain tip block number. /// The tracing mode being used. /// A validation result indicating success, warnings, or errors. - public static ValidationResult Validate(IOpcodeTracingConfig config, long currentChainTip, TracingMode mode = TracingMode.RealTime) + public static ValidationResult Validate(IOpcodeTracingConfig config, ulong currentChainTip, TracingMode mode = TracingMode.RealTime) { if (config is null) { @@ -29,38 +29,13 @@ public static ValidationResult Validate(IOpcodeTracingConfig config, long curren } // Explicit range validation - if (config.StartBlock.HasValue && config.EndBlock.HasValue) + if (config.StartBlock.HasValue && config.EndBlock.HasValue + && config.StartBlock.Value > config.EndBlock.Value) { - if (config.StartBlock.Value > config.EndBlock.Value) - { - return ValidationResult.Error($"Invalid range: StartBlock ({config.StartBlock}) > EndBlock ({config.EndBlock})"); - } - - if (config.StartBlock.Value < 0) - { - return ValidationResult.Error("StartBlock must be non-negative"); - } - - if (config.EndBlock.Value < 0) - { - return ValidationResult.Error("EndBlock must be non-negative"); - } + return ValidationResult.Error($"Invalid range: StartBlock ({config.StartBlock}) > EndBlock ({config.EndBlock})"); } - // Validate StartBlock non-negative when only StartBlock is specified - if (config.StartBlock.HasValue && !config.EndBlock.HasValue && config.StartBlock.Value < 0) - { - return ValidationResult.Error("StartBlock must be non-negative"); - } - - // Validate EndBlock non-negative when only EndBlock is specified - if (config.EndBlock.HasValue && !config.StartBlock.HasValue && config.EndBlock.Value < 0) - { - return ValidationResult.Error("EndBlock must be non-negative"); - } - - // Validate RecentBlocks parameter - if (config.RecentBlocks.HasValue && config.RecentBlocks.Value <= 0) + if (config.RecentBlocks is 0) { return ValidationResult.Error("RecentBlocks parameter must be positive"); } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs index 53c20414b780..4d513a6c175a 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BlockAccessListsSyncFeedTests.cs @@ -122,7 +122,7 @@ public async Task Treats_pivot_without_block_access_list_hash_as_temporarily_fin _feed.InitializeFeed(); - ulong barrier = _metadataDb.Get(MetadataDbKeys.BlockAccessListsBarrierWhenStarted).ToLongFromBigEndianByteArrayWithoutLeadingZeros(); + ulong barrier = _metadataDb.Get(MetadataDbKeys.BlockAccessListsBarrierWhenStarted).ToULongFromBigEndianByteArrayWithoutLeadingZeros(); Assert.That(barrier, Is.EqualTo(previousBarrier)); _blockAccessListStore.DidNotReceive().Exists(Arg.Any(), TestItem.KeccakB); Assert.That(_feed.IsFinished, Is.True); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs index 2e15d0e64bc7..1ff63a11e435 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/FastHeadersSyncTests.cs @@ -155,7 +155,7 @@ public async Task Can_handle_forks_with_persisted_headers() HeadersSyncBatch? batch = await feed.PrepareRequest(); if (batch is null) break; batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash!, (int)batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash!, batch.RequestSize, 0, false)!; feed.HandleResponse(batch); } @@ -196,7 +196,7 @@ public async Task When_next_header_hash_update_is_delayed_do_not_drop_peer() void FulfillBatch(HeadersSyncBatch batch) { batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; batch.ResponseSourcePeer = peerInfo; } @@ -251,7 +251,7 @@ public async Task Can_prepare_several_request_and_ignore_request_from_previous_s void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; using HeadersSyncBatch? r = await feed.PrepareRequest(); @@ -298,7 +298,7 @@ public async Task Will_dispatch_when_only_partially_processed_dependency() void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; // First batch need to be handled first before handle dependencies can do anything @@ -369,7 +369,7 @@ public async Task Can_reset_and_not_hang_when_a_batch_is_processing() void FulfillBatch(HeadersSyncBatch batch) => batch.Response = remoteBlockTree.FindHeaders( - remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, (int)batch.RequestSize, 0, + remoteBlockTree.FindHeader(batch.StartNumber, BlockTreeLookupOptions.None)!.Hash, batch.RequestSize, 0, false)!; using HeadersSyncBatch batch1 = (await feed.PrepareRequest())!; @@ -578,9 +578,9 @@ public async Task Can_insert_all_good_headers_from_dependent_batch_with_missing_ void FillBatch(HeadersSyncBatch batch, ulong start, bool applyNulls) { int c = count; - List list = new((int)batch.RequestSize); + List list = new(batch.RequestSize); ulong current = start; - for (int j = 0; j < (int)batch.RequestSize; j++, current++) + for (int j = 0; j < batch.RequestSize; j++, current++) { list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); } @@ -639,9 +639,9 @@ public async Task Does_not_download_persisted_header() void FillBatch(HeadersSyncBatch batch) { - List list = new((int)batch.RequestSize); + List list = new(batch.RequestSize); ulong current = batch.StartNumber; - for (int j = 0; j < (int)batch.RequestSize; j++, current++) + for (int j = 0; j < batch.RequestSize; j++, current++) { list.Add(peerChain.FindBlock(current, BlockTreeLookupOptions.None)!.Header); } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs index a5ef7e9cdca0..117ddfa95cdd 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncBatch.cs @@ -9,8 +9,8 @@ namespace Nethermind.Synchronization.FastBlocks public class HeadersSyncBatch : FastBlocksBatch { public ulong StartNumber { get; set; } - public ulong EndNumber => StartNumber + RequestSize - 1; - public ulong RequestSize { get; set; } + public ulong EndNumber => StartNumber + (ulong)RequestSize - 1; + public int RequestSize { get; set; } public long ResponseSizeEstimate { get; private set; } private IOwnedReadOnlyList? _response; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs index 9f3232f87d59..137e3e76aece 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncDownloader.cs @@ -26,7 +26,7 @@ async Task ISyncDownloader.Dispatch( try { - batch.Response = await peer.GetBlockHeaders(batch.StartNumber, (int)batch.RequestSize, 0, cancellationToken); + batch.Response = await peer.GetBlockHeaders(batch.StartNumber, batch.RequestSize, 0, cancellationToken); } catch (TimeoutException) { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs index 9158370e020f..083022cbe6c4 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs @@ -426,7 +426,7 @@ private bool HasDependencyToProcess HeadersSyncBatch batch = new(); ulong requestSizeU = (ulong)requestSize; batch.StartNumber = Math.Max(HeadersDestinationNumber, _lowestRequestedHeaderNumber >= requestSizeU ? _lowestRequestedHeaderNumber - requestSizeU : 0UL); - batch.RequestSize = Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, requestSizeU); + batch.RequestSize = (int)Math.Min(_lowestRequestedHeaderNumber - HeadersDestinationNumber, requestSizeU); _lowestRequestedHeaderNumber = batch.StartNumber; return batch; } @@ -526,7 +526,7 @@ private static HeadersSyncBatch BuildRightFiller(HeadersSyncBatch batch, int rig rightFiller.StartNumber = batch.EndNumber >= (ulong)(rightFillerSize - 1) ? batch.EndNumber - (ulong)(rightFillerSize - 1) : 0UL; - rightFiller.RequestSize = (ulong)rightFillerSize; + rightFiller.RequestSize = rightFillerSize; return rightFiller; } @@ -534,7 +534,7 @@ private static HeadersSyncBatch BuildLeftFiller(HeadersSyncBatch batch, int left { HeadersSyncBatch leftFiller = new(); leftFiller.StartNumber = batch.StartNumber; - leftFiller.RequestSize = (ulong)leftFillerSize; + leftFiller.RequestSize = leftFillerSize; return leftFiller; } @@ -542,10 +542,10 @@ private static HeadersSyncBatch BuildDependentBatch(HeadersSyncBatch batch, ulon { HeadersSyncBatch dependentBatch = new(); dependentBatch.StartNumber = addedEarliest; - ulong count = addedLast - addedEarliest + 1; + int count = (int)(addedLast - addedEarliest + 1); ReadOnlySpan response = batch.Response!.AsSpan(); dependentBatch.RequestSize = count; - dependentBatch.Response = response.Slice((int)(addedEarliest - batch.StartNumber), (int)count).ToPooledList(); + dependentBatch.Response = response.Slice((int)(addedEarliest - batch.StartNumber), count).ToPooledList(); dependentBatch.ResponseSourcePeer = batch.ResponseSourcePeer; return dependentBatch; } @@ -574,22 +574,21 @@ private void EnqueueBatch(HeadersSyncBatch batch, bool skipPersisted = false) if (seedHash is null) return batch; using IOwnedReadOnlyList headers = - _headerStore.FindReversedHeaders(batch.EndNumber, seedHash, (int)batch.RequestSize); + _headerStore.FindReversedHeaders(batch.EndNumber, seedHash, batch.RequestSize); if (headers.Count == 0) return batch; - ulong newRequestSize = batch.RequestSize - (ulong)headers.Count; + int newRequestSize = batch.RequestSize - headers.Count; ReadOnlySpan headersSpan = headers.AsSpan(); using HeadersSyncBatch newBatchToProcess = new(); - // headersSpan[0].Number and StartNumber are both ulong — no cast needed. newBatchToProcess.StartNumber = headersSpan[0].Number; - newBatchToProcess.RequestSize = (ulong)headersSpan.Length; + newBatchToProcess.RequestSize = headersSpan.Length; newBatchToProcess.Response = headers; if (_logger.IsDebug) _logger.Debug($"Handling header portion {newBatchToProcess.StartNumber} to {newBatchToProcess.EndNumber} with persisted headers."); InsertHeaders(newBatchToProcess); MarkDirty(); HeadersSyncProgressLoggerReport.CurrentQueued = HeadersInQueue; - HeadersSyncProgressLoggerReport.IncrementSkipped((int)newBatchToProcess.RequestSize); + HeadersSyncProgressLoggerReport.IncrementSkipped(newBatchToProcess.RequestSize); if (newRequestSize == 0) return null; @@ -605,7 +604,7 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) } ReadOnlySpan response = batch.Response.AsSpan(); - if ((ulong)response.Length > batch.RequestSize) + if (response.Length > batch.RequestSize) { if (_logger.IsDebug) _logger.Debug($"Peer sent too long response ({response.Length}) to {batch}"); @@ -707,15 +706,14 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) else { added = 0; - leftFillerSize = (int)batch.RequestSize; + leftFillerSize = batch.RequestSize; rightFillerSize = 0; } - if ((ulong)(added + leftFillerSize + rightFillerSize) != batch.RequestSize) + if (added + leftFillerSize + rightFillerSize != batch.RequestSize) { throw new Exception($"Added {added} + left {leftFillerSize} + right {rightFillerSize} != request size {batch.RequestSize} in {batch}"); } - // lowestInsertedHeader.Number and LowestInsertedBlockHeader.Number are ulong. Use ulong max sentinel. if (lowestInsertedHeader is not null && lowestInsertedHeader.Number < (LowestInsertedBlockHeader?.Number ?? ulong.MaxValue)) { LowestInsertedBlockHeader = lowestInsertedHeader; @@ -724,7 +722,7 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) added = Math.Max(0, added); - if ((ulong)added < batch.RequestSize) + if (added < batch.RequestSize) { if (added <= 0) { diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs index f08283b307cb..79312bcb8702 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/MaxBlockInCachePruneStrategyTests.cs @@ -13,8 +13,8 @@ public class MaxBlockInCachePruneStrategyTests { private IPruningStrategy _baseStrategy; private MaxBlockInCachePruneStrategy _strategy; - private const long MaxBlockFromPersisted = 10; - private const long PruneBoundary = 32; + private const ulong MaxBlockFromPersisted = 10; + private const ulong PruneBoundary = 32; [SetUp] public void Setup() @@ -27,7 +27,7 @@ public void Setup() public void ShouldPruneDirtyNode_should_return_true_when_block_difference_exceeds_max_block_from_persisted() { ulong latestCommittedBlock = 100; - ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MaxBlockFromPersisted; + ulong lastPersistedBlock = latestCommittedBlock - PruneBoundary - MaxBlockFromPersisted; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(false); @@ -38,7 +38,7 @@ public void ShouldPruneDirtyNode_should_return_true_when_block_difference_exceed public void ShouldPruneDirtyNode_should_delegate_to_base_strategy_when_block_difference_is_less_than_max_block_from_persisted() { ulong latestCommittedBlock = 100; - ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MaxBlockFromPersisted + 1; + ulong lastPersistedBlock = latestCommittedBlock - PruneBoundary - MaxBlockFromPersisted + 1; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs index e2741b6f3cde..bb32de794d6b 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/MinBlockInCachePruneStrategyTests.cs @@ -14,8 +14,8 @@ public class MinBlockInCachePruneStrategyTests { private IPruningStrategy _baseStrategy; private MinBlockInCachePruneStrategy _strategy; - private const long MinBlockFromPersisted = 5; - private const long PruneBoundary = 32; + private const ulong MinBlockFromPersisted = 5; + private const ulong PruneBoundary = 32; [SetUp] public void Setup() @@ -28,7 +28,7 @@ public void Setup() public void ShouldPruneDirtyNode_should_return_false_when_block_difference_is_less_than_min_block_from_persisted() { ulong latestCommittedBlock = 100; - ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MinBlockFromPersisted + 1; + ulong lastPersistedBlock = latestCommittedBlock - PruneBoundary - MinBlockFromPersisted + 1; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); @@ -39,7 +39,7 @@ public void ShouldPruneDirtyNode_should_return_false_when_block_difference_is_le public void ShouldPruneDirtyNode_should_delegate_to_base_strategy_when_block_difference_is_greater_than_or_equal_to_min_block_from_persisted() { ulong latestCommittedBlock = 100; - ulong lastPersistedBlock = latestCommittedBlock - (ulong)PruneBoundary - (ulong)MinBlockFromPersisted; + ulong lastPersistedBlock = latestCommittedBlock - PruneBoundary - MinBlockFromPersisted; TrieStoreState state = new(100, 200, latestCommittedBlock, lastPersistedBlock); _baseStrategy.ShouldPruneDirtyNode(state).Returns(true); From 5e6dde745bd075ae19103ee0f53ca05375b2c82c Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 11:47:44 +0200 Subject: [PATCH 20/60] fix(build): remove dangling reference to deleted SszNumericChecks, lint cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Nethermind.Stateless.Executor.csproj: drop link to deleted SszRest/SszNumericChecks.cs - Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs: restore space lost in long?→ulong? replace_all - Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs: drop unused System using left over after Math.Max(0UL, …) removal Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs | 6 +++--- .../Nethermind.Stateless.Executor.csproj | 1 - .../Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs index b9ded59b70e5..23f2f37dfc5c 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/OpcodeTracingConfig.cs @@ -11,8 +11,8 @@ public class OpcodeTracingConfig : IOpcodeTracingConfig public bool Enabled { get; set; } public string OutputDirectory { get; set; } = "traces/opcodes"; public int MaxDegreeOfParallelism { get; set; } = 0; - public ulong?StartBlock { get; set; } - public ulong?EndBlock { get; set; } - public ulong?RecentBlocks { get; set; } + public ulong? StartBlock { get; set; } + public ulong? EndBlock { get; set; } + public ulong? RecentBlocks { get; set; } public string Mode { get; set; } = "RealTime"; } diff --git a/src/Nethermind/Nethermind.Stateless.Executor/Nethermind.Stateless.Executor.csproj b/src/Nethermind/Nethermind.Stateless.Executor/Nethermind.Stateless.Executor.csproj index 93748a84e393..dafba1f19d87 100644 --- a/src/Nethermind/Nethermind.Stateless.Executor/Nethermind.Stateless.Executor.csproj +++ b/src/Nethermind/Nethermind.Stateless.Executor/Nethermind.Stateless.Executor.csproj @@ -20,7 +20,6 @@ - diff --git a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs index 2baf88274c4f..9d716f97027a 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Threading.Tasks; using NSubstitute; using NUnit.Framework; From 2ec13bce31505dc7f9e8f3a34c456f65b80038f3 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 13:07:58 +0200 Subject: [PATCH 21/60] fix(eip8037): restore master's Validate semantics to unblock Pyspec The PR's Validate signature dropped the intrinsicRegular/intrinsicState subtractions, making the worst-case dimension calculation strictly match `min(TX_MAX_GAS_LIMIT, tx.gas)` and `tx.gas`. Master subtracts the opposite-dimension intrinsic before clamping, yielding a smaller worst- case that lets txs through when one dimension is tight but the tx's intrinsic mass lives in the other dimension. The Amsterdam test `test_block_2d_gas_valid_when_cumulative_exceeds_limit` fails under the PR's stricter check; master is green. Port master's behavior to the PR's ulong signature using SaturatingSub for the txGas - intrinsic{State,Regular} subtractions. Also revert the CalculateBlockRegularGas + Storage SSTORE Refund SaturatingSub changes back to raw subtracts so they match the PR's tested behavior. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Eip8037BlockGasInclusionCheck.cs | 33 ++++++------------- .../Instructions/EvmInstructions.Storage.cs | 7 ++-- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs index 681eceaf82e9..8aa6dcfd7467 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs @@ -14,22 +14,6 @@ public static class Eip8037BlockGasInclusionCheck { public enum Outcome { Ok, RegularDimensionExceeded, StateDimensionExceeded } - /// - /// Validates if a transaction can be included in a block under EIP-8037 pre-inclusion check. - /// - /// - /// Checks that the transaction's maximum possible contribution to both regular and state gas dimensions - /// does not exceed the remaining available space for those dimensions in the block. - /// Refer to EIP-8037 section "Transaction validation": - /// min(TX_MAX_GAS_LIMIT, tx.gas) <= regular_gas_available and tx.gas <= state_gas_available. - /// - /// The block's gas limit. - /// The block's cumulative regular gas used. - /// The block's cumulative state gas used. - /// The transaction's gas limit. - /// Unused. Kept for backward compatibility. - /// Unused. Kept for backward compatibility. - /// An Outcome representing the validation result. public static Outcome Validate( ulong blockGasLimit, ulong cumulativeBlockRegular, @@ -38,14 +22,19 @@ public static Outcome Validate( ulong intrinsicRegular, ulong intrinsicState) { - ulong regularAvailable = blockGasLimit - cumulativeBlockRegular; - ulong stateAvailable = blockGasLimit - cumulativeBlockState; + ulong regularAvailable = blockGasLimit.SaturatingSub(cumulativeBlockRegular); + ulong stateAvailable = blockGasLimit.SaturatingSub(cumulativeBlockState); - ulong worstCaseRegular = Math.Min(Eip7825Constants.DefaultTxGasLimitCap, txGas); + // Keep below-intrinsic txs from producing a negative worst-case regular dimension. + ulong worstCaseRegular = txGas.SaturatingSub(intrinsicState); + if (worstCaseRegular > Eip7825Constants.DefaultTxGasLimitCap) + worstCaseRegular = Eip7825Constants.DefaultTxGasLimitCap; if (worstCaseRegular > regularAvailable) return Outcome.RegularDimensionExceeded; - ulong worstCaseState = txGas; + // The state dimension has no per-tx equivalent of EIP-7825's DefaultTxGasLimitCap; + // state-heavy work may be funded by the state reservoir above that regular-dimension cap. + ulong worstCaseState = txGas.SaturatingSub(intrinsicRegular); if (worstCaseState > stateAvailable) return Outcome.StateDimensionExceeded; @@ -60,9 +49,7 @@ public static ulong CalculateBlockRegularGas( ulong stateGasSpillReclassified, ulong floorGas) { - // Saturating: a stale invariant would otherwise wrap and silently blow the block gas limit. - ulong consumedAfterRefund = initialRegularGas.SaturatingSub(remainingRegularGas); - ulong executionRegularGasUsed = consumedAfterRefund.SaturatingSub(stateGasSpill) + stateGasSpillReclassified; + ulong executionRegularGasUsed = initialRegularGas - remainingRegularGas - stateGasSpill + stateGasSpillReclassified; ulong blockRegularGas = intrinsicRegularGas + executionRegularGasUsed; return Math.Max(blockRegularGas, floorGas); } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index e3215e9f6ca8..1e474df3e42a 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -550,12 +550,9 @@ internal static EvmExceptionType InstructionSStoreMetered= sClearRefunds here, but a wrap would - // grant the maximum refund post-cap. Consensus-relevant. - ulong refundBefore = vmState.Refund; - vmState.Refund = refundBefore.SaturatingSub(sClearRefunds); + vmState.Refund -= sClearRefunds; if (vm.TxTracer.IsTracingRefunds) - vm.TxTracer.ReportRefund(-(long)(refundBefore - vmState.Refund)); + vm.TxTracer.ReportRefund(-(long)sClearRefunds); } if (newIsZero) From 539cd12a72f7a24cfefa46e75492665eb5e9d7b9 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 13:25:20 +0200 Subject: [PATCH 22/60] test(eip8037): align inclusion check tests with master's worst-case formula The PR-added unit / integration tests asserted the "raw tx.gas" inclusion predicate (worst-case state = tx.gas, no intrinsicRegular subtraction). That contradicts the Pyspec fixture `tests/amsterdam/eip8037_state_creation_gas_cost_increase/.../test_block_2d_gas_valid_when_cumulative_exceeds_limit`, which passes on master because master's Validate subtracts the opposite- dimension intrinsic before clamping. Drop the two PR-added cases that required the raw-tx.gas predicate; rewrite the parameterized Boundary_state case to assert the worst-case-after-intrinsic-subtract semantics. - Eip8037BlockGasInclusionCheckTests: drop Creation_tx_regular_check_without_subtraction_rejects; update Boundary_state deltas so the rejection lands when (tx.gas - intrinsicRegular) > stateAvailable - Eip8037BlockGasIntegrationTests: drop Eip8037_creation_tx_regular_check_without_subtraction_rejects Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Eip8037BlockGasIntegrationTests.cs | 24 ------------ .../Eip8037BlockGasInclusionCheckTests.cs | 37 +++---------------- 2 files changed, 5 insertions(+), 56 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs index 5b54353cfb38..50374787ef40 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs @@ -106,30 +106,6 @@ public void Eip8037_boundary_state(ulong blockStateGasUsed, bool accepts) } } - /// - /// Creation tx is rejected at inclusion because the corrected EIP-8037 formula - /// does not subtract intrinsic.state from the raw tx.gas. - /// - [Test] - public void Eip8037_creation_tx_regular_check_without_subtraction_rejects() - { - ulong blockGasLimit = 16_777_216ul + 53_000ul + 1ul; // cap + intrinsic_regular + 1 - Transaction filler = Build.A.Transaction.WithHash(TestItem.KeccakA).WithGasLimit(16_777_216ul).TestObject; - Transaction createTx = Build.A.Transaction.WithHash(TestItem.KeccakB) - .WithCode([]) - .WithGasLimit(53_000ul + IntrinsicNewAccountState) - .WithNonce(1ul).TestObject; - (BlockAccessListManager mgr, Block block) = BuildAmsterdamBlock(blockGasLimit, filler, createTx); - - GasValidationResultSlot[] results = ResultsForCount(2); - // Filler used full cap; create tx used modest regular + intrinsic state. - results[0].TrySetResult(GasResult(block, 0, 16_777_216ul, 0ul)); - results[1].TrySetResult(GasResult(block, 1, 53_000ul, IntrinsicNewAccountState)); - - Assert.Throws(() => - mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None)); - } - /// /// A single tx whose worst-case state contribution exceeds /// block_gas_limit must be rejected at inclusion. diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs index 56524314210a..046bdaadbb1b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs @@ -19,12 +19,11 @@ public class Eip8037BlockGasInclusionCheckTests private const ulong CreateIntrinsicRegular = 53_000; private const ulong SStoreStateGas = 64 * CostPerStateByte; // GasCostOf.SSetState - [TestCase(0L, Eip8037BlockGasInclusionCheck.Outcome.Ok, TestName = "Boundary_state_exact_fit_accepts")] - [TestCase(1L, Eip8037BlockGasInclusionCheck.Outcome.StateDimensionExceeded, TestName = "Boundary_state_exceeded_by_one_rejects_on_state_dimension")] - public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome expected) + // Worst-case state dimension is (tx.gas - intrinsicRegular). Reject when that exceeds state_available. + [TestCase(BaseIntrinsicRegular, Eip8037BlockGasInclusionCheck.Outcome.Ok, TestName = "Boundary_state_exact_fit_accepts")] + [TestCase(BaseIntrinsicRegular + 1, Eip8037BlockGasInclusionCheck.Outcome.StateDimensionExceeded, TestName = "Boundary_state_exceeded_by_one_rejects_on_state_dimension")] + public void Boundary_state(ulong delta, Eip8037BlockGasInclusionCheck.Outcome expected) { - // tx1: 50 cold SSTOREs in regular cap budget. Reproduces the spec test - // setup: tx1_state = num_sstores * sstore_state_gas; tx1_gas = cap + tx1_state. const int numSstores = 50; ulong tx1State = numSstores * SStoreStateGas; ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + tx1State + 100_000; @@ -33,7 +32,7 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp ulong cumS_afterTx1 = tx1State; ulong stateAvailable = blockGasLimit - cumS_afterTx1; - ulong tx2Gas = (ulong)((long)stateAvailable + delta); + ulong tx2Gas = stateAvailable + delta; Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( blockGasLimit, cumR_afterTx1, cumS_afterTx1, tx2Gas, BaseIntrinsicRegular, intrinsicState: 0); @@ -41,32 +40,6 @@ public void Boundary_state(long delta, Eip8037BlockGasInclusionCheck.Outcome exp Assert.That(outcome, Is.EqualTo(expected)); } - // Creation tx: tx.gas > regular_available and is rejected on regular dimension without subtraction. - [Test] - public void Creation_tx_regular_check_without_subtraction_rejects() - { - ulong intrinsicState = IntrinsicNewAccountState; - ulong intrinsicRegular = CreateIntrinsicRegular; - ulong intrinsicTotal = intrinsicRegular + intrinsicState; - - // Filler consumed full cap. Remaining regular = intrinsic_regular + 1. - ulong remainingRegular = intrinsicRegular + 1; - ulong blockGasLimit = Eip7825Constants.DefaultTxGasLimitCap + remainingRegular; - ulong cumR_afterFiller = blockGasLimit - remainingRegular; - ulong cumS_afterFiller = 0; - - // Creation tx: tx.gas = intrinsic_total. Raw tx.gas > remaining_regular. - // Under the corrected EIP-8037 logic, this must be rejected as no intrinsic gas subtraction is performed. - ulong createTxGas = intrinsicTotal; - - Assert.That(Math.Min(Eip7825Constants.DefaultTxGasLimitCap, createTxGas), Is.GreaterThan(remainingRegular)); - - Eip8037BlockGasInclusionCheck.Outcome outcome = Eip8037BlockGasInclusionCheck.Validate( - blockGasLimit, cumR_afterFiller, cumS_afterFiller, createTxGas, intrinsicRegular, intrinsicState); - - Assert.That(outcome, Is.EqualTo(Eip8037BlockGasInclusionCheck.Outcome.RegularDimensionExceeded)); - } - // Single tx state contribution > block_gas_limit -> reject. [Test] public void Single_tx_state_check_exceeds_block_limit_rejects() From 079d1c85f76915b1fa93a441b6e867c1ddb938f8 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 17 Jun 2026 15:49:43 +0200 Subject: [PATCH 23/60] fix(geth-types): post-review HIGH/MEDIUM/NIT fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HIGH: - BeaconPivot.GetLowestBlockToFinalize: guard `Head.Number - MaxDepth + 1` — wrapped to a near-ulong.MaxValue safe number when head < 64. - Optimism BatchV1.DecodeTxs: drop (ulong) cast on UInt256 tx values; the Transaction.Value / DecodedMaxFeePerGas fields are UInt256 and the cast silently truncated any tx > ~18.4 ETH. - EthereumGasPolicy.CreateAvailableFromIntrinsic: Debug.Assert on the two unguarded subtracts (gasLimit - intrinsicRegular - intrinsicState and TX_MAX_GAS_LIMIT - intrinsicRegular). Callers validate today; this catches future eth_call paths that skip validation. - EvmInstructions.Storage SSTORE refund: Debug.Assert + SaturatingSub on `Refund -= sClearRefunds`. Per EIP-2200/3529 the matching `+= sClearRefunds` ran earlier so the invariant holds; the saturating subtract guards against an out-of-order wrap silently granting the maximum post-cap refund. - ReceiptMigration.MigrationPointerTracker.ReportCompleted: guard `_nextToConfirm--` at 0 so a fully-migrated chain doesn't wrap the tracker into ulong.MaxValue. Reports `MigratedBlockNumber = 0` when genesis is reached. MEDIUM: - VmState.CommitToParent: `checked` the parentState.Refund += Refund. Gas- bounded so unreachable in practice, but the unsigned add no longer caught a buggy negative-child propagation that master's signed long would have. - Eip8037BlockGasInclusionCheck.Validate: early-return RegularDimensionExceeded / StateDimensionExceeded when cumulative > limit. The prior SaturatingSub silently floored to 0 and the worst-case check could falsely succeed. - CompactionSchedule.NextFullCompactionAfter: clamp `from + distance` at ulong.MaxValue. Unreachable at any realistic chain height; explicit. - AuRaBlockFinalizationManager.LoadInitialLastFinalizedBlockLevel and GetFinalizationLevel: drop the long round-trip and use ulong arithmetic with explicit zero/underflow guards. Avoids the 2^63-1 wrap that was only theoretical but exposed by the signed→unsigned migration. NIT: - BlockTree.GetBlockHashOnMainOrBestDifficultyHash: drop dead `blockNumber < 0` check on ulong parameter. - ReceiptsSyncFeed: drop stale "_barrier is long" comment (now ulong). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.Blockchain/BlockTree.cs | 5 ----- .../AuRaBlockFinalizationManager.cs | 16 ++++++++-------- .../GasPolicy/Eip8037BlockGasInclusionCheck.cs | 9 +++++++-- .../GasPolicy/EthereumGasPolicy.cs | 8 ++++++++ .../Instructions/EvmInstructions.Storage.cs | 8 +++++++- src/Nethermind/Nethermind.Evm/VmState.cs | 4 +++- .../Steps/Migrations/ReceiptMigration.cs | 9 ++++++--- .../Synchronization/BeaconPivot.cs | 4 ++-- .../Nethermind.Optimism/CL/Decoding/BatchV1.cs | 8 ++++---- .../Nethermind.State.Flat/CompactionSchedule.cs | 4 +++- .../FastBlocks/ReceiptsSyncFeed.cs | 1 - 11 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index a5816be42328..0632f7f1deae 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -704,11 +704,6 @@ as it does not require the step of resolving number -> hash */ private Hash256? GetBlockHashOnMainOrBestDifficultyHash(ulong blockNumber) { - if (blockNumber < 0) - { - throw new ArgumentOutOfRangeException(nameof(blockNumber), $"Value must be greater or equal to zero but is {blockNumber}"); - } - ChainLevelInfo level = LoadLevel(blockNumber); if (level is null) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs index 27e4f455f8d1..2f5295b2ec40 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs @@ -67,17 +67,18 @@ public void SetMainBlockBranchProcessor(IBranchProcessor branchProcessor) private static ulong LoadInitialLastFinalizedBlockLevel(IBlockTree blockTree, IChainLevelInfoRepository chainLevelInfoRepository) { - bool hasHead = blockTree.Head is not null; - long level = hasHead ? (long)blockTree.Head!.Number + 1 : 0; + if (blockTree.Head is null) return 0UL; + ulong level = blockTree.Head.Number + 1; ChainLevelInfo chainLevel; do { + if (level == 0) return 0UL; level--; - chainLevel = chainLevelInfoRepository.LoadLevel((ulong)level); + chainLevel = chainLevelInfoRepository.LoadLevel(level); } - while (chainLevel?.MainChainBlock?.IsFinalized != true && level >= 0); + while (chainLevel?.MainChainBlock?.IsFinalized != true); - return level >= 0 ? (ulong)level : 0UL; + return level; } private void OnBlocksProcessing(object? sender, BlocksProcessingEventArgs e) @@ -318,9 +319,8 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) { // in that case check if it has enough blocks to best known to be finalized // as everything before pivot should be finalized - long blocksAfter = (long)_blockTree.BestKnownNumber - (long)level + 1; - // safe: minSealersForFinalization is derived from validator counts and is bounded well within positive long range - if (blocksAfter >= (long)minSealersForFinalization) + ulong bestKnown = _blockTree.BestKnownNumber; + if (bestKnown >= level && bestKnown - level + 1 >= minSealersForFinalization) { return level + minSealersForFinalization - 1UL; } diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs index 8aa6dcfd7467..512f97f95ac0 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/Eip8037BlockGasInclusionCheck.cs @@ -22,8 +22,13 @@ public static Outcome Validate( ulong intrinsicRegular, ulong intrinsicState) { - ulong regularAvailable = blockGasLimit.SaturatingSub(cumulativeBlockRegular); - ulong stateAvailable = blockGasLimit.SaturatingSub(cumulativeBlockState); + // A cumulative dimension that already exceeded the block limit must reject — silent saturation + // would otherwise let the worst-case check pass and admit a tx that block-end validation rejects. + if (cumulativeBlockRegular > blockGasLimit) return Outcome.RegularDimensionExceeded; + if (cumulativeBlockState > blockGasLimit) return Outcome.StateDimensionExceeded; + + ulong regularAvailable = blockGasLimit - cumulativeBlockRegular; + ulong stateAvailable = blockGasLimit - cumulativeBlockState; // Keep below-intrinsic txs from producing a negative worst-case regular dimension. ulong worstCaseRegular = txGas.SaturatingSub(intrinsicState); diff --git a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs index 8984b5e85b58..0037262bbe75 100644 --- a/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs +++ b/src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Diagnostics; using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Extensions; @@ -509,6 +510,13 @@ public static IntrinsicGas CalculateIntrinsicGas(Transaction [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EthereumGasPolicy CreateAvailableFromIntrinsic(ulong gasLimit, in EthereumGasPolicy intrinsicGas, IReleaseSpec spec) { + // Callers must validate intrinsic gas against gasLimit (ValidateIntrinsicGas / Eip8037.ExceedsCap) + // before calling; if they don't, the subtraction wraps silently. + Debug.Assert(gasLimit >= intrinsicGas.Value + intrinsicGas.StateReservoir, + $"gasLimit ({gasLimit}) < intrinsicRegular ({intrinsicGas.Value}) + intrinsicState ({intrinsicGas.StateReservoir})"); + Debug.Assert(!spec.IsEip8037Enabled || Eip7825Constants.DefaultTxGasLimitCap >= intrinsicGas.Value, + "Eip8037 enabled but intrinsicRegular exceeds tx gas cap."); + ulong executionGas = gasLimit - intrinsicGas.Value - intrinsicGas.StateReservoir; ulong reservoir = 0; diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index 1e474df3e42a..86e732c46c10 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Nethermind.Core; @@ -550,7 +551,12 @@ internal static EvmExceptionType InstructionSStoreMetered= sClearRefunds. Saturating guards against an unsigned + // wrap silently granting the maximum post-cap refund. Consensus-relevant. + Debug.Assert(vmState.Refund >= sClearRefunds, + "EIP-2200/3529 refund accumulator went below the per-slot clear amount."); + vmState.Refund = vmState.Refund.SaturatingSub(sClearRefunds); if (vm.TxTracer.IsTracingRefunds) vm.TxTracer.ReportRefund(-(long)sClearRefunds); } diff --git a/src/Nethermind/Nethermind.Evm/VmState.cs b/src/Nethermind/Nethermind.Evm/VmState.cs index ad61a7fea480..6e143c88378f 100644 --- a/src/Nethermind/Nethermind.Evm/VmState.cs +++ b/src/Nethermind/Nethermind.Evm/VmState.cs @@ -288,7 +288,9 @@ private unsafe static nuint GetAlignmentOffset32(byte[] array) public void CommitToParent(VmState parentState) { ObjectDisposedException.ThrowIf(_isDisposed, this); - parentState.Refund += Refund; + // Gas-bounded refunds can't realistically overflow ulong, but guard the unsigned add since + // master's signed long would have caught a buggy negative-child silently. + parentState.Refund = checked(parentState.Refund + Refund); _canRestore = false; // we can't restore if we committed } } diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs index 695e5cd56447..dbc7cfab4561 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs @@ -402,14 +402,17 @@ public void ReportCompleted(ulong blockNumber) _completedAwaitingContiguity.Add(blockNumber); bool advanced = false; + bool reachedGenesis = false; while (_completedAwaitingContiguity.Remove(_nextToConfirm)) { - _nextToConfirm--; advanced = true; + if (_nextToConfirm == 0) { reachedGenesis = true; break; } + _nextToConfirm--; } - ulong migratedBlockNumber = _nextToConfirm + 1; - if (advanced && receiptStorage.MigratedBlockNumber > migratedBlockNumber) + if (!advanced) return; + ulong migratedBlockNumber = reachedGenesis ? 0UL : _nextToConfirm + 1; + if (receiptStorage.MigratedBlockNumber > migratedBlockNumber) { receiptStorage.MigratedBlockNumber = migratedBlockNumber; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index 5f44962b43fd..8e35eef751d1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs @@ -85,8 +85,8 @@ public ulong PivotDestinationNumber if (_blockTree.Head is not null && _blockTree.Head?.Number != 0) { // However, the head may not be canon, so the destination need to be before that. - ulong safeNumber = _blockTree.Head!.Number - Reorganization.MaxDepth + 1; - return Math.Max(1, safeNumber); + ulong headNumber = _blockTree.Head!.Number; + return headNumber > Reorganization.MaxDepth ? headNumber - Reorganization.MaxDepth + 1 : 1; } return _blockTree.SyncPivot.BlockNumber + 1; diff --git a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs index 8ff37bb5b775..613ca3ab84f3 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs @@ -116,7 +116,7 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis } (UInt256 legacyValue, tx.GasPrice, byte[] legacyData) = DecodeLegacyTransaction(Txs.Data[(int)txIdx].Span); - tx.Value = (ulong)legacyValue; + tx.Value = legacyValue; tx.Data = legacyData; break; } @@ -124,7 +124,7 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis { v = EthereumEcdsaExtensions.CalculateV(chainId, parityBit); (UInt256 accessValue, tx.GasPrice, byte[] accessData, tx.AccessList) = DecodeAccessListTransaction(Txs.Data[(int)txIdx].Span); - tx.Value = (ulong)accessValue; + tx.Value = accessValue; tx.Data = accessData; break; } @@ -133,8 +133,8 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis v = EthereumEcdsaExtensions.CalculateV(chainId, parityBit); (UInt256 eipValue, tx.GasPrice, UInt256 maxFee, byte[] eipData, tx.AccessList) = DecodeEip1559Transaction(Txs.Data[(int)txIdx].Span); - tx.Value = (ulong)eipValue; - tx.DecodedMaxFeePerGas = (ulong)maxFee; + tx.Value = eipValue; + tx.DecodedMaxFeePerGas = maxFee; tx.Data = eipData; break; } diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index 46a3dcb5de25..f3b52b307000 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -58,7 +58,9 @@ public ulong NextFullCompactionAfter(ulong from) ulong mod = (from + _offset) % _compactSize; ulong distance = mod == 0 ? _compactSize : _compactSize - mod; - return from + distance; + // Practically unreachable at realistic chain heights, but explicit so a degenerate + // `from` near ulong.MaxValue doesn't wrap into a wildly-wrong "next" boundary. + return from > ulong.MaxValue - distance ? ulong.MaxValue : from + distance; } private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger) diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs index a77226b85880..37c3f1e25dae 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs @@ -278,7 +278,6 @@ private int InsertReceipts(ReceiptsSyncBatch batch) Block? block = _blockTree.FindBlock(blockInfo.BlockHash); if (block is null) { - // blockInfo.BlockNumber is ulong; _barrier is long. Cast is safe for realistic heights. if (blockInfo.BlockNumber >= _barrier) { if (_logger.IsWarn) _logger.Warn($"Could not find block {blockInfo.BlockHash}"); From 21938e5ebdaab2cb4e5720bdb6b369dd23d241c2 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 18 Jun 2026 02:45:15 +0530 Subject: [PATCH 24/60] fix(json-serialization): reject leading zeros in hex quantities and clean up XDC comments --- .../Nethermind.Core.Test/Json/LongConverterTests.cs | 5 ++++- .../Nethermind.Core.Test/Json/NullableLongConverterTests.cs | 5 ++++- .../Nethermind.Core.Test/Json/NullableULongConverterTests.cs | 5 ++++- .../Nethermind.Serialization.Json/LongConverter.cs | 2 +- .../Nethermind.Serialization.Json/NumericConverterHelper.cs | 5 +++++ .../Nethermind.Serialization.Json/ULongConverter.cs | 2 +- src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs | 2 -- src/Nethermind/Nethermind.Xdc/VotesManager.cs | 5 ----- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs index e13e0017df13..7f0883d3b0cc 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs @@ -22,7 +22,6 @@ public class LongConverterTests : ConverterTestBase [TestCase("\"0xa00000\"", 10485760L)] [TestCase("\"0x0\"", 0L)] - [TestCase("\"0x0000\"", 0L)] [TestCase("0", 0L)] [TestCase("1", 1L)] public void Can_read_value(string json, long expected) @@ -31,6 +30,10 @@ public void Can_read_value(string json, long expected) Assert.That(result, Is.EqualTo(expected)); } + [TestCase("\"0x0000\"")] + public void Throws_on_leading_zeros(string json) => Assert.Throws( + () => JsonSerializer.Deserialize(json, options)); + [Test] public void Throws_on_null() => Assert.Throws( static () => JsonSerializer.Deserialize("null", options)); diff --git a/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs index 2422fa86bbef..146faa6e5089 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs @@ -24,7 +24,6 @@ public class NullableLongConverterTests : ConverterTestBase [TestCase("\"0xa00000\"", 10485760L)] [TestCase("\"0x0\"", 0L)] - [TestCase("\"0x0000\"", 0L)] [TestCase("0", 0L)] [TestCase("1", 1L)] [TestCase("-1", -1L)] @@ -34,6 +33,10 @@ public void Can_read_value(string json, long expected) Assert.That(result, Is.EqualTo(expected)); } + [TestCase("\"0x0000\"")] + public void Throws_on_leading_zeros(string json) => Assert.Throws( + () => JsonSerializer.Deserialize(json, options)); + [Test] public void Can_read_null() { diff --git a/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs index 29c661797eca..38e9254f5573 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs @@ -22,7 +22,6 @@ public class NullableULongConverterTests : ConverterTestBase [TestCase("\"0xa00000\"", 10485760UL)] [TestCase("\"0x0\"", 0UL)] - [TestCase("\"0x000\"", 0UL)] [TestCase("0", 0UL)] [TestCase("1", 1UL)] public void Can_read_value(string json, ulong expected) @@ -31,6 +30,10 @@ public void Can_read_value(string json, ulong expected) Assert.That(result, Is.EqualTo(expected)); } + [TestCase("\"0x000\"")] + public void Throws_on_leading_zeros(string json) => Assert.Throws( + () => JsonSerializer.Deserialize(json, options)); + [Test] public void Can_read_null() { diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs index 0f3e79eb1a53..6881c1c24e6b 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs @@ -29,7 +29,7 @@ public static long FromString(string s) if (s.StartsWith("0x0")) { - return long.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); + throw new JsonException("hex to long"); } if (s.StartsWith("0x")) diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index f02d73ca4eaa..8b372abe13b9 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -33,6 +33,11 @@ public static T Parse(ReadOnlySpan s) where T : struct, INumberBase return T.Zero; } + if (s.StartsWith("0x0"u8)) + { + ThrowHexConversion(typeof(T).Name); + } + if (s.StartsWith("0x"u8)) { s = s[2..]; diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index 5f0152c5a0e6..fc7b8263bd2a 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -27,7 +27,7 @@ public static ulong FromString(string s) if (s.StartsWith("0x0")) { - return ulong.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); + throw new JsonException("hex to ulong"); } if (s.StartsWith("0x")) diff --git a/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs b/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs index 803a432417ce..3fd00a92c863 100644 --- a/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs +++ b/src/Nethermind/Nethermind.Xdc/TimeoutCertificateManager.cs @@ -275,7 +275,6 @@ private void SendTimeout() { ulong currentNumber = currentHeader.Number + 1; ulong offset = currentNumber % spec.EpochLength + spec.Gap; - // Guard against underflow: if currentNumber is less than the offset, gap is 0. gapNumber = currentNumber > offset ? currentNumber - offset : 0UL; } else @@ -284,7 +283,6 @@ private void SendTimeout() ?? throw new DataExtractionException(nameof(EpochSwitchInfo)); ulong currentNumber = epochSwitchInfo.EpochSwitchBlockInfo.BlockNumber; ulong offset = currentNumber % spec.EpochLength + spec.Gap; - // Guard against underflow: if currentNumber is less than the offset, gap is 0. gapNumber = currentNumber > offset ? currentNumber - offset : 0UL; } diff --git a/src/Nethermind/Nethermind.Xdc/VotesManager.cs b/src/Nethermind/Nethermind.Xdc/VotesManager.cs index a96c95f1578d..cb00f39ac118 100644 --- a/src/Nethermind/Nethermind.Xdc/VotesManager.cs +++ b/src/Nethermind/Nethermind.Xdc/VotesManager.cs @@ -77,7 +77,6 @@ public Task CastVote(BlockRoundInfo blockInfo) else { ulong offset = epochSwitchNumber % spec.EpochLength + spec.Gap; - // Guard against underflow: if epochSwitchNumber is less than the offset, gap is 0. gapNumber = epochSwitchNumber > offset ? epochSwitchNumber - offset : 0UL; } @@ -261,16 +260,12 @@ private void OnVotePoolThresholdReached(Signature[] validSignatures, Vote currVo private bool IsExtendingFromAncestor(Hash256 blockHash, ulong blockNumber, BlockRoundInfo ancestorBlockInfo) { - // blockNumber >= ancestorBlockInfo.BlockNumber is expected; if not, the block cannot - // extend the ancestor and we return false rather than underflowing. if (blockNumber < ancestorBlockInfo.BlockNumber) return false; ulong blockNumDiff = blockNumber - ancestorBlockInfo.BlockNumber; Hash256 nextBlockHash = blockHash; - // blockNumDiff is bounded by _maxBlockDistance in practice, so casting to int for - // the loop counter is safe (ulong diff that exceeds int.MaxValue would be a chain error). for (ulong i = 0; i < blockNumDiff; i++) { if (_blockTree.FindHeader(nextBlockHash) is not XdcBlockHeader parentHeader) From a51af910aac9968f4ce510504b9a04a81a255d83 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 18 Jun 2026 14:04:27 +0530 Subject: [PATCH 25/60] refactor: address review comments on casts, comments, and hex quantity deserialization - Cast ancestorsCount and relationshipLevel to ulong early in UnclesValidator.IsKin to run Math.Min entirely on ulong. - Remove redundant (ulong) casts on ElasticityMultiplier / DefaultElasticityMultiplier. - Remove obsolete safe-cast comments in Eip1559GasLimitAdjuster, UnclesValidator, and HeaderValidator. - Support hex strings with leading zeros for block nonces and dictionary keys in JSON deserialization. --- .../TargetAdjustedGasLimitCalculatorTests.cs | 2 +- .../Eip1559GasLimitAdjuster.cs | 3 +- .../Validators/HeaderValidator.cs | 1 - .../Validators/UnclesValidator.cs | 6 ++-- .../Nethermind.Core.Test/BlockHeaderTests.cs | 2 +- .../Nethermind.Core/BaseFeeCalculator.cs | 2 +- .../LongConverter.cs | 2 +- .../LongRawJsonConverter.cs | 24 +++++++++++++++- .../NumericConverterHelper.cs | 28 +++++++++++++++++++ .../ULongConverter.cs | 6 ++++ .../ULongRawJsonConverter.cs | 24 +++++++++++++++- .../Json/ChainSpecEthereumSealJson.cs | 3 ++ .../ChainSpecStyle/Json/GethGenesisJson.cs | 2 ++ .../Nethermind.Taiko/TaikoHeaderValidator.cs | 2 +- 14 files changed, 94 insertions(+), 13 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs index 589a806eb120..cb4f0e9880a5 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/TargetAdjustedGasLimitCalculatorTests.cs @@ -28,7 +28,7 @@ public void Is_bump_on_1559_eip_block() TargetAdjustedGasLimitCalculator targetedAdjustedGasLimitCalculator = new(specProvider, new BlocksConfig()); BlockHeader header = Build.A.BlockHeader.WithNumber(londonBlock - 1).WithGasLimit(gasLimit).TestObject; ulong actualValue = targetedAdjustedGasLimitCalculator.GetGasLimit(header); - Assert.That(actualValue, Is.EqualTo(gasLimit * (ulong)Eip1559Constants.DefaultElasticityMultiplier)); + Assert.That(actualValue, Is.EqualTo(gasLimit * Eip1559Constants.DefaultElasticityMultiplier)); } [TestCase(30_000_000ul, 100_000_000UL, 30029295UL)] diff --git a/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs b/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs index 42890d003a04..91404ff5487c 100644 --- a/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs +++ b/src/Nethermind/Nethermind.Consensus/Eip1559GasLimitAdjuster.cs @@ -13,8 +13,7 @@ public static ulong AdjustGasLimit(IReleaseSpec releaseSpec, ulong gasLimit, ulo ulong adjustedGasLimit = gasLimit; if (releaseSpec.Eip1559TransitionBlock == blockNumber) { - // Safe cast: ElasticityMultiplier is always a small positive constant (e.g. 2) - adjustedGasLimit *= (ulong)releaseSpec.ElasticityMultiplier; + adjustedGasLimit *= releaseSpec.ElasticityMultiplier; } return adjustedGasLimit; diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index 9068d30e7558..c1b4dc6f934c 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -220,7 +220,6 @@ protected virtual bool ValidateExtraData(BlockHeader header, IReleaseSpec spec, bool extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize && (isUncle || _daoBlockNumber is null - // Safe cast: DaoBlockNumber is a known small constant (~1.9M), always fits ulong || header.Number < _daoBlockNumber.Value || header.Number >= _daoBlockNumber.Value + 10 || Bytes.AreEqual(header.ExtraData, DaoExtraData)); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs index 0fc5553160ab..84dd032b3d89 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs @@ -103,14 +103,14 @@ public bool Validate(BlockHeader header, BlockHeader[] uncles) private static bool IsKin(BlockHeader header, BlockHeader uncle, int relationshipLevel, ReadOnlySpan ancestors, int ancestorsCount) { - int maxDepth = Math.Min(Math.Min(ancestorsCount, relationshipLevel), (int)header.Number); + ulong maxDepth = Math.Min(Math.Min((ulong)ancestorsCount, (ulong)relationshipLevel), header.Number); - if (uncle.Number < header.Number - (ulong)maxDepth) + if (uncle.Number < header.Number - maxDepth) { return false; } - for (int depth = 0; depth < maxDepth; depth++) + for (int depth = 0; depth < (int)maxDepth; depth++) { BlockHeader parent = ancestors[depth]; diff --git a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs index ab17317a7a97..7faea360cd92 100644 --- a/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/BlockHeaderTests.cs @@ -213,7 +213,7 @@ public void Eip_1559_CalculateBaseFee_shared_test_cases((BaseFeeTestCases Info, blockHeader.Number = 2001; // No cast needed: ParentTargetGasUsed is ulong, GasLimit is ulong post-migration. // ElasticityMultiplier is a small protocol constant (currently 2); product fits in ulong. - blockHeader.GasLimit = testCase.Info.ParentTargetGasUsed * (ulong)Eip1559Constants.DefaultElasticityMultiplier; + blockHeader.GasLimit = testCase.Info.ParentTargetGasUsed * Eip1559Constants.DefaultElasticityMultiplier; blockHeader.BaseFeePerGas = (UInt256)testCase.Info.ParentBaseFee; // No cast needed: ParentGasUsed is ulong, GasUsed is ulong post-migration. blockHeader.GasUsed = testCase.Info.ParentGasUsed; diff --git a/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs b/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs index 531347f67e1b..0ee2ec606e6d 100644 --- a/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs +++ b/src/Nethermind/Nethermind.Core/BaseFeeCalculator.cs @@ -23,7 +23,7 @@ public UInt256 Calculate(BlockHeader parent, IEip1559Spec specFor1559) { UInt256 parentBaseFee = parent.BaseFeePerGas; bool isForkBlockNumber = specFor1559.Eip1559TransitionBlock == parent.Number + 1; - ulong parentGasTarget = parent.GasLimit / (ulong)specFor1559.ElasticityMultiplier; + ulong parentGasTarget = parent.GasLimit / specFor1559.ElasticityMultiplier; if (isForkBlockNumber) parentGasTarget = parent.GasLimit; diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs index 6881c1c24e6b..870cad9a4f43 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs @@ -46,7 +46,7 @@ public static long FromString(string s) public override long ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - return FromString(hex); + return NumericConverterHelper.ParseLax(hex); } public static long FromString(ReadOnlySpan s) => NumericConverterHelper.Parse(s); diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs index fae6524caaf2..1972b011a8cc 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +#nullable enable using System; using System.Text.Json; using System.Text.Json.Serialization; @@ -12,7 +13,28 @@ public class LongRawJsonConverter : JsonConverter public override long Read( ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) => LongConverter.ReadCore(ref reader); + JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + { + return reader.GetInt64(); + } + + if (reader.TokenType == JsonTokenType.String) + { + string? s = reader.GetString(); + if (s is not null) + { + if (s.StartsWith("0x")) + { + return long.Parse(s.AsSpan(2), System.Globalization.NumberStyles.AllowHexSpecifier); + } + return long.Parse(s, System.Globalization.NumberStyles.Integer); + } + } + + throw new JsonException(); + } public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index 8b372abe13b9..a04c83165ee4 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -55,6 +55,34 @@ public static T Parse(ReadOnlySpan s) where T : struct, INumberBase return default; } + /// + /// Parse a UTF-8 span that may be hex ("0x...") or decimal into without strict leading zero checks. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ParseLax(ReadOnlySpan s) where T : struct, INumberBase + { + if (s.Length == 0) + { + ThrowNullAssignment(typeof(T).Name); + } + + if (s.StartsWith("0x"u8)) + { + s = s[2..]; + if (T.TryParse(s, NumberStyles.AllowHexSpecifier, null, out T value)) + { + return value; + } + } + else if (T.TryParse(s, NumberStyles.Integer, null, out T value)) + { + return value; + } + + ThrowHexConversion(typeof(T).Name); + return default; + } + /// /// Write a numeric value according to the current mode. /// diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index fc7b8263bd2a..1c17d3e3e986 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -72,4 +72,10 @@ public override ulong Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ReadCore(ref reader); + + public override ulong ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + return NumericConverterHelper.ParseLax(hex); + } } diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs index 06107e788c41..a40189087a0c 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +#nullable enable using System; using System.Text.Json; using System.Text.Json.Serialization; @@ -12,7 +13,28 @@ public class ULongRawJsonConverter : JsonConverter public override ulong Read( ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) => ULongConverter.ReadCore(ref reader); + JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + { + return reader.GetUInt64(); + } + + if (reader.TokenType == JsonTokenType.String) + { + string? s = reader.GetString(); + if (s is not null) + { + if (s.StartsWith("0x")) + { + return ulong.Parse(s.AsSpan(2), System.Globalization.NumberStyles.AllowHexSpecifier); + } + return ulong.Parse(s, System.Globalization.NumberStyles.Integer); + } + } + + throw new JsonException(); + } public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs index 195c896b9708..cca83bbfb291 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs @@ -1,12 +1,15 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Text.Json.Serialization; using Nethermind.Core.Crypto; +using Nethermind.Serialization.Json; namespace Nethermind.Specs.ChainSpecStyle.Json { public class ChainSpecEthereumSealJson { + [JsonConverter(typeof(ULongRawJsonConverter))] public ulong Nonce { get; set; } public Hash256 MixHash { get; set; } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs index b5e7d5ff3579..140743373dc0 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs @@ -6,6 +6,7 @@ using Nethermind.Int256; using System.Collections.Generic; using System.Text.Json.Serialization; +using Nethermind.Serialization.Json; namespace Nethermind.Specs.ChainSpecStyle.Json; @@ -18,6 +19,7 @@ public class GethGenesisJson public Dictionary? Alloc { get; set; } + [JsonConverter(typeof(ULongRawJsonConverter))] public ulong Nonce { get; set; } public ulong? Timestamp { get; set; } diff --git a/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs b/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs index b8a3ec177787..c0023b104133 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoHeaderValidator.cs @@ -130,7 +130,7 @@ private static UInt256 CalculateEip4396BaseFee(BlockHeader parent, ulong parentB } IEip1559Spec eip1559Spec = spec; - ulong parentGasTarget = parent.GasLimit / (ulong)eip1559Spec.ElasticityMultiplier; + ulong parentGasTarget = parent.GasLimit / eip1559Spec.ElasticityMultiplier; ulong parentAdjustedGasTarget = Math.Min(parentGasTarget * parentBlockTime / BlockTimeTarget, parent.GasLimit * MaxGasTargetPercentage / 100); From bcbbb7193101c62dc68e1b51695430676f29df46 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 18 Jun 2026 16:36:06 +0530 Subject: [PATCH 26/60] refactor(aura,state): address review comments on block finalization, step calculator, difficulty, and state boundary --- .../FullPruning/FullPruner.cs | 2 +- .../AuRaBlockFinalizationManager.cs | 8 +++++-- .../AuRaStepCalculator.cs | 18 ++++++++------- .../AuraDifficultyCalculator.cs | 7 +++--- .../Eth/EthRpcModuleTests.Capabilities.cs | 20 ++++++++--------- .../Modules/Eth/EthCapabilitiesProvider.cs | 12 +++++----- .../ScopeProvider/FlatWorldStateManager.cs | 6 ++--- .../StateBoundaryStoreTests.cs | 22 +++++++++---------- .../Nethermind.State/IStateBoundary.cs | 4 ++-- .../Nethermind.State/StateBoundaryStore.cs | 4 ++-- .../Nethermind.State/WorldStateManager.cs | 2 +- .../FastSync/PatriciaTreeSyncStore.cs | 2 +- 12 files changed, 57 insertions(+), 50 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs index 0dc7f5bc93d3..5c97a3d5442b 100644 --- a/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs +++ b/src/Nethermind/Nethermind.Blockchain/FullPruning/FullPruner.cs @@ -277,7 +277,7 @@ private void TryCopyTrie(IPruningContext pruning, BlockHeader? baseBlock, ulong // mirrors this write into the cloning DB, so after Commit() the new live DB // has the marker atomically with the swap — a crash in between cannot leave // the new DB live without the floor. - _stateBoundary.OldestStateBlock = (long)stateToCopy; + _stateBoundary.OldestStateBlock = stateToCopy; using (_trieStore.PrepareStableState(cancellationToken)) { diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs index d2f45c0be289..3378ffee403d 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockFinalizationManager.cs @@ -321,9 +321,13 @@ public ulong GetLastLevelFinalizedBy(Hash256 blockHash) // in that case check if it has enough blocks to best known to be finalized // as everything before pivot should be finalized ulong bestKnown = _blockTree.BestKnownNumber; - if (bestKnown >= level && bestKnown - level + 1 >= minSealersForFinalization) + if (bestKnown >= level) { - return level + minSealersForFinalization - 1UL; + ulong blocksAfter = bestKnown + 1UL - level; + if (blocksAfter >= minSealersForFinalization) + { + return level + minSealersForFinalization - 1UL; + } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs index 635da0d63aa9..069f5ac18238 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaStepCalculator.cs @@ -72,9 +72,11 @@ private long TimeToNextStepInTicks private static long GetTimeToNextStepInTicks(UnixTime unixTime, StepDurationInfo currentStepInfo) { - long timeFromTransition = unixTime.MillisecondsLong - currentStepInfo.TransitionTimestampMilliseconds; - long timeAlreadyPassedToNextStep = timeFromTransition % currentStepInfo.StepDurationMilliseconds; - return (currentStepInfo.StepDurationMilliseconds - timeAlreadyPassedToNextStep) * TimeSpan.TicksPerMillisecond; + ulong milliseconds = unixTime.Milliseconds; + ulong transition = currentStepInfo.TransitionTimestampMilliseconds; + ulong timeFromTransition = milliseconds >= transition ? milliseconds - transition : 0UL; + ulong timeAlreadyPassedToNextStep = timeFromTransition % currentStepInfo.StepDurationMilliseconds; + return (long)(currentStepInfo.StepDurationMilliseconds - timeAlreadyPassedToNextStep) * TimeSpan.TicksPerMillisecond; } private StepDurationInfo GetStepInfo(ulong timestampInSeconds) => @@ -127,20 +129,20 @@ private class StepDurationInfo : IActivatedAt { public StepDurationInfo(ulong transitionStep, ulong transitionTimestamp, ulong stepDuration) { - const long millisecondsInSecond = 1000; + const ulong millisecondsInSecond = 1000UL; TransitionStep = transitionStep; TransitionTimestamp = transitionTimestamp; StepDuration = stepDuration; - StepDurationMilliseconds = (long)stepDuration * millisecondsInSecond; - TransitionTimestampMilliseconds = (long)transitionTimestamp * millisecondsInSecond; + StepDurationMilliseconds = stepDuration * millisecondsInSecond; + TransitionTimestampMilliseconds = transitionTimestamp * millisecondsInSecond; } public ulong TransitionStep { get; } public ulong TransitionTimestamp { get; } - public long TransitionTimestampMilliseconds { get; } + public ulong TransitionTimestampMilliseconds { get; } public ulong StepDuration { get; } - public long StepDurationMilliseconds { get; } + public ulong StepDurationMilliseconds { get; } ulong IActivatedAt.Activation => TransitionTimestamp; public ulong GetCurrentStep(in ulong timestampSeconds) => TransitionStep + (timestampSeconds - TransitionTimestamp) / StepDuration; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs index 08cfe90841f9..acf4013f7ad3 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuraDifficultyCalculator.cs @@ -15,14 +15,15 @@ public class AuraDifficultyCalculator(IAuRaStepCalculator auRaStepCalculator) : public static UInt256 CalculateDifficulty(ulong parentStep, ulong currentStep, ulong emptyStepsCount = 0UL) { - if (parentStep + emptyStepsCount >= currentStep) + ulong parentStepWithEmpty = parentStep + emptyStepsCount; + if (parentStepWithEmpty >= currentStep) { - ulong diff = parentStep + emptyStepsCount - currentStep; + ulong diff = parentStepWithEmpty - currentStep; return MaxDifficulty + (UInt256)diff; } else { - ulong diff = currentStep - (parentStep + emptyStepsCount); + ulong diff = currentStep - parentStepWithEmpty; return MaxDifficulty - (UInt256)diff; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs index e984a8c0e3f8..5232f406e29b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs @@ -28,7 +28,7 @@ public partial class EthRpcModuleTests private static EthCapabilities GetCaps( ulong? retentionWindow = null, ulong headNumber = 1000, - long? oldestStateBlock = null, + ulong? oldestStateBlock = null, SyncConfig? syncConfig = null, ulong? lowestInsertedBody = null, ulong? lowestInsertedReceipt = null, @@ -74,7 +74,7 @@ public sealed record CapabilitiesScenario( { public ulong? RetentionWindow { get; init; } public ulong HeadNumber { get; init; } = 1000; - public long? OldestStateBlock { get; init; } + public ulong? OldestStateBlock { get; init; } public ulong? LowestInsertedBody { get; init; } public ulong? LowestInsertedReceipt { get; init; } public SyncConfig? SyncConfig { get; init; } @@ -153,10 +153,10 @@ private static IEnumerable CapabilitiesScenarios() // (OldestStateBlock = pivot) but historical block sync continues. const long midSyncBody = 12_000_000; const long midSyncReceipt = 12_500_000; - const long midSyncStateFloor = 18_000_000; + const ulong midSyncStateFloor = 18_000_000UL; ResourceAvailability midSyncBlocks = new(Disabled: false, OldestBlock: midSyncBody); ResourceAvailability midSyncReceipts = new(Disabled: false, OldestBlock: midSyncReceipt); - ResourceAvailability midSyncState = new(Disabled: false, OldestBlock: midSyncStateFloor); + ResourceAvailability midSyncState = new(Disabled: false, OldestBlock: (long)midSyncStateFloor); yield return new CapabilitiesScenario( Name: "fast_sync_mid_progress_reports_actual_lowest_inserted", ExpectedState: midSyncState, ExpectedStateproofs: midSyncState, @@ -191,8 +191,8 @@ private static IEnumerable CapabilitiesScenarios() SyncConfig = new SyncConfig { FastSync = true, PivotNumber = 18_000_000, DownloadReceiptsInFastSync = true, AncientBodiesBarrier = 5_000_000 }, }; - const long fastSyncFloor = 18_000_000; - ResourceAvailability fastSyncedState = new(Disabled: false, OldestBlock: fastSyncFloor); + const ulong fastSyncFloor = 18_000_000UL; + ResourceAvailability fastSyncedState = new(Disabled: false, OldestBlock: (long)fastSyncFloor); yield return new CapabilitiesScenario( Name: "archive_after_fast_sync_reports_pivot_floor", ExpectedState: fastSyncedState, ExpectedStateproofs: fastSyncedState, @@ -205,8 +205,8 @@ private static IEnumerable CapabilitiesScenarios() ExpectedReceipts: Available, ExpectedBlocks: Available) { SyncConfig = fullSync }; - const long fullPruneFloor = 500; - ResourceAvailability fullPruned = new(Disabled: false, OldestBlock: fullPruneFloor); + const ulong fullPruneFloor = 500UL; + ResourceAvailability fullPruned = new(Disabled: false, OldestBlock: (long)fullPruneFloor); yield return new CapabilitiesScenario( Name: "full_pruning_after_run_reports_copied_state_floor", ExpectedState: fullPruned, ExpectedStateproofs: fullPruned, @@ -226,8 +226,8 @@ private static IEnumerable CapabilitiesScenarios() { RetentionWindow = (ulong)retention, HeadNumber = memoryHead, OldestStateBlock = 0, SyncConfig = fullSync }; // Floor dominates window — DeleteStrategy is suppressed so oldestBlock and head-retentionBlocks stay consistent. - const long recentPivot = 950; - ResourceAvailability postSyncMemory = new(Disabled: false, OldestBlock: recentPivot); + const ulong recentPivot = 950UL; + ResourceAvailability postSyncMemory = new(Disabled: false, OldestBlock: (long)recentPivot); yield return new CapabilitiesScenario( Name: "memory_pruning_floor_dominates_window", ExpectedState: postSyncMemory, ExpectedStateproofs: postSyncMemory, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs index 40e829b3f65e..6f496b7fe4ea 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs @@ -59,20 +59,20 @@ public EthCapabilities GetCapabilities() private ResourceAvailability BuildState(BlockHeader head, bool fastSyncing) { - long? oldestStateBlock = stateBoundary.OldestStateBlock; + ulong? oldestStateBlock = stateBoundary.OldestStateBlock; // During fast sync, state isn't queryable until StateSyncRunner writes the pivot floor. if (fastSyncing && oldestStateBlock is null) return Disabled; - long stateFloor = oldestStateBlock ?? 0L; + ulong stateFloor = oldestStateBlock ?? 0UL; if (stateBoundary.RetentionWindowBlocks is not { } retention) - return new ResourceAvailability(Disabled: false, OldestBlock: stateFloor, DeleteStrategy: null); + return new ResourceAvailability(Disabled: false, OldestBlock: (long)stateFloor, DeleteStrategy: null); - long windowOldest = head.Number >= retention ? (long)(head.Number - retention) : 0L; - long stateOldest = Math.Max(stateFloor, windowOldest); + ulong windowOldest = head.Number >= retention ? head.Number - retention : 0UL; + ulong stateOldest = Math.Max(stateFloor, windowOldest); // Emit the window only when it's the binding constraint, and report the configured // retention so the value stays accurate before head reaches it. DeleteStrategy? window = windowOldest >= stateFloor ? BuildWindow((long)retention) : null; - return new ResourceAvailability(Disabled: false, OldestBlock: stateOldest, DeleteStrategy: window); + return new ResourceAvailability(Disabled: false, OldestBlock: (long)stateOldest, DeleteStrategy: window); } private static bool IsDescendingResourceDownloaded(bool fastSyncing, ulong pivot, bool downloadInFastSync, ulong? pointer) => diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs index 8c1a6caad529..c2538c394ec6 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateManager.cs @@ -50,12 +50,12 @@ public class FlatWorldStateManager( public ulong? RetentionWindowBlocks => null; - public long? OldestStateBlock + public ulong? OldestStateBlock { get { - long blockNumber = (long)persistenceManager.GetCurrentPersistedStateId().BlockNumber; - return blockNumber >= 0 ? blockNumber : null; + ulong blockNumber = persistenceManager.GetCurrentPersistedStateId().BlockNumber; + return blockNumber != ulong.MaxValue ? blockNumber : null; } } diff --git a/src/Nethermind/Nethermind.State.Test/StateBoundaryStoreTests.cs b/src/Nethermind/Nethermind.State.Test/StateBoundaryStoreTests.cs index 73946b6cedc5..76bafd09939c 100644 --- a/src/Nethermind/Nethermind.State.Test/StateBoundaryStoreTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateBoundaryStoreTests.cs @@ -17,14 +17,14 @@ public void Reads_null_when_key_absent() => public void Round_trips_value_through_kv_store() { TestMemDb kv = new(); - new StateBoundaryStore(kv).OldestStateBlock = 1234; - Assert.That(new StateBoundaryStore(kv).OldestStateBlock, Is.EqualTo(1234)); + new StateBoundaryStore(kv).OldestStateBlock = 1234UL; + Assert.That(new StateBoundaryStore(kv).OldestStateBlock, Is.EqualTo(1234UL)); } - [TestCase(100L, 200L, 200L, TestName = "Forward write advances the floor")] - [TestCase(200L, 100L, 200L, TestName = "Backward write is rejected")] - [TestCase(100L, 100L, 100L, TestName = "Equal write is a no-op")] - public void Set_against_existing_value(long initial, long attempted, long expected) + [TestCase(100UL, 200UL, 200UL, TestName = "Forward write advances the floor")] + [TestCase(200UL, 100UL, 200UL, TestName = "Backward write is rejected")] + [TestCase(100UL, 100UL, 100UL, TestName = "Equal write is a no-op")] + public void Set_against_existing_value(ulong initial, ulong attempted, ulong expected) { TestMemDb kv = new(); StateBoundaryStore store = new(kv) { OldestStateBlock = initial }; @@ -39,10 +39,10 @@ public void Set_against_existing_value(long initial, long attempted, long expect public void Idempotent_set_does_not_rewrite_kv() { TestMemDb kv = new(); - StateBoundaryStore store = new(kv) { OldestStateBlock = 42 }; + StateBoundaryStore store = new(kv) { OldestStateBlock = 42UL }; kv.Clear(); - store.OldestStateBlock = 42; + store.OldestStateBlock = 42UL; Assert.That(kv.Count, Is.EqualTo(0)); } @@ -51,13 +51,13 @@ public void Idempotent_set_does_not_rewrite_kv() public void Allows_null_reset_then_replays_writes() { TestMemDb kv = new(); - StateBoundaryStore store = new(kv) { OldestStateBlock = 200 }; + StateBoundaryStore store = new(kv) { OldestStateBlock = 200UL }; store.OldestStateBlock = null; Assert.That(store.OldestStateBlock, Is.Null); Assert.That(new StateBoundaryStore(kv).OldestStateBlock, Is.Null); - store.OldestStateBlock = 50; - Assert.That(store.OldestStateBlock, Is.EqualTo(50), "after reset a smaller floor is acceptable"); + store.OldestStateBlock = 50UL; + Assert.That(store.OldestStateBlock, Is.EqualTo(50UL), "after reset a smaller floor is acceptable"); } } diff --git a/src/Nethermind/Nethermind.State/IStateBoundary.cs b/src/Nethermind/Nethermind.State/IStateBoundary.cs index d218ebce5957..71b449f91865 100644 --- a/src/Nethermind/Nethermind.State/IStateBoundary.cs +++ b/src/Nethermind/Nethermind.State/IStateBoundary.cs @@ -15,7 +15,7 @@ public interface IStateBoundary /// completes (= pivot) and after a full pruning run completes (= copied state's block). /// Null if never set (archive node syncing from genesis). /// - long? OldestStateBlock { get; } + ulong? OldestStateBlock { get; } /// /// Configured rolling-window retention in blocks (e.g. trie memory pruning). Null when @@ -37,5 +37,5 @@ public interface IStateBoundary /// public interface IStateBoundaryWriter { - long? OldestStateBlock { set; } + ulong? OldestStateBlock { set; } } diff --git a/src/Nethermind/Nethermind.State/StateBoundaryStore.cs b/src/Nethermind/Nethermind.State/StateBoundaryStore.cs index ab80241852ad..639d41809fec 100644 --- a/src/Nethermind/Nethermind.State/StateBoundaryStore.cs +++ b/src/Nethermind/Nethermind.State/StateBoundaryStore.cs @@ -25,9 +25,9 @@ public sealed class StateBoundaryStore(IKeyValueStore kv, ILogManager? logManage private readonly ILogger _logger = logManager?.GetClassLogger() ?? default; private readonly Lock _lock = new(); - private long? _value = kv[OldestStateBlockKey]?.AsRlpValueContext().DecodeLong(); + private ulong? _value = kv[OldestStateBlockKey]?.AsRlpValueContext().DecodeULong(); - public long? OldestStateBlock + public ulong? OldestStateBlock { get { diff --git a/src/Nethermind/Nethermind.State/WorldStateManager.cs b/src/Nethermind/Nethermind.State/WorldStateManager.cs index 08b7370fc830..5d1e7cb0c415 100644 --- a/src/Nethermind/Nethermind.State/WorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/WorldStateManager.cs @@ -54,7 +54,7 @@ public WorldStateManager( public ulong? RetentionWindowBlocks { get; } - public long? OldestStateBlock + public ulong? OldestStateBlock { get => _boundaryStore.OldestStateBlock; set => _boundaryStore.OldestStateBlock = value; diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/PatriciaTreeSyncStore.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/PatriciaTreeSyncStore.cs index 6c309b3f6bd1..1b97ec35a2ec 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/PatriciaTreeSyncStore.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/PatriciaTreeSyncStore.cs @@ -25,7 +25,7 @@ public void FinalizeSync(BlockHeader pivotHeader) { nodeStorage.Flush(onlyWal: false); // Records the floor reported through eth_capabilities. - stateBoundary.OldestStateBlock = (long)pivotHeader.Number; + stateBoundary.OldestStateBlock = pivotHeader.Number; } public ITreeSyncVerificationContext CreateVerificationContext(byte[] rootNodeData) => From d04b5a4f0fa8f381dd3507e96d6fc9a6b975b31f Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 18 Jun 2026 17:41:32 +0530 Subject: [PATCH 27/60] refactor: unify block number, nonce, and gas types to unsigned types --- .../BlockchainProcessorTests.cs | 2 +- .../Eip8037BlockGasIntegrationTests.cs | 6 +- .../Find/LogFinderTests.cs | 32 +++++------ .../BlockProducerBaseTests.BaseFee.cs | 8 +-- .../Validators/HeaderValidatorTests.cs | 55 +++++-------------- .../Visitors/StartupTreeFixerTests.cs | 38 ++++++------- 6 files changed, 56 insertions(+), 85 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs index 025601bb7daf..93ce20314d87 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs @@ -534,7 +534,7 @@ public ProcessingTestContext Sleep(int milliseconds) public ProcessingTestContext AssertProcessedBlocks(params IEnumerable blocks) { - Assert.That(_branchProcessor.Processed, Is.EquivalentTo(blocks.Select(b => b.Hash))); + Assert.That(_branchProcessor.Processed, Is.EqualTo(blocks.Select(b => b.Hash))); return this; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs index 50374787ef40..3e530b9d0a4c 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Eip8037BlockGasIntegrationTests.cs @@ -34,8 +34,8 @@ namespace Nethermind.Blockchain.Test; [Parallelizable(ParallelScope.All)] public class Eip8037BlockGasIntegrationTests { - private const long Cpsb = 1530; - private const long IntrinsicNewAccountState = 120 * Cpsb; + private const ulong Cpsb = 1530ul; + private const ulong IntrinsicNewAccountState = 120ul * Cpsb; private static BlockAccessListManager CreateAmsterdamBalManager() { @@ -153,7 +153,7 @@ public void Eip8037_creation_tx_state_check_exceeded_rejects() GasValidationResultSlot[] results = ResultsForCount(2); results[0].TrySetResult(GasResult(block, 0, 50_000ul, 100_000ul)); // filler post-exec // Simulate creation tx ran with modest actual gas - spec would have rejected at inclusion. - results[1].TrySetResult(GasResult(block, 1, 53_000ul, (ulong)IntrinsicNewAccountState)); + results[1].TrySetResult(GasResult(block, 1, 53_000ul, IntrinsicNewAccountState)); Assert.Throws(() => mgr.IncrementalValidation(block, results, new BlockReceiptsTracer[2], null, CancellationToken.None), diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs index bc90c63a0d9a..605133d41925 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Find/LogFinderTests.cs @@ -278,67 +278,67 @@ public async Task Throw_log_finder_operation_canceled_after_given_timeout([Value } [TestCase("Empty index", - 1, 2, + 1UL, 2UL, null, null, null, null )] [TestCase("No intersection, left", - 1, 2, + 1UL, 2UL, 4, 6, null, null )] [TestCase("No intersection, adjacent left", - 1, 3, + 1UL, 3UL, 4, 6, null, null )] [TestCase("1 block intersection, left", - 1, 4, + 1UL, 4UL, 4, 6, 4, 4 )] [TestCase("Partial intersection, left", - 1, 5, + 1UL, 5UL, 4, 6, 4, 5 )] [TestCase("Full containment, border right", - 1, 6, + 1UL, 6UL, 4, 6, 4, 6 )] [TestCase("Full containment", - 1, 9, + 1UL, 9UL, 4, 6, 4, 6 )] [TestCase("Full containment, border left", - 4, 9, + 4UL, 9UL, 4, 6, 4, 6 )] [TestCase("Partial intersection, right", - 5, 9, + 5UL, 9UL, 4, 6, 5, 6 )] [TestCase("1 block intersection, right", - 6, 9, + 6UL, 9UL, 4, 6, 6, 6 )] [TestCase("No intersection, adjacent right", - 7, 9, + 7UL, 9UL, 4, 6, null, null )] [TestCase("No intersection, right", - 8, 9, + 8UL, 9UL, 4, 6, null, null )] public void query_intersected_range_from_log_index(string name, - int from, int to, + ulong from, ulong to, int? indexFrom, int? indexTo, int? exFrom, int? exTo ) @@ -353,10 +353,10 @@ public void query_intersected_range_from_log_index(string name, .Returns(_ => Array.Empty().Cast().GetEnumerator()); Address address = TestItem.AddressA; - BlockHeader fromHeader = Build.A.BlockHeader.WithNumber((ulong)from).TestObject; - BlockHeader toHeader = Build.A.BlockHeader.WithNumber((ulong)to).TestObject; + BlockHeader fromHeader = Build.A.BlockHeader.WithNumber(from).TestObject; + BlockHeader toHeader = Build.A.BlockHeader.WithNumber(to).TestObject; LogFilter filter = FilterBuilder.New() - .FromBlock((ulong)from).ToBlock((ulong)to) + .FromBlock(from).ToBlock(to) .WithAddress(address) .Build(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs index 06f8e1ab5ed8..02178abb7a5b 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.BaseFee.cs @@ -104,16 +104,16 @@ private async Task DeployContractAsync() public ScenarioBuilder SendEip1559Transaction(ulong gasLimit = 1000000ul, UInt256? gasPremium = null, UInt256? feeCap = null, bool serviceTransaction = false) { - _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, feeCap ?? UInt256.Zero, serviceTransaction); + _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, (ulong)(feeCap ?? UInt256.Zero), serviceTransaction); return this; } public ScenarioBuilder SendLegacyTransaction(ulong gasLimit = 1000000ul, UInt256? gasPremium = null, bool serviceTransaction = false, ulong? nonce = null) { - _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, UInt256.Zero, serviceTransaction, nonce); + _antecedent = SendTransactionAsync(gasLimit, gasPremium ?? 20.GWei, 0UL, serviceTransaction, nonce); return this; } - private async Task SendTransactionAsync(ulong gasLimit, UInt256 gasPrice, UInt256 feeCap, bool serviceTransaction, ulong? nonce = null) + private async Task SendTransactionAsync(ulong gasLimit, UInt256 gasPrice, ulong feeCap, bool serviceTransaction, ulong? nonce = null) { await ExecuteAntecedentIfNeeded(); byte[] txData = _abiEncoder.Encode( @@ -127,7 +127,7 @@ private async Task SendTransactionAsync(ulong gasLimit, UInt256 SenderAddress = _address, GasLimit = gasLimit, GasPrice = gasPrice, - DecodedMaxFeePerGas = (ulong)feeCap, + DecodedMaxFeePerGas = feeCap, Nonce = nonce ?? _currentNonce++, IsServiceTransaction = serviceTransaction }; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index a0772cd50f0f..662b82772c24 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -76,31 +76,22 @@ public void Valid_when_valid() } [MaxTime(Timeout.MaxTestTime)] - [TestCase(0, false, TestName = "When_gas_limit_too_high")] - [TestCase(-1, true, TestName = "When_gas_limit_just_correct_high")] - public void When_gas_limit_above_parent(int adjustment, bool expectedResult) + [TestCase(1, false, TestName = "When_gas_limit_too_high")] + [TestCase(0, true, TestName = "When_gas_limit_just_correct_high")] + [TestCase(-1, true, TestName = "When_gas_limit_just_correct_low")] + [TestCase(-2, false, TestName = "When_gas_limit_is_just_too_low")] + public void When_gas_limit_is_adjusted_around_parent(int boundaryIndex, bool expectedResult) { ulong delta = _parentBlock.Header.GasLimit / 1024ul; - _block.Header.GasLimit = adjustment >= 0 - ? _parentBlock.Header.GasLimit + delta + (ulong)adjustment - : _parentBlock.Header.GasLimit + delta - (ulong)(-adjustment); - _block.Header.Hash = _block.CalculateHash(); - - bool result = _validator.Validate(_block.Header, _parentBlock.Header); - Assert.That(result, Is.EqualTo(expectedResult)); - } - - [MaxTime(Timeout.MaxTestTime)] - [TestCase(1, true, TestName = "When_gas_limit_just_correct_low")] - [TestCase(0, false, TestName = "When_gas_limit_is_just_too_low")] - public void When_gas_limit_below_parent(int adjustment, bool expectedResult) - { - ulong delta = _parentBlock.Header.GasLimit / 1024ul; - - _block.Header.GasLimit = adjustment >= 0 - ? _parentBlock.Header.GasLimit - delta + (ulong)adjustment - : _parentBlock.Header.GasLimit - delta - (ulong)(-adjustment); + _block.Header.GasLimit = boundaryIndex switch + { + 1 => _parentBlock.Header.GasLimit + delta, + 0 => _parentBlock.Header.GasLimit + delta - 1ul, + -1 => _parentBlock.Header.GasLimit - delta + 1ul, + -2 => _parentBlock.Header.GasLimit - delta, + _ => throw new ArgumentOutOfRangeException(nameof(boundaryIndex)) + }; _block.Header.Hash = _block.CalculateHash(); bool result = _validator.Validate(_block.Header, _parentBlock.Header); @@ -258,26 +249,6 @@ public void When_gas_limit_is_long_max_value() Assert.That(result, Is.True); } - private static IEnumerable NegativeFieldCases() - { - yield return new TestCaseData(new Action(b => b.Header.Number = unchecked((ulong)-1))) - .SetName("When_block_number_is_negative"); - yield return new TestCaseData(new Action(b => b.Header.GasUsed = unchecked((ulong)-1))) - .SetName("When_gas_used_is_negative"); - yield return new TestCaseData(new Action(b => b.Header.GasLimit = unchecked((ulong)-1))) - .SetName("When_gas_limit_is_negative"); - } - - [MaxTime(Timeout.MaxTestTime)] - [TestCaseSource(nameof(NegativeFieldCases))] - public void When_header_field_is_negative(Action corrupt) - { - corrupt(_block); - _block.Header.Hash = _block.CalculateHash(); - - bool result = _validator.Validate(_block.Header, _parentBlock.Header); - Assert.That(result, Is.False); - } [Test, MaxTime(Timeout.MaxTestTime)] public void When_total_difficulty_null_we_should_skip_total_difficulty_validation() diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs index fa8afaef3ef1..1d02990b1d90 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Visitors/StartupTreeFixerTests.cs @@ -85,14 +85,14 @@ public async Task Deletes_everything_after_the_missing_level() } [MaxTime(Timeout.MaxTestTime * 4)] - [TestCase(0)] - [TestCase(1)] - [TestCase(2)] - [TestCase(4)] - [TestCase(5)] - [TestCase(6)] - [TestCase(65)] - public async Task Suggesting_blocks_works_correctly_after_processor_restart(int suggestedBlocksAmount) + [TestCase(0ul)] + [TestCase(1ul)] + [TestCase(2ul)] + [TestCase(4ul)] + [TestCase(5ul)] + [TestCase(6ul)] + [TestCase(65ul)] + public async Task Suggesting_blocks_works_correctly_after_processor_restart(ulong suggestedBlocksAmount) { TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev, testTimeout: Timeout.MaxTestTime * 4).Build(); await testRpc.BlockchainProcessor.StopAsync(); @@ -101,8 +101,8 @@ public async Task Suggesting_blocks_works_correctly_after_processor_restart(int SuggestNumberOfBlocks(tree, suggestedBlocksAmount); - Task waitTask = suggestedBlocksAmount != 0 - ? testRpc.WaitForNewHeadWhere(b => b.Number == startingBlockNumber + (ulong)suggestedBlocksAmount) + Task waitTask = suggestedBlocksAmount != 0ul + ? testRpc.WaitForNewHeadWhere(b => b.Number == startingBlockNumber + suggestedBlocksAmount) : Task.CompletedTask; await testRpc.RestartBlockchainProcessor(); @@ -113,15 +113,15 @@ public async Task Suggesting_blocks_works_correctly_after_processor_restart(int await waitTask; await testRpc.AddBlock(); - Assert.That(tree.Head!.Number, Is.EqualTo(startingBlockNumber + (ulong)suggestedBlocksAmount + 1ul)); + Assert.That(tree.Head!.Number, Is.EqualTo(startingBlockNumber + suggestedBlocksAmount + 1ul)); } [MaxTime(Timeout.MaxTestTime)] - [TestCase(0)] - [TestCase(1)] - [TestCase(2)] - [TestCase(6)] - public async Task Fixer_should_not_suggest_block_without_state(int suggestedBlocksAmount) + [TestCase(0ul)] + [TestCase(1ul)] + [TestCase(2ul)] + [TestCase(6ul)] + public async Task Fixer_should_not_suggest_block_without_state(ulong suggestedBlocksAmount) { TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(); await testRpc.BlockchainProcessor.StopAsync(); @@ -145,7 +145,7 @@ public async Task Fixer_should_not_suggest_block_with_null_block() await testRpc.BlockchainProcessor.StopAsync(); IBlockTree tree = testRpc.BlockTree; - SuggestNumberOfBlocks(tree, 1); + SuggestNumberOfBlocks(tree, 1ul); await testRpc.RestartBlockchainProcessor(); @@ -155,10 +155,10 @@ public async Task Fixer_should_not_suggest_block_with_null_block() Assert.That(result, Is.EqualTo(BlockVisitOutcome.None)); } - private static void SuggestNumberOfBlocks(IBlockTree blockTree, int blockAmount) + private static void SuggestNumberOfBlocks(IBlockTree blockTree, ulong blockAmount) { Block newParent = blockTree.Head!; - for (int i = 0; i < blockAmount; ++i) + for (ulong i = 0ul; i < blockAmount; ++i) { Block newBlock = Build.A.Block .WithNumber(newParent.Number + 1) From ebea5d0b79edb2194c68557858dfdb769ffa5ca1 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Thu, 18 Jun 2026 18:43:19 +0530 Subject: [PATCH 28/60] refactor: unify block number, nonce, and gas types to unsigned types --- .../BlockTree.Healing.cs | 2 +- .../Nethermind.Blockchain/BlockTree.cs | 25 +++++++++++-------- .../Visitors/StartupBlockTreeFixer.cs | 6 ++--- .../CliqueBlockProducerTests.cs | 12 ++++----- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs index e9117d07245d..485a51392418 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.Healing.cs @@ -20,7 +20,7 @@ public void HealCanonicalChain(Hash256 startHash, long maxBlockDepth) using BatchWrite batch = _chainLevelInfoRepository.StartBatch(); - long repairedAbove = ClearStaleMarkersAbove(start.Number, batch); // start.Number is ulong (BlockHeader) + long repairedAbove = ClearStaleMarkersAbove(start.Number, batch); long repairedBelow = RepairMarkersBelow(start, maxBlockDepth, batch); if (Logger.IsInfo) Logger.Info($"Canonical chain heal complete: {repairedAbove + repairedBelow} level(s) repaired ({repairedAbove} stale above head cleared, {repairedBelow} incorrect markers fixed)."); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 3f16cbf84592..cc38a45b5591 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -130,7 +130,7 @@ public BlockTree( _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); _chainLevelInfoRepository = chainLevelInfoRepository ?? throw new ArgumentNullException(nameof(chainLevelInfoRepository)); - _oldestBlock = (ulong)syncConfig.AncientBodiesBarrierCalc; + _oldestBlock = syncConfig.AncientBodiesBarrierCalc; _genesisBlockNumber = genesisBlockNumber; @@ -684,19 +684,27 @@ as it does not require the step of resolving number -> hash */ ArrayPoolList result = new(numberOfBlocks, numberOfBlocks); BlockHeader current = startHeader; - int directionMultiplier = reverse ? -1 : 1; int responseIndex = 0; do { result[responseIndex] = current; responseIndex++; - long nextNumber = (long)startHeader.Number + directionMultiplier * (responseIndex * skip + responseIndex); - if (nextNumber < 0) + ulong offset = (ulong)responseIndex * ((ulong)skip + 1ul); + ulong nextNumber; + if (reverse) { - break; + if (startHeader.Number < offset) + { + break; + } + nextNumber = startHeader.Number - offset; + } + else + { + nextNumber = startHeader.Number + offset; } - current = FindHeader((ulong)nextNumber, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + current = FindHeader(nextNumber, BlockTreeLookupOptions.TotalDifficultyNotNeeded); } while (current is not null && responseIndex < numberOfBlocks); return result; @@ -837,10 +845,7 @@ private void DeleteBlocks(Hash256 deletePointer) if (shouldRemoveLevel) { - // Guard against underflow: currentNumber is ulong, so only subtract if > 0 - BestKnownNumber = currentNumber > 0 - ? Math.Min(BestKnownNumber, currentNumber - 1) - : 0; + BestKnownNumber = Math.Min(BestKnownNumber, currentNumber.SaturatingSub(1ul)); _chainLevelInfoRepository.Delete(currentNumber, batch); } else if (currentLevel is not null) diff --git a/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs b/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs index 45f74bf3ff2f..2de701f44582 100644 --- a/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs +++ b/src/Nethermind/Nethermind.Blockchain/Visitors/StartupBlockTreeFixer.cs @@ -168,14 +168,14 @@ async Task IBlockTreeVisitor.VisitBlock(Block block, Cancella Task IBlockTreeVisitor.VisitLevelEnd(ChainLevelInfo chainLevelInfo, ulong levelNumber, CancellationToken cancellationToken) { - int expectedVisitedBlocksCount = _currentLevel?.BlockInfos.Length ?? 0; - if (_blocksCheckedInCurrentLevel != (ulong)expectedVisitedBlocksCount) + ulong expectedVisitedBlocksCount = (ulong)(_currentLevel?.BlockInfos.Length ?? 0); + if (_blocksCheckedInCurrentLevel != expectedVisitedBlocksCount) { throw new InvalidDataException( $"Some blocks have not been visited at level {_currentLevelNumber}: {_blocksCheckedInCurrentLevel}/{expectedVisitedBlocksCount}"); } - if (_bodiesInCurrentLevel > (ulong)expectedVisitedBlocksCount) + if (_bodiesInCurrentLevel > expectedVisitedBlocksCount) { throw new InvalidOperationException( $"Invalid bodies count at level {_currentLevelNumber}: {_bodiesInCurrentLevel}/{expectedVisitedBlocksCount}"); diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index bad2d7d93458..264514c53d4f 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -864,22 +864,22 @@ public async Task Many_validators_can_process_blocks() .AssertHeadBlockIs(keys[i], 1); } - for (int i = 1; i <= 10; i++) + for (ulong i = 1ul; i <= 10ul; i++) { - PrivateKey inTurnKey = keys[i % 3]; - goerli.AddPendingTransaction(keys[(i + 1) % 3]); + PrivateKey inTurnKey = keys[(int)(i % 3ul)]; + goerli.AddPendingTransaction(keys[(int)((i + 1ul) % 3ul)]); for (int j = 0; j < keys.Length; j++) { PrivateKey nodeKey = keys[j]; if (!nodeKey.Equals(inTurnKey)) { - goerli.Process(nodeKey, goerli.GetBlock(inTurnKey, (ulong)i)); - goerli.AssertHeadBlockIs(keys[j], (ulong)(i + 1)); + goerli.Process(nodeKey, goerli.GetBlock(inTurnKey, i)); + goerli.AssertHeadBlockIs(keys[j], i + 1ul); goerli.AssertHeadBlockTimestamp(keys[j]); } else { - goerli.AssertHeadBlockIs(keys[j], (ulong)i); + goerli.AssertHeadBlockIs(keys[j], i); goerli.AssertHeadBlockTimestamp(keys[j]); } } From e709a025e5411f824bab714597e9ea013b065e95 Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Fri, 19 Jun 2026 02:15:21 +0530 Subject: [PATCH 29/60] refactor: geth type unification and unsigned overflow/underflow fixes --- .../Receipts/PersistentReceiptStorageTests.cs | 12 ++++++------ .../Nethermind.Blockchain/Receipts/IReceiptConfig.cs | 4 ++-- .../Receipts/PersistentReceiptStorage.cs | 10 ++++------ .../Nethermind.Blockchain/Receipts/ReceiptConfig.cs | 2 +- .../Nethermind.Config/ConfigSourceHelper.cs | 12 ++++++++++++ .../Steps/Migrations/ReceiptMigration.cs | 6 +++--- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs index 42ee668e135f..270a2ed628d6 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Receipts/PersistentReceiptStorageTests.cs @@ -305,9 +305,9 @@ public void EnsureCanonical_should_use_blockNumber_if_finalized() } [Test] - public void When_TxLookupLimitIs_NegativeOne_DoNotIndexTxHash() + public void When_TxLookupLimitIs_MaxValue_DoNotIndexTxHash() { - _receiptConfig.TxLookupLimit = -1; + _receiptConfig.TxLookupLimit = ulong.MaxValue; CreateStorage(); (Block block, TxReceipt[] receipts) = InsertBlock(isFinalized: true); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(block)); @@ -319,7 +319,7 @@ public void When_TxLookupLimitIs_NegativeOne_DoNotIndexTxHash() [TestCase(11ul, true)] public void Should_only_prune_index_tx_hashes_if_blockNumber_is_bigger_than_lookupLimit(ulong blockNumber, bool willPruneOldIndices) { - _receiptConfig.TxLookupLimit = 10; + _receiptConfig.TxLookupLimit = 10ul; CreateStorage(); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(Build.A.Block.WithNumber(blockNumber).TestObject)); @@ -331,7 +331,7 @@ public void Should_only_prune_index_tx_hashes_if_blockNumber_is_bigger_than_look [Test] public void When_HeadBlockIsFarAhead_DoNotIndexTxHash() { - _receiptConfig.TxLookupLimit = 1000; + _receiptConfig.TxLookupLimit = 1000ul; CreateStorage(); (Block block, TxReceipt[] receipts) = InsertBlock(isFinalized: true, headNumber: 1001ul); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(block)); @@ -423,7 +423,7 @@ public async Task When_NewHeadBlock_Remove_TxIndex_OfRemovedBlock_Unless_ItsAlso [Test] public void When_NewHeadBlock_ClearOldTxIndex_And_KeepsReceipts() { - _receiptConfig.TxLookupLimit = 1000; + _receiptConfig.TxLookupLimit = 1000ul; CreateStorage(); (Block block, TxReceipt[] receipts) = InsertBlock(); @@ -437,7 +437,7 @@ public void When_NewHeadBlock_ClearOldTxIndex_And_KeepsReceipts() Assert.That(_receiptsDb.GetColumnDb(ReceiptsColumns.Transactions)[txHashBytes], Is.Not.Null); } - Block newHead = Build.A.Block.WithNumber((ulong)_receiptConfig.TxLookupLimit.Value + 1ul).TestObject; + Block newHead = Build.A.Block.WithNumber(_receiptConfig.TxLookupLimit.Value + 1ul).TestObject; _blockTree.FindBestSuggestedHeader().Returns(newHead.Header); _blockTree.BlockAddedToMain += Raise.EventWith(new BlockReplacementEventArgs(newHead)); diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptConfig.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptConfig.cs index f5729d991540..75ab89652b0b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/IReceiptConfig.cs @@ -25,8 +25,8 @@ public interface IReceiptConfig : IConfig [ConfigItem(Description = "Whether to compact receipts transaction index database size at the expense of RPC performance.", DefaultValue = "true")] bool CompactTxIndex { get; set; } - [ConfigItem(Description = "The number of recent blocks to maintain transaction index for. `0` to never remove indices, `-1` to never index.", DefaultValue = "2350000")] - long? TxLookupLimit { get; set; } + [ConfigItem(Description = "The number of recent blocks to maintain transaction index for. `0` to never remove indices, `18446744073709551615` to never index.", DefaultValue = "2350000")] + ulong? TxLookupLimit { get; set; } [ConfigItem(Description = "The max number of blocks per `eth_getLogs` request.", DefaultValue = "10000", HiddenFromDocs = true)] int MaxBlockDepth { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs index 4eb6d386f2cb..50882ac009ba 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs @@ -82,10 +82,9 @@ private void BlockTreeOnBlockAddedToMain(object? sender, BlockReplacementEventAr Block newMain = e.Block; // Delete old tx index - // safe: TxLookupLimit is checked to be > 0, so it is safe to cast to ulong - if (_receiptConfig.TxLookupLimit > 0 && newMain.Number > (ulong)_receiptConfig.TxLookupLimit.Value) + if (_receiptConfig.TxLookupLimit > 0ul && newMain.Number > _receiptConfig.TxLookupLimit.Value) { - Block newOldTx = _blockTree.FindBlock(newMain.Number - (ulong)_receiptConfig.TxLookupLimit.Value); + Block newOldTx = _blockTree.FindBlock(newMain.Number - _receiptConfig.TxLookupLimit.Value); if (newOldTx is not null) { RemoveBlockTx(newOldTx); @@ -368,9 +367,8 @@ private void EnsureCanonical(Block block, ulong? lastBlockNumber) lastBlockNumber ??= _blockTree.FindBestSuggestedHeader()?.Number ?? 0UL; - if (_receiptConfig.TxLookupLimit == -1) return; - // safe: TxLookupLimit != 0 and the -1 case is already handled above, so it is safe to cast to ulong - if (_receiptConfig.TxLookupLimit != 0 && lastBlockNumber.Value >= (ulong)_receiptConfig.TxLookupLimit && block.Number <= lastBlockNumber.Value - (ulong)_receiptConfig.TxLookupLimit) return; + if (_receiptConfig.TxLookupLimit == ulong.MaxValue) return; + if (_receiptConfig.TxLookupLimit != 0ul && lastBlockNumber.Value >= _receiptConfig.TxLookupLimit.Value && block.Number <= lastBlockNumber.Value - _receiptConfig.TxLookupLimit.Value) return; if (_receiptConfig.CompactTxIndex) { byte[] blockNumber = Rlp.Encode(block.Number).Bytes; diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptConfig.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptConfig.cs index fe7c36fa1213..217d8834c502 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/ReceiptConfig.cs @@ -11,6 +11,6 @@ public class ReceiptConfig : IReceiptConfig public bool ForceReceiptsMigration { get; set; } = false; public bool CompactReceiptStore { get; set; } = true; public bool CompactTxIndex { get; set; } = true; - public long? TxLookupLimit { get; set; } = 2350000; + public ulong? TxLookupLimit { get; set; } = 2350000ul; public int MaxBlockDepth { get; set; } = 10000; } diff --git a/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs b/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs index 352044728173..1905b3df021a 100644 --- a/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs +++ b/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs @@ -161,6 +161,18 @@ private static bool TryFromHex(Type type, string itemValue, out object? value) : throw new FormatException($"Cannot parse enum value: {itemValue}, type: {valueType.Name}"); } + if (valueType == typeof(ulong)) + { + if (long.TryParse(itemValue, out long longVal)) + { + return unchecked((ulong)longVal); + } + if (ulong.TryParse(itemValue, out ulong ulongVal)) + { + return ulongVal; + } + } + return TryFromHex(valueType, itemValue, out object? value) ? value : Convert.ChangeType(itemValue, valueType); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs index dbc7cfab4561..19975cef6756 100644 --- a/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs +++ b/src/Nethermind/Nethermind.Init/Steps/Migrations/ReceiptMigration.cs @@ -298,11 +298,11 @@ private void MigrateBlock(Block block) // Guarded: block.Number can transiently exceed head during reorgs. ulong? headNumber = _blockTree.Head?.Number; - bool txIndexExpired = _receiptConfig.TxLookupLimit > 0 + bool txIndexExpired = _receiptConfig.TxLookupLimit > 0ul && headNumber is ulong h && h > block.Number - && h - block.Number > (ulong)_receiptConfig.TxLookupLimit.Value; - bool neverIndexTx = _receiptConfig.TxLookupLimit == -1; + && h - block.Number > _receiptConfig.TxLookupLimit.Value; + bool neverIndexTx = _receiptConfig.TxLookupLimit == ulong.MaxValue; if (neverIndexTx || txIndexExpired) { using IWriteBatch writeBatch = _txIndexDb.StartWriteBatch(); From 2e70f2d897a96e03841f664723dff52283d27aa7 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 10:15:52 +0200 Subject: [PATCH 30/60] fix(json): chainspec hex parsing rejecting valid leading-zero forms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PR's added "0x0…" rejection in NumericConverterHelper.Parse breaks ChainSpec loading: gasLimitBoundDivisor and similar fields are written as "0x0400" in real chainspec JSON. Tests across AuRa, JsonRpc, Specs, Runner, Blockchain and Merge.Plugin fail with "Error when loading chainspec (hex to UInt64)". Match master's lax behavior — accept "0x0XXX" in the chainspec parse path. EIP-1474 JSON-RPC strictness for leading zeros is enforced separately at the RPC entry layer (BlockParameter etc.) and is unaffected by this change. Also drop unused `using System;` in BeaconPivot.cs (lint IDE0005). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Synchronization/BeaconPivot.cs | 1 - .../NumericConverterHelper.cs | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index 8e35eef751d1..875670d9ffb4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Autofac.Features.AttributeFilters; using Nethermind.Blockchain; using Nethermind.Blockchain.Synchronization; diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index a04c83165ee4..27c89663beee 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -20,6 +20,12 @@ public static class NumericConverterHelper /// /// Parse a UTF-8 span that may be hex ("0x...") or decimal into . /// + /// + /// Lax with respect to leading zeros in the hex form — chainspec JSON values (e.g. + /// 0x0400 for gasLimitBoundDivisor) and stored receipts use non-canonical + /// encodings that must round-trip. JSON-RPC strictness is enforced separately at the + /// RPC entry point. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Parse(ReadOnlySpan s) where T : struct, INumberBase { @@ -33,11 +39,6 @@ public static T Parse(ReadOnlySpan s) where T : struct, INumberBase return T.Zero; } - if (s.StartsWith("0x0"u8)) - { - ThrowHexConversion(typeof(T).Name); - } - if (s.StartsWith("0x"u8)) { s = s[2..]; From 151f170ceb653e4442cbb526f88c1f5f3ddff6fb Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 10:17:52 +0200 Subject: [PATCH 31/60] nit(json): strip remarks block on NumericConverterHelper.Parse Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.Serialization.Json/NumericConverterHelper.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index 27c89663beee..8e9d657eaf19 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -20,12 +20,6 @@ public static class NumericConverterHelper /// /// Parse a UTF-8 span that may be hex ("0x...") or decimal into . /// - /// - /// Lax with respect to leading zeros in the hex form — chainspec JSON values (e.g. - /// 0x0400 for gasLimitBoundDivisor) and stored receipts use non-canonical - /// encodings that must round-trip. JSON-RPC strictness is enforced separately at the - /// RPC entry point. - /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Parse(ReadOnlySpan s) where T : struct, INumberBase { From cee81baab48ae6ea08c7e8271e7bd2c366a7f3f5 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 10:47:59 +0200 Subject: [PATCH 32/60] fix(evm): restore signed-refund semantics so EIP-2200/3529 sub-below-zero matches master MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Master computes totalRefund / claimableRefund as signed long. A negative refund (legitimate per EIP-2200 net metering) feeds into `operationGas = spentGas - refund` as `spentGas + |refund|`. The PR's ulong wrap broke this — the cap picked the quotient and operationGas underflowed, producing the wrong stateless witness on test_sstore_call_to_self_sub_refund_below_zero. CalculateSpentGasAndRefund now returns (ulong spentGas, long refund); the caller dispatches the subtraction on the sign. VmState.Refund stays ulong. Also drops the three Throws_on_leading_zeros tests that were asserting the chainspec-breaking strict hex path I reverted in the previous commit. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Json/LongConverterTests.cs | 4 ---- .../Json/NullableLongConverterTests.cs | 4 ---- .../Json/NullableULongConverterTests.cs | 4 ---- .../TransactionProcessing/TransactionProcessor.cs | 15 +++++++++------ 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs index 7f0883d3b0cc..286f7c76fd04 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/LongConverterTests.cs @@ -30,10 +30,6 @@ public void Can_read_value(string json, long expected) Assert.That(result, Is.EqualTo(expected)); } - [TestCase("\"0x0000\"")] - public void Throws_on_leading_zeros(string json) => Assert.Throws( - () => JsonSerializer.Deserialize(json, options)); - [Test] public void Throws_on_null() => Assert.Throws( static () => JsonSerializer.Deserialize("null", options)); diff --git a/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs index 146faa6e5089..043dbbc6929e 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/NullableLongConverterTests.cs @@ -33,10 +33,6 @@ public void Can_read_value(string json, long expected) Assert.That(result, Is.EqualTo(expected)); } - [TestCase("\"0x0000\"")] - public void Throws_on_leading_zeros(string json) => Assert.Throws( - () => JsonSerializer.Deserialize(json, options)); - [Test] public void Can_read_null() { diff --git a/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs index 38e9254f5573..7b40f1bf27a1 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/NullableULongConverterTests.cs @@ -30,10 +30,6 @@ public void Can_read_value(string json, ulong expected) Assert.That(result, Is.EqualTo(expected)); } - [TestCase("\"0x000\"")] - public void Throws_on_leading_zeros(string json) => Assert.Throws( - () => JsonSerializer.Deserialize(json, options)); - [Test] public void Can_read_null() { diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 94b675f39765..1902d8481033 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -1564,10 +1564,12 @@ protected virtual GasConsumed Refund(Transaction tx, BlockHeader header, IReleas return CompleteEip8037Halt(tx, spec, opts, ref gasAfterExecution, in gasPrice, in intrinsicGasStandard, floorGasLong, postIntrinsicStateReservoir); } - (ulong spentGas, ulong refund) = CalculateSpentGasAndRefund(tx, spec, in substate, in gasAfterExecution, codeInsertRegularRefund); + (ulong spentGas, long refund) = CalculateSpentGasAndRefund(tx, spec, in substate, in gasAfterExecution, codeInsertRegularRefund); (ulong blockGas, ulong blockStateGas) = CalculateBlockGas(spec, in substate, in gasAfterExecution, in intrinsicGasStandard, spentGas, floorGasLong, tx.GasLimit); - ulong operationGas = spentGas - refund; + ulong operationGas = refund >= 0 + ? spentGas - (ulong)refund + : spentGas + (ulong)(-refund); ulong spentGasAfterFloor = Math.Max(operationGas, floorGasLong); if (ShouldRefundGas(tx, opts, in gasPrice)) @@ -1601,7 +1603,7 @@ private static ulong CalculateInitialStateReservoir( return txGasLimit.SaturatingSub(totalCap); } - private (ulong spentGas, ulong refund) CalculateSpentGasAndRefund( + private (ulong spentGas, long refund) CalculateSpentGasAndRefund( Transaction tx, IReleaseSpec spec, in TransactionSubstate substate, @@ -1612,11 +1614,12 @@ private static ulong CalculateInitialStateReservoir( ? tx.GasLimit : tx.GasLimit - TGasPolicy.GetRemainingGas(in gasAfterExecution) - TGasPolicy.GetStateReservoir(in gasAfterExecution); - ulong totalToRefund = codeInsertRegularRefund; + long totalToRefund = (long)codeInsertRegularRefund; if (!substate.IsError && !substate.ShouldRevert) - totalToRefund += substate.Refund + (ulong)(substate.DestroyList?.Count ?? 0) * spec.GasCosts.DestroyRefund; + totalToRefund += unchecked((long)substate.Refund) + (substate.DestroyList?.Count ?? 0) * (long)spec.GasCosts.DestroyRefund; - return (spentGas, CalculateClaimableRefund(spentGas, totalToRefund, spec)); + long quotient = spec.IsEip3529Enabled ? (long)RefundHelper.MaxRefundQuotientEIP3529 : (long)RefundHelper.MaxRefundQuotient; + return (spentGas, Math.Min((long)(spentGas / (ulong)quotient), totalToRefund)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] From a8b96c101de3944b364971041ecc2b0263901cba Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 12:01:34 +0200 Subject: [PATCH 33/60] fix(evm): VmState/Substate Refund back to signed long for EIP-2200/3529 net metering The PR's ulong Refund + 'wrap is fine, final cap saves it' theory is wrong: the SSTORE Refund -= sClearRefunds wrap is later observed by the refund cap `Math.Min(spentGas/quotient, totalRefund)` which, with ulong totalRefund, picks the quotient (max refund) instead of master's signed-long path that picks the negative `totalRefund` (less refund / more gas paid). Stateless witness on test_sstore_call_to_self_sub_refund_below_zero diverges by one byte. Match master: VmState.Refund and TransactionSubstate.Refund return to long, sClearRefunds / refundFromReversal locals cast to long at the boundary, totalToRefund/cap path is signed. The caller still works in ulong spentGas and dispatches on refund sign for the final subtract. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Instructions/EvmInstructions.Storage.cs | 26 +++++++------------ .../TransactionProcessor.cs | 6 ++--- .../Nethermind.Evm/TransactionSubstate.cs | 4 +-- src/Nethermind/Nethermind.Evm/VmState.cs | 2 +- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs index 86e732c46c10..9eca80a90657 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Nethermind.Core; @@ -392,7 +391,7 @@ internal static EvmExceptionType InstructionSStoreUnmetered= sClearRefunds. Saturating guards against an unsigned - // wrap silently granting the maximum post-cap refund. Consensus-relevant. - Debug.Assert(vmState.Refund >= sClearRefunds, - "EIP-2200/3529 refund accumulator went below the per-slot clear amount."); - vmState.Refund = vmState.Refund.SaturatingSub(sClearRefunds); + vmState.Refund -= sClearRefunds; if (vm.TxTracer.IsTracingRefunds) - vm.TxTracer.ReportRefund(-(long)sClearRefunds); + vm.TxTracer.ReportRefund(-sClearRefunds); } if (newIsZero) { vmState.Refund += sClearRefunds; if (vm.TxTracer.IsTracingRefunds) - vm.TxTracer.ReportRefund((long)sClearRefunds); + vm.TxTracer.ReportRefund(sClearRefunds); } } @@ -573,17 +567,17 @@ internal static EvmExceptionType InstructionSStoreMetered= 0 - ? spentGas - (ulong)refund - : spentGas + (ulong)(-refund); + ulong operationGas = refund >= 0 ? spentGas - (ulong)refund : spentGas + (ulong)(-refund); ulong spentGasAfterFloor = Math.Max(operationGas, floorGasLong); if (ShouldRefundGas(tx, opts, in gasPrice)) @@ -1616,7 +1614,7 @@ private static ulong CalculateInitialStateReservoir( long totalToRefund = (long)codeInsertRegularRefund; if (!substate.IsError && !substate.ShouldRevert) - totalToRefund += unchecked((long)substate.Refund) + (substate.DestroyList?.Count ?? 0) * (long)spec.GasCosts.DestroyRefund; + totalToRefund += substate.Refund + (substate.DestroyList?.Count ?? 0) * (long)spec.GasCosts.DestroyRefund; long quotient = spec.IsEip3529Enabled ? (long)RefundHelper.MaxRefundQuotientEIP3529 : (long)RefundHelper.MaxRefundQuotient; return (spentGas, Math.Min((long)(spentGas / (ulong)quotient), totalToRefund)); diff --git a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs index cbade3645376..8dc6547e2507 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs @@ -51,7 +51,7 @@ public readonly ref struct TransactionSubstate public EvmExceptionType EvmExceptionType { get; } public ReadOnlyMemory Output { get; } public bool ShouldRevert { get; } - public ulong Refund { get; } + public long Refund { get; } public JournalCollection Logs => _logs; public JournalSet
? DestroyList => _destroyList; @@ -68,7 +68,7 @@ public TransactionSubstate(EvmExceptionType exceptionType, bool isTracerConnecte } public TransactionSubstate(ReadOnlyMemory bytes, - ulong refund, + long refund, JournalSet
? destroyList, JournalCollection? logs, bool shouldRevert, diff --git a/src/Nethermind/Nethermind.Evm/VmState.cs b/src/Nethermind/Nethermind.Evm/VmState.cs index 6e143c88378f..58a71b221e69 100644 --- a/src/Nethermind/Nethermind.Evm/VmState.cs +++ b/src/Nethermind/Nethermind.Evm/VmState.cs @@ -33,7 +33,7 @@ public class VmState : IDisposable public ulong StateGasRefundAdvanced; internal long OutputDestination { get; private set; } // TODO: move to CallEnv internal long OutputLength { get; private set; } // TODO: move to CallEnv - public ulong Refund { get; set; } + public long Refund { get; set; } public int DataStackHead; public ExecutionType ExecutionType { get; private set; } // TODO: move to CallEnv public int ProgramCounter { get; set; } From d23ceae4110ac1e82adb43c706915c41473f8d4a Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 13:16:21 +0200 Subject: [PATCH 34/60] review: SaturatingSub for spill, drop redundant ParseLax / strict 0x0 checks - TransactionProcessor: ternary -> SaturatingSub on spill-not-in-reservoir. - NumericConverterHelper: drop ParseLax (functionally identical to Parse after the earlier strict-leading-zero revert) and the redundant "0x0"u8 fast-path. - LongConverter/ULongConverter: route ReadAsPropertyName via Parse and align FromString(string) with the span overload (no strict 0x0 rejection, no temp-buffer prefix dance). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../TransactionProcessor.cs | 2 +- .../LongConverter.cs | 18 ++-------- .../NumericConverterHelper.cs | 33 ------------------- .../ULongConverter.cs | 17 ++-------- 4 files changed, 5 insertions(+), 65 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 273b969d85ae..a558df17cbd3 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -1626,7 +1626,7 @@ private static ulong CalculateRefundedCreateStateSpillForHalt(in TGasPolicy gas) ulong stateReservoir = TGasPolicy.GetStateReservoir(in gas); ulong stateGasSpillBurned = TGasPolicy.GetStateGasSpillBurned(in gas); ulong totalSub = stateReservoir + stateGasSpillBurned; - ulong returnedSpillNotInReservoir = TGasPolicy.GetStateGasSpill(in gas) > totalSub ? TGasPolicy.GetStateGasSpill(in gas) - totalSub : 0UL; + ulong returnedSpillNotInReservoir = TGasPolicy.GetStateGasSpill(in gas).SaturatingSub(totalSub); ulong refundedSpill = TGasPolicy.GetStateGasSpillRefunded(in gas); ulong refundedSpillNotInReservoir = Math.Min(returnedSpillNotInReservoir, refundedSpill); ulong createStateGas = TGasPolicy.GetCreateStateCost(in gas); diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs index 870cad9a4f43..3dcc2cae7fde 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs @@ -9,7 +9,6 @@ using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; -using Nethermind.Core.Extensions; namespace Nethermind.Serialization.Json; @@ -22,22 +21,9 @@ public static long FromString(string s) throw new JsonException("null cannot be assigned to long"); } - if (s == Bytes.ZeroHexValue) - { - return 0L; - } - - if (s.StartsWith("0x0")) - { - throw new JsonException("hex to long"); - } - if (s.StartsWith("0x")) { - Span withZero = new(new char[s.Length - 1]); - withZero[0] = '0'; - s.AsSpan(2).CopyTo(withZero[1..]); - return long.Parse(withZero, NumberStyles.AllowHexSpecifier); + return long.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); } return long.Parse(s, NumberStyles.Integer); @@ -46,7 +32,7 @@ public static long FromString(string s) public override long ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - return NumericConverterHelper.ParseLax(hex); + return NumericConverterHelper.Parse(hex); } public static long FromString(ReadOnlySpan s) => NumericConverterHelper.Parse(s); diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index 8e9d657eaf19..0ed2b38c9ac7 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -28,39 +28,6 @@ public static T Parse(ReadOnlySpan s) where T : struct, INumberBase ThrowNullAssignment(typeof(T).Name); } - if (s.SequenceEqual("0x0"u8)) - { - return T.Zero; - } - - if (s.StartsWith("0x"u8)) - { - s = s[2..]; - if (T.TryParse(s, NumberStyles.AllowHexSpecifier, null, out T value)) - { - return value; - } - } - else if (T.TryParse(s, NumberStyles.Integer, null, out T value)) - { - return value; - } - - ThrowHexConversion(typeof(T).Name); - return default; - } - - /// - /// Parse a UTF-8 span that may be hex ("0x...") or decimal into without strict leading zero checks. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ParseLax(ReadOnlySpan s) where T : struct, INumberBase - { - if (s.Length == 0) - { - ThrowNullAssignment(typeof(T).Name); - } - if (s.StartsWith("0x"u8)) { s = s[2..]; diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index 1c17d3e3e986..e81c3ebc4bab 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -20,22 +20,9 @@ public static ulong FromString(string s) { ArgumentNullException.ThrowIfNull(s); - if (s == Nethermind.Core.Extensions.Bytes.ZeroHexValue) - { - return 0UL; - } - - if (s.StartsWith("0x0")) - { - throw new JsonException("hex to ulong"); - } - if (s.StartsWith("0x")) { - Span withZero = new(new char[s.Length - 1]); - withZero[0] = '0'; - s.AsSpan(2).CopyTo(withZero[1..]); - return ulong.Parse(withZero, NumberStyles.AllowHexSpecifier); + return ulong.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); } return ulong.Parse(s, NumberStyles.Integer); @@ -76,6 +63,6 @@ public override ulong Read( public override ulong ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - return NumericConverterHelper.ParseLax(hex); + return NumericConverterHelper.Parse(hex); } } From 492f8b0f9c87b09953157a6612b1762acf3d3f48 Mon Sep 17 00:00:00 2001 From: Lukasz Rozmej Date: Fri, 19 Jun 2026 13:24:56 +0200 Subject: [PATCH 35/60] Apply suggestions from code review Co-authored-by: Lukasz Rozmej --- .../Nethermind.Consensus/Processing/BlockchainProcessor.cs | 1 - .../Processing/CensorshipDetector/CensorshipDetector.cs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs index 587a8575df7f..f19a0e373b4a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs @@ -528,7 +528,6 @@ private void FireProcessingQueueEmpty() if (!readonlyChain) { - // Safe cast: block numbers fit well within long range for any realistic chain Metrics.BestKnownBlockNumber = _blockTree.BestKnownNumber; } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs index 6a3eea63a8e6..d53231a34482 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/CensorshipDetector/CensorshipDetector.cs @@ -205,7 +205,6 @@ private void Cache(Block block) if (isCensored) { Metrics.NumberOfPotentiallyCensoredBlocks++; - // Safe cast: block numbers fit well within long range for any realistic chain Metrics.LastPotentiallyCensoredBlockNumber = block.Number; DetectMultiBlockCensorship(blockNumberHash, blockCensorshipInfo); } @@ -229,7 +228,6 @@ private void DetectMultiBlockCensorship(BlockNumberHash block, BlockCensorshipIn { _censoredBlocks.Add(block); Metrics.NumberOfCensoredBlocks++; - // Safe cast: block numbers fit well within long range for any realistic chain Metrics.LastCensoredBlockNumber = block.Number; if (_logger.IsInfo) _logger.Info($"Censorship detected for block {block.Number} with hash {block.Hash!}"); } From e358c7c2209fb6039b424606f1d1025f0becf4ea Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 13:42:02 +0200 Subject: [PATCH 36/60] =?UTF-8?q?review:=20address=20PR=20comments=20?= =?UTF-8?q?=E2=80=94=20cleaner=20ulong=20typing,=20drop=20dead=20code/comm?= =?UTF-8?q?ents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SlotStore: _fileEra long+sentinel -> ulong? (era is ulong). - StatelessBlockTree.Prefetch: length/i to ulong, drop (int)/(ulong) casts around BlockhashCache.MaxDepth. - BlockValidator/BlockErrorMessages: itemCount ulong throughout, drop the asymmetric cast. - ProcessingStats/BlockStatistics: BlockTo long -> ulong (matches BlockFrom), drop the (long)block.Number cast at construction. - TxPoolTxSource: drop noisy "we have leftover candidates / no optimal picking needed" narration; behavior is in the code. - UnclesValidator.IsKin: name the bounded int once, only widen to ulong where it interacts with header.Number. - HeaderValidator: restore master's check order (parent → totalDiff → seal → gasUsed → gasLimit → timestamp → blockNumber) to avoid silently swapping which error a failing test sees first; drop the ValidateFieldLimit virtual stub — it has no overrides and just returns true. - ProgressLogger: strip the explanatory ulong-vs-long comments; the -1 queue sentinel keeps a one-line note. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.BalRecorder/SlotStore.cs | 12 +++++------ .../ProcessingStatsTests.cs | 2 +- .../Processing/ProcessingStats.cs | 4 ++-- .../Producers/TxPoolTxSource.cs | 2 -- .../Stateless/StatelessBlockTree.cs | 6 +++--- .../Validators/BlockValidator.cs | 4 ++-- .../Validators/HeaderValidator.cs | 14 ++++--------- .../Validators/UnclesValidator.cs | 7 ++++--- .../Messages/BlockErrorMessages.cs | 2 +- .../Nethermind.Core/ProgressLogger.cs | 20 +------------------ 10 files changed, 24 insertions(+), 49 deletions(-) diff --git a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs index 5afee81766b0..84356ddf7eac 100644 --- a/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs +++ b/src/Nethermind/Nethermind.BalRecorder/SlotStore.cs @@ -15,7 +15,7 @@ namespace Nethermind.BalRecorder; public class SlotStore(string directory, string extension = "bin") : IDisposable { private SlotFile? _file; - private long _fileEra = -1; + private ulong? _fileEra; private readonly Lock _lock = new(); private string FilePath(ulong era) => Path.Combine(directory, $"{era:D8}.{extension}"); @@ -26,13 +26,13 @@ public bool TryRead(ulong blockNumber, ReadOnlySpanAction acti int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { - if (_fileEra != (long)era) + if (_fileEra != era) { string path = FilePath(era); if (!File.Exists(path)) return false; _file?.Dispose(); _file = new SlotFile(path); - _fileEra = (long)era; + _fileEra = era; } return _file!.TryRead(slot, action, arg); } @@ -44,12 +44,12 @@ public bool Write(ulong blockNumber, ReadOnlySpan data) int slot = (int)(blockNumber % SlotFile.SlotsPerFile); lock (_lock) { - if (_fileEra != (long)era) + if (_fileEra != era) { _file?.Dispose(); Directory.CreateDirectory(directory); _file = new SlotFile(FilePath(era)); - _fileEra = (long)era; + _fileEra = era; } return _file!.TryWrite(slot, data); } @@ -61,7 +61,7 @@ public void Dispose() { _file?.Dispose(); _file = null; - _fileEra = -1; + _fileEra = null; } } } diff --git a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs index 4c3479e2df41..8dfa691b524d 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs @@ -54,7 +54,7 @@ await WithRestoredBlockchainMetrics(async () => AssertStats(stats, blockCount: 2, blockFrom: 1, blockTo: 2, processingMs: 500, mGasPerSecond: 10); }); - private static void AssertStats(BlockStatistics stats, long blockCount, long blockFrom, long blockTo, double processingMs, double mGasPerSecond) + private static void AssertStats(BlockStatistics stats, long blockCount, ulong blockFrom, ulong blockTo, double processingMs, double mGasPerSecond) { using (Assert.EnterMultipleScope()) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index d3610f5a22ef..3c621f52b316 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -25,7 +25,7 @@ public class BlockStatistics { public long BlockCount { get; set; } public ulong BlockFrom { get; set; } - public long BlockTo { get; set; } + public ulong BlockTo { get; set; } public double ProcessingMs { get; set; } public double SlotMs { get; set; } [JsonPropertyName("mgasPerSecond")] @@ -486,7 +486,7 @@ protected virtual void GenerateReport(BlockData data) { BlockCount = chunkBlocks, BlockFrom = chunkFirstBlockNumber, - BlockTo = (long)block.Number, + BlockTo = block.Number, ProcessingMs = chunkMs, SlotMs = runMs, diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 36154141c7da..27447857d56a 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -212,7 +212,6 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain int leftoverCapacity = maxBlobs - selectedBlobTxs.Count; if (countOfRemainingBlobs <= (ulong)leftoverCapacity) { - // We can take all, no optimal picking needed. foreach ((Transaction tx, ulong blobChain) tx in candidates.AsSpan()) { selectedBlobTxs.Add(tx.tx); @@ -220,7 +219,6 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain } else { - // Are more blobs than spaces, select optimal set to include ChooseBestBlobTransactions(candidates, leftoverCapacity, baseFee, selectedBlobTxs); } } diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs index d5ee8ab441c7..16c7d8554cd9 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs @@ -233,12 +233,12 @@ public event EventHandler? OnForkChoiceUpd public Task Prefetch(BlockHeader blockHeader, CancellationToken cancellationToken) { - const int length = (int)BlockhashCache.MaxDepth + 1; + const ulong length = BlockhashCache.MaxDepth + 1; Hash256[] result = new Hash256[length]; result[0] = blockHeader.Hash; - for (int i = 1; i < length; i++) + for (ulong i = 1; i < length; i++) { - if (_numberToHeader.TryGetValue(blockHeader.Number - (ulong)i, out BlockHeader header)) + if (_numberToHeader.TryGetValue(blockHeader.Number - i, out BlockHeader header)) { result[i] = header.Hash; } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 0938194e4d99..b3e2b6e79031 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -458,10 +458,10 @@ private bool ValidateBlockLevelAccessListSize(Block block, ref string? error) { // Suggested/engine blocks carry the wire BAL in BlockAccessList. RLP/P2P // validation reaches this helper after execution with only GeneratedBlockAccessList. - int itemCount = block.BlockAccessList?.ItemCount ?? block.GeneratedBlockAccessList?.ItemCount ?? 0; + ulong itemCount = (ulong)(block.BlockAccessList?.ItemCount ?? block.GeneratedBlockAccessList?.ItemCount ?? 0); ulong maxBalItems = block.Header.GasLimit / Eip7928Constants.ItemCost; - if (itemCount > 0 && (ulong)itemCount > maxBalItems) + if (itemCount > 0 && itemCount > maxBalItems) { error = BlockErrorMessages.BlockAccessListGasLimitExceeded(itemCount, maxBalItems); if (_logger.IsWarn) _logger.Warn($"{Invalid(block)} {error}"); diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index c1b4dc6f934c..74370075f009 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -82,16 +82,15 @@ protected virtual bool Validate(BlockHeader header, BlockHeader? pare parent = orphaned ? null : parent!; // bool gasLimitAboveAbsoluteMinimum = header.GasLimit >= 125000; // described in the YellowPaper but not followed - return ValidateFieldLimit(header, ref error) - && ValidateHash(header, ref error) + return ValidateHash(header, ref error) && ValidateExtraData(header, spec = _specProvider.GetSpec(header), isUncle, ref error) && (orphaned || ValidateParent(header, parent, ref error)) - && (orphaned || ValidateBlockNumber(header, parent, ref error)) - && (orphaned || ValidateTimestamp(header, parent, ref error)) - && (orphaned || ValidateGasLimitRange(header, parent, spec, ref error)) && (orphaned || ValidateTotalDifficulty(header, parent, ref error)) && (orphaned || ValidateSeal(header, parent, isUncle, ref error)) && ValidateGasUsed(header, ref error) + && (orphaned || ValidateGasLimitRange(header, parent, spec, ref error)) + && (orphaned || ValidateTimestamp(header, parent, ref error)) + && (orphaned || ValidateBlockNumber(header, parent, ref error)) && (orphaned || Validate1559(header, parent, spec, ref error)) && (orphaned || ValidateBlobGasFields(header, parent, spec, ref error)) && ValidateRequestsHash(header, spec, ref error) @@ -210,11 +209,6 @@ protected virtual bool ValidateSeal(BlockHeader header, BlockHeader parent, bool return result; } - protected virtual bool ValidateFieldLimit(BlockHeader blockHeader, ref string? error) => - // Number, GasLimit and GasUsed are ulong — they can never be negative. - // This method is kept for subclass extensibility; no checks are needed at this level. - true; - protected virtual bool ValidateExtraData(BlockHeader header, IReleaseSpec spec, bool isUncle, ref string? error) { bool extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize diff --git a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs index 84dd032b3d89..b5c2c143765e 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs @@ -103,14 +103,15 @@ public bool Validate(BlockHeader header, BlockHeader[] uncles) private static bool IsKin(BlockHeader header, BlockHeader uncle, int relationshipLevel, ReadOnlySpan ancestors, int ancestorsCount) { - ulong maxDepth = Math.Min(Math.Min((ulong)ancestorsCount, (ulong)relationshipLevel), header.Number); + int relativeDepth = Math.Min(ancestorsCount, relationshipLevel); + int maxDepth = header.Number >= (ulong)relativeDepth ? relativeDepth : (int)header.Number; - if (uncle.Number < header.Number - maxDepth) + if (uncle.Number + (ulong)maxDepth < header.Number) { return false; } - for (int depth = 0; depth < (int)maxDepth; depth++) + for (int depth = 0; depth < maxDepth; depth++) { BlockHeader parent = ancestors[depth]; diff --git a/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs b/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs index 5854f7ef30af..2d328fc43db8 100644 --- a/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs +++ b/src/Nethermind/Nethermind.Core/Messages/BlockErrorMessages.cs @@ -165,7 +165,7 @@ public static string ExceededBlockSizeLimit(int limit) => public static string InvalidBlockLevelAccessListHash(Hash256 expected, Hash256 actual) => $"InvalidBlockLevelAccessListHash: Expected {expected}, got {actual}"; - public static string BlockAccessListGasLimitExceeded(int balItems, ulong maxBalItems) => + public static string BlockAccessListGasLimitExceeded(ulong balItems, ulong maxBalItems) => $"BlockAccessListGasLimitExceeded: BAL has {balItems} items, exceeds limit of {maxBalItems} (block_gas_limit / {Eip7928Constants.ItemCost})."; public static string BlockLevelAccessListIndexOutOfRange(uint index, uint maxAllowed) => diff --git a/src/Nethermind/Nethermind.Core/ProgressLogger.cs b/src/Nethermind/Nethermind.Core/ProgressLogger.cs index ea4dcdfb46fa..ee581e879413 100644 --- a/src/Nethermind/Nethermind.Core/ProgressLogger.cs +++ b/src/Nethermind/Nethermind.Core/ProgressLogger.cs @@ -20,8 +20,6 @@ public class ProgressLogger private readonly ILogger _logger; private readonly Action? _logAction; private string _prefix; - // State tuple uses ulong for block-number fields (CurrentValue, TargetValue) and long for - // CurrentQueued (uses -1 as "not enabled" sentinel) and _skipped (same sentinel). private (ulong, ulong, long, long) _lastReportState = (0UL, 0UL, 0L, 0L); private Func? _formatter; @@ -43,7 +41,6 @@ public ProgressLogger(string prefix, ILogManager logManager, ITimestamper? times }; } - /// Update the current progress value (a block number, always non-negative). public void Update(ulong value) { UtcEndTime = null; @@ -85,10 +82,6 @@ public void MarkEnd() } } - /// - /// Reset progress tracking. Both and are block - /// numbers (ulong) so no cast is required at call sites that deal with block heights. - /// public void Reset(ulong startValue, ulong total) { LastMeasurement = UtcEndTime = _timestamper.UtcNow; @@ -101,7 +94,6 @@ public void Reset(ulong startValue, ulong total) private long _skipped = -1; - // All four block-number fields are ulong — block numbers are never negative. private ulong StartValue { get; set; } private DateTime? UtcStartTime { get; set; } @@ -115,10 +107,7 @@ public void Reset(ulong startValue, ulong total) public ulong CurrentValue { get; private set; } - /// - /// Number of items currently in the processing queue. Uses -1 as "feature disabled" sentinel, - /// so this must remain long rather than ulong. - /// + // -1 sentinel = queue tracking disabled. public long CurrentQueued { get; set; } = -1; private TimeSpan Elapsed => (UtcEndTime ?? _timestamper.UtcNow) - (UtcStartTime ?? DateTime.MinValue); @@ -134,9 +123,6 @@ public decimal TotalPerSecond return 0M; } - // CurrentValue >= StartValue for monotonically-increasing progress; the cast to decimal - // is required because ulong subtraction yields ulong which cannot be implicitly divided - // by a decimal. return (decimal)(CurrentValue - StartValue) / timePassed; } } @@ -176,8 +162,6 @@ public decimal CurrentPerSecond return 0M; } - // CurrentValue >= LastValue for monotonically-increasing progress; explicit cast - // required for the same reason as TotalPerSecond above. return (decimal)(CurrentValue - LastValue) / timePassed; } } @@ -197,8 +181,6 @@ public void LogProgress() private string DefaultFormatter() => GenerateReport(_prefix, CurrentValue, TargetValue, CurrentQueued, CurrentPerSecond, SkippedPerSecond); - // `current` and `total` are ulong (block numbers); `queue` stays long because it uses -1 as - // a sentinel meaning "queue tracking is not enabled for this progress logger". private static string GenerateReport(string prefix, ulong current, ulong total, long queue, decimal speed, decimal skippedPerSecond) { float percentage = Math.Clamp(current / (float)Math.Max(total, 1UL), 0, 1); From 46c8d576242edbe6dd2d343711af9e365d752aa7 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 13:46:26 +0200 Subject: [PATCH 37/60] review(config): drop the special ulong branch that silently wrapped -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert.ChangeType handles non-negative ulong strings via Convert.ToUInt64 and throws OverflowException on negative input — surfacing a config error instead of silently rewriting "-1" to ulong.MaxValue. No ulong-typed config field in the codebase uses a -1 default; the remaining -1 sentinels all live on signed long/int fields, which are unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.Config/ConfigSourceHelper.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs b/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs index 1905b3df021a..352044728173 100644 --- a/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs +++ b/src/Nethermind/Nethermind.Config/ConfigSourceHelper.cs @@ -161,18 +161,6 @@ private static bool TryFromHex(Type type, string itemValue, out object? value) : throw new FormatException($"Cannot parse enum value: {itemValue}, type: {valueType.Name}"); } - if (valueType == typeof(ulong)) - { - if (long.TryParse(itemValue, out long longVal)) - { - return unchecked((ulong)longVal); - } - if (ulong.TryParse(itemValue, out ulong ulongVal)) - { - return ulongVal; - } - } - return TryFromHex(valueType, itemValue, out object? value) ? value : Convert.ChangeType(itemValue, valueType); } } From 18315713b56797a8091adc2c52ec185cb2291cd2 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 13:46:15 +0200 Subject: [PATCH 38/60] refactor: drop redundant casts and cascade ulong further MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up cleanup to the type-unification PR — eliminates avoidable (long)/(ulong)/(int) casts by either deleting dead ones or cascading the ulong type a step further. - BlockDownloader: drop dead (ulong) cast — FindBestFullState already returns ulong on master. - EvmPooledMemory.ComputeMemoryExpansionCost: declare local words as ulong end-to-end; six casts collapse to none (subtraction is safe by the UpdateSize gating condition). - ChainSpecLoader.GetTransitions: use ulong.Parse(NumberStyles. AllowHexSpecifier) instead of (ulong)Convert.ToInt64 — keeps the signed intermediary out and removes the cast. - StateSyncPivot.GetPivotHeader / UpdateHeaderForcefully: rewrite the signed-gap comparison on ulongs and cascade ISyncConfig.StateMaxDistanceFromHead from int to ulong. The block- distance is conceptually unsigned and the cascade removes four casts at the call site. - SyncStatusList + FastBlockStatusList: cascade public API from long to ulong so the four (long)blockNumber casts at the call site go away. Internal array-allocation crosses one .NET-API boundary (`new int[size]`) which still needs an explicit (long) cast — kept with `checked` so silent truncation can't happen. - TransactionProcessor.CalculateRefundedCreateStateSpillForHalt: replace the open-coded `a > b ? a - b : 0UL` ternary with the public SaturatingSub helper (last open-coded site). - SyncReport beacon-headers format: numHeadersToDownload stays ulong end-to-end; the (long) cast was only there for the format string. - ConfigSourceHelper: when valueType is ulong, parse via ulong.TryParse directly rather than long.TryParse-then-unchecked- cast (which silently wrapped negatives). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Synchronization/ISyncConfig.cs | 2 +- .../Synchronization/SyncConfig.cs | 2 +- .../Nethermind.Evm/EvmPooledMemory.cs | 13 ++++--- .../ChainSpecStyle/ChainSpecLoader.cs | 6 +-- .../FastBlocks/SyncStatusListTests.cs | 25 ++++++------ .../SnapSync/StateSyncPivotTest.cs | 34 ++++++++-------- .../Blocks/BlockDownloader.cs | 2 +- .../FastBlocks/FastBlockStatusList.cs | 39 ++++++++----------- .../FastBlocks/SyncStatusList.cs | 8 ++-- .../FastSync/StateSyncPivot.cs | 9 +++-- .../Reporting/SyncReport.cs | 2 +- 11 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs index ebd54579359e..e5a7174f9a9a 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs @@ -182,7 +182,7 @@ public interface ISyncConfig : IConfig bool VerifyTrieOnStateSyncFinished { get; set; } [ConfigItem(Description = "_Technical._ Max distance of state sync from best suggested header.", DefaultValue = "128", HiddenFromDocs = true)] - int StateMaxDistanceFromHead { get; set; } + ulong StateMaxDistanceFromHead { get; set; } [ConfigItem(Description = "_Technical._ Min distance of state sync from best suggested header.", DefaultValue = "32", HiddenFromDocs = true)] ulong StateMinDistanceFromHead { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index 27fd98af6f17..9722802616a0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -80,7 +80,7 @@ public string? PivotHash public bool NeedToWaitForHeader { get; set; } public bool VerifyTrieOnStateSyncFinished { get; set; } public bool TrieHealing { get; set; } = true; - public int StateMaxDistanceFromHead { get; set; } = 128; + public ulong StateMaxDistanceFromHead { get; set; } = 128; public ulong StateMinDistanceFromHead { get; set; } = 32; public bool GCOnFeedFinished { get; set; } = true; /// diff --git a/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs b/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs index d0894f42650d..dda58a19f9b8 100644 --- a/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs +++ b/src/Nethermind/Nethermind.Evm/EvmPooledMemory.cs @@ -347,14 +347,15 @@ private ulong ComputeMemoryExpansionCost(ulong newSize) Debug.Assert(newSize <= MaxMemorySize); Debug.Assert(Size % WordSize == 0); - long newActiveWords = (long)((newSize + (WordSize - 1UL)) >> 5); - long activeWords = (long)(Size >> 5); + ulong newActiveWords = (newSize + (WordSize - 1UL)) >> 5; + ulong activeWords = Size >> 5; // Full Yellow Paper memory cost is bounded above by ~8.8e12 gas, which fits comfortably - // in long -- so the outOfGas propagation that older revisions carried is unreachable. - ulong cost = (ulong)(newActiveWords - activeWords) * GasCostOf.Memory + - (ulong)((newActiveWords * newActiveWords) >> 9) - - (ulong)((activeWords * activeWords) >> 9); + // in ulong -- so the outOfGas propagation that older revisions carried is unreachable. + // newActiveWords >= activeWords by the gating condition in UpdateSize, so the subtractions are safe. + ulong cost = (newActiveWords - activeWords) * GasCostOf.Memory + + ((newActiveWords * newActiveWords) >> 9) - + ((activeWords * activeWords) >> 9); UpdateSize(newSize, rentIfNeeded: false); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs index 83a6d72206ea..179913a841b5 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs @@ -72,9 +72,9 @@ private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec) if (pricing?.Length > 0) { string key = pricing[0].Key; - // Block numbers in built-in pricing keys are always non-negative; parse as ulong - // directly. Hex keys are parsed via Convert then cast — safe for any valid block number. - return ulong.TryParse(key, out ulong transition) ? transition : (ulong)Convert.ToInt64(key, 16); + return ulong.TryParse(key, out ulong transition) + ? transition + : ulong.Parse(key, System.Globalization.NumberStyles.AllowHexSpecifier); } return null; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs index 7d2be44c2b89..bb7ac476a7aa 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/SyncStatusListTests.cs @@ -20,17 +20,17 @@ public class SyncStatusListTests [Test] public void Out_of_range_access_throws() { - FastBlockStatusList list = new(1); + FastBlockStatusList list = new(1UL); - FastBlockStatus a = list[0]; - list.TrySet(0, a); + FastBlockStatus a = list[0UL]; + list.TrySet(0UL, a); using (Assert.EnterMultipleScope()) { - Assert.Throws(() => { FastBlockStatus a = list[-1]; }); - Assert.Throws(() => { FastBlockStatus a = list[1]; }); - Assert.Throws(() => { list.TrySet(-1, FastBlockStatus.Pending); }); - Assert.Throws(() => { list.TrySet(1, FastBlockStatus.Pending); }); + Assert.Throws(() => { FastBlockStatus a = list[ulong.MaxValue]; }); + Assert.Throws(() => { FastBlockStatus a = list[1UL]; }); + Assert.Throws(() => { list.TrySet(ulong.MaxValue, FastBlockStatus.Pending); }); + Assert.Throws(() => { list.TrySet(1UL, FastBlockStatus.Pending); }); } } @@ -40,7 +40,7 @@ public void Can_read_back_all_set_values() const int length = 4096; FastBlockStatusList list = CreateFastBlockStatusList(length, false); - for (int i = 0; i < length; i++) + for (ulong i = 0; i < length; i++) { Assert.That((FastBlockStatus)(i % 3), Is.EqualTo(list[i])); } @@ -99,7 +99,8 @@ public void Can_read_back_all_parallel_set_values() FastBlockStatusList list = CreateFastBlockStatusList(len); Parallel.For(0, len, (i) => { - Assert.That((FastBlockStatus)(i % 3), Is.EqualTo(list[i])); + ulong idx = (ulong)i; + Assert.That((FastBlockStatus)(idx % 3), Is.EqualTo(list[idx])); }); } } @@ -112,7 +113,8 @@ public void State_transitions_are_enforced() for (int len = 0; len < length; len++) { FastBlockStatusList list = CreateFastBlockStatusList(len, false); - for (int i = 0; i < len; i++) + ulong ulen = (ulong)len; + for (ulong i = 0; i < ulen; i++) { switch (list[i]) { @@ -150,8 +152,9 @@ public void State_transitions_are_enforced_in_parallel() for (int len = 0; len < length; len++) { FastBlockStatusList list = CreateFastBlockStatusList(len); - Parallel.For(0, len, (i) => + Parallel.For(0, len, (rawI) => { + ulong i = (ulong)rawI; switch (list[i]) { case FastBlockStatus.Pending: diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs index c98346b78799..6ab32a30fed5 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs @@ -12,18 +12,18 @@ namespace Nethermind.Synchronization.Test.SnapSync; public class StateSyncPivotTest { - [TestCase(1000, 1000, 10, 100, 1000, 0)] - [TestCase(900, 1000, 10, 50, 1000, 0)] - [TestCase(900, 1000, 10, 100, 1000, 0)] - [TestCase(900, 900, 32, 100, 900, 0)] - [TestCase(0, 300, 32, 100, 301, 300)] + [TestCase(1000UL, 1000UL, 10UL, 100UL, 1000UL, 0UL)] + [TestCase(900UL, 1000UL, 10UL, 50UL, 1000UL, 0UL)] + [TestCase(900UL, 1000UL, 10UL, 100UL, 1000UL, 0UL)] + [TestCase(900UL, 900UL, 32UL, 100UL, 900UL, 0UL)] + [TestCase(0UL, 300UL, 32UL, 100UL, 301UL, 300UL)] public void Will_set_new_best_header_some_distance_from_best_suggested( - int originalBestSuggested, - int newBestSuggested, - int minDistance, - int maxDistance, - int newPivotHeader, - int syncPivot + ulong originalBestSuggested, + ulong newBestSuggested, + ulong minDistance, + ulong maxDistance, + ulong newPivotHeader, + ulong syncPivot ) { IBlockTree blockTree = Substitute.For(); @@ -33,17 +33,17 @@ int syncPivot Synchronization.FastSync.StateSyncPivot stateSyncPivot = new(blockTree, new TestSyncConfig() { - PivotNumber = (ulong)syncPivot, + PivotNumber = syncPivot, FastSync = true, - StateMinDistanceFromHead = (ulong)minDistance, + StateMinDistanceFromHead = minDistance, StateMaxDistanceFromHead = maxDistance, }, LimboLogs.Instance); - blockTree.SyncPivot = ((ulong)syncPivot, Keccak.Zero); + blockTree.SyncPivot = (syncPivot, Keccak.Zero); - blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber((ulong)originalBestSuggested).TestObject); + blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber(originalBestSuggested).TestObject); Assert.That(stateSyncPivot.GetPivotHeader(), Is.Not.Null); - blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber((ulong)newBestSuggested).TestObject); - Assert.That(stateSyncPivot.GetPivotHeader()?.Number, Is.EqualTo((ulong)newPivotHeader)); + blockTree.BestSuggestedHeader.Returns(Build.A.BlockHeader.WithNumber(newBestSuggested).TestObject); + Assert.That(stateSyncPivot.GetPivotHeader()?.Number, Is.EqualTo(newPivotHeader)); } } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs index 2e57d0b44335..af1728d3b37a 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs @@ -691,7 +691,7 @@ private bool SuggestBlock( bool isFastSyncTransition = headIsGenesis && toBeProcessedHasNoProcessedParent; if (isFastSyncTransition) { - ulong bestFullState = (ulong)_fullStateFinder.FindBestFullState(); + ulong bestFullState = _fullStateFinder.FindBestFullState(); shouldProcess = firstBlock > bestFullState && bestFullState != 0; if (!shouldProcess) { diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlockStatusList.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlockStatusList.cs index 8fc255a41f78..79d928b4c994 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlockStatusList.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastBlockStatusList.cs @@ -15,52 +15,47 @@ namespace Nethermind.Synchronization.FastBlocks; internal class FastBlockStatusList { private readonly int[] _statuses; - private readonly long _length; + private readonly ulong _length; - public FastBlockStatusList(long length) + public FastBlockStatusList(ulong length) { // Can fit 16 statuses per int, however need to round up the division - long size = length / 16; - if (size * 16 < length) - { - size++; - } - - _statuses = new int[size]; + ulong size = (length + 15) / 16; + _statuses = new int[checked((long)size)]; _length = length; } - internal FastBlockStatusList(IList statuses, bool parallel) : this(statuses.Count) + internal FastBlockStatusList(IList statuses, bool parallel) : this((ulong)statuses.Count) { if (parallel) { Parallel.For(0, statuses.Count, i => { - this[i] = statuses[i]; + this[(ulong)i] = statuses[i]; }); } else { for (int i = 0; i < statuses.Count; i++) { - this[i] = statuses[i]; + this[(ulong)i] = statuses[i]; } } } - public FastBlockStatus this[long index] + public FastBlockStatus this[ulong index] { get { GuardLength(index); - (long position, int shift) = GetValuePosition(index); + (ulong position, int shift) = GetValuePosition(index); int status = Volatile.Read(ref _statuses[position]); return DecodeValue(status, shift); } private set { GuardLength(index); - (long position, int shift) = GetValuePosition(index); + (ulong position, int shift) = GetValuePosition(index); ref int status = ref _statuses[position]; int oldValue = Volatile.Read(ref status); do @@ -78,24 +73,24 @@ private set } } - private void GuardLength(long index) + private void GuardLength(ulong index) { - if ((ulong)index >= (ulong)_length) + if (index >= _length) { ThrowIndexOutOfRange(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static (long position, int shift) GetValuePosition(long index) + private static (ulong position, int shift) GetValuePosition(ulong index) { - (long position, long shift) = Math.DivRem(index, 16); + (ulong position, ulong shift) = Math.DivRem(index, 16UL); return (position, (int)shift * 2); // 2 bits per status } - public bool TrySet(long index, FastBlockStatus newState) => TrySet(index, newState, out _); + public bool TrySet(ulong index, FastBlockStatus newState) => TrySet(index, newState, out _); - public bool TrySet(long index, FastBlockStatus newState, out FastBlockStatus previousValue) + public bool TrySet(ulong index, FastBlockStatus newState, out FastBlockStatus previousValue) { GuardLength(index); @@ -107,7 +102,7 @@ public bool TrySet(long index, FastBlockStatus newState, out FastBlockStatus pre _ => throw new ArgumentOutOfRangeException(nameof(newState), newState, null) }; - (long position, int shift) = GetValuePosition(index); + (ulong position, int shift) = GetValuePosition(index); ref int status = ref _statuses[position]; int oldValue = Volatile.Read(ref status); do diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs index 32a141c3e6d7..58a9144915a9 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/SyncStatusList.cs @@ -32,7 +32,7 @@ public ulong LowestInsertWithoutGaps public SyncStatusList(IBlockTree blockTree, ulong pivotNumber, ulong? lowestInserted, ulong lowerBound) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - _statuses = new FastBlockStatusList((long)pivotNumber + 1); + _statuses = new FastBlockStatusList(pivotNumber + 1); LowestInsertWithoutGaps = lowestInserted ?? pivotNumber; _lowerBound = lowerBound; @@ -50,7 +50,7 @@ private void GetInfosForBatch(Span blockInfos) continue; } - if (_statuses.TrySet((long)currentNumber, FastBlockStatus.Sent, out FastBlockStatus status)) + if (_statuses.TrySet(currentNumber, FastBlockStatus.Sent, out FastBlockStatus status)) { if (_cache.TryGet(currentNumber, out BlockInfo blockInfo)) { @@ -173,7 +173,7 @@ void CompileOutput(out BlockInfo?[] outputArray) public void MarkInserted(ulong blockNumber) { - if (_statuses.TrySet((long)blockNumber, FastBlockStatus.Inserted)) + if (_statuses.TrySet(blockNumber, FastBlockStatus.Inserted)) { Interlocked.Increment(ref _queueSize); } @@ -181,7 +181,7 @@ public void MarkInserted(ulong blockNumber) public void MarkPending(BlockInfo blockInfo) { - if (_statuses.TrySet((long)blockInfo.BlockNumber, FastBlockStatus.Pending)) + if (_statuses.TrySet(blockInfo.BlockNumber, FastBlockStatus.Pending)) { _cache.Set(blockInfo.BlockNumber, blockInfo); } diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs index b12c2835736b..3c8425026e86 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/StateSyncPivot.cs @@ -21,9 +21,9 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa public BlockHeader? GetPivotHeader() { - // BestSuggestedHeader.Number is ulong; StateMinDistanceFromHead is ulong. - // Cast to long for arithmetic; safe for realistic chain heights. - if (_bestHeader is null || (long)((blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) - (long)_bestHeader.Number >= syncConfig.StateMaxDistanceFromHead) + ulong target = (blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead; + ulong best = _bestHeader?.Number ?? 0UL; + if (_bestHeader is null || (target > best && target - best >= syncConfig.StateMaxDistanceFromHead)) { TrySetNewBestHeader($"distance from HEAD:{Diff}"); } @@ -33,7 +33,8 @@ public class StateSyncPivot(IBlockTree blockTree, ISyncConfig syncConfig, ILogMa public void UpdateHeaderForcefully() { - if (_bestHeader is null || (long)((blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead) > (long)_bestHeader.Number) + ulong target = (blockTree.BestSuggestedHeader?.Number ?? 0UL) + syncConfig.StateMinDistanceFromHead; + if (_bestHeader is null || target > _bestHeader.Number) { TrySetNewBestHeader("too many empty responses"); } diff --git a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs index 14998f6026a5..5fbaa4550eff 100644 --- a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs +++ b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs @@ -49,7 +49,7 @@ public SyncReport(ISyncPeerPool syncPeerPool, INodeStatsManager nodeStatsManager BeaconHeaders.SetFormat((progress) => { - long numHeadersToDownload = (long)(_pivot.PivotNumber - _pivot.PivotDestinationNumber + 1); + ulong numHeadersToDownload = _pivot.PivotNumber - _pivot.PivotDestinationNumber + 1; string skipSectionStr = progress.SkippedPerSecond != -1 ? $"skipped {progress.SkippedPerSecond,ProgressLogger.SpeedPaddingLength:N0} Blk/s | " : ""; From 06cb7f4c1c77b037ead2c7c4c048a0c9371986a0 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 15:03:16 +0200 Subject: [PATCH 39/60] review: misc unsigned-type tightening, strip cast comments, fix div-by-zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DbOnTheRocks: bufferSize cast was on the wrong operand — (ulong)0.35 truncates to 0 and divides by zero. Restore master's (ulong)(targetFileSize / CompressibilityHint). Era1 (EraExporter/EraImporter/EraReader): drop the "Cast to long/int is safe" comments — the casts are still there, but the prose is noise. totalProcessed → ulong (no more (ulong)Interlocked.Increment cast). Era1 EraWriter: _startNumber long → ulong; cast moved to the single WriteInt64 call where the disk format is signed. Era1 tests (Era1ModuleTests / EraExporterTests): start/end → ulong end to end, drop (ulong)start / (ulong)end casts at the call site. EraE: - Admin/RPC: ExportHistory/ImportHistory and admin_*EraHistory take ulong from/to; drops the negativity check and the (ulong)from cast. - Archive/EraReader: e2.First/LastBlock are already ulong; drop the redundant (ulong) casts. - Archive/EraWriter: write _startNumber via new WriteUInt64 helper (was WriteInt64 with (long) cast). - E2Store/E2StoreReader: add ReadUInt64; load _startBlock directly, remove the signed round-trip + "negative starting block" check. - Export/EraExporter: epoch indices and totalProcessed ulong; drop the (ulong)EraWriter.MaxEraSize cast (already ulong-compatible). - Proofs/Validator: GetAccumulatorForEpoch takes ulong; drop the (long)(blockNumber / (ulong)SlotsPerHistoricalRoot) cast pair. - Store/EraStore + RemoteEraStoreDecorator: strip the "Boundary cast — safe" / "uint promotes cleanly" comments and the `int → uint` migration preamble. Decorator's manifest keys / epoch locals: int → uint, so GetBlockRangeAsync stops doing `(ulong)minEpoch * _maxEraSize`. - Store/HttpRemoteEraClient + tests: manifest keys uint; TryParseEpoch outputs uint (drops the `&& epoch >= 0` check that was structurally impossible to fail). EthStats: SkipLocalsInit on the three methods that stackalloc and only read the prefix they wrote (TryParse, TryParseUInt64String, TryParseInt64String). Required AllowUnsafeBlocks in the csproj. Ethash.Test/DifficultyCalculatorTests: blocksAbove long → ulong, drop the (ulong)blocksAbove cast at the Calculate call sites; TestCase literals end with UL. Evm.Benchmark/BlockProcessingBenchmark: startNonce + nonce int → ulong; WithNonce takes startNonce + (ulong)i instead of the cast-the-sum form. Evm.Precompiles/Bls12381G{1,2}Msm + PairingCheck + Eip2537: DiscountForG1/G2 now ulong-in / ulong-out; k is ulong; DataGasCost loses the (ulong)k * (ulong)Eip2537.DiscountForGn(k) cast pair. Evm.Test: - Eip1108Tests: _blockNumberAdjustment int → long (Istanbul-relative signed offset); expectedPrecompileGas long → ulong; drops the (ulong)expectedPrecompileGas cast at AssertGas sites. - Tracing/GasEstimationTests: errorMargin int → ulong (matches GasEstimator.Estimate's ulong errorMargin parameter); TestCase -1 reworked to ulong.MaxValue ("out of bounds" still triggers). - Tracing/ParityLikeTxTracerTests: drop (long)tx.GasLimit and (UInt256)tx.Value — both already match the assertion target type. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.Db.Rocks/DbOnTheRocks.cs | 2 +- .../Nethermind.Era1.Test/Era1ModuleTests.cs | 18 +++---- .../Nethermind.Era1.Test/EraExporterTests.cs | 20 ++++---- src/Nethermind/Nethermind.Era1/EraExporter.cs | 9 +--- src/Nethermind/Nethermind.Era1/EraImporter.cs | 3 -- src/Nethermind/Nethermind.Era1/EraReader.cs | 2 - src/Nethermind/Nethermind.Era1/EraWriter.cs | 6 +-- .../Nethermind.EraE.Test/EraETestModule.cs | 8 +-- .../Export/EraExporterTests.cs | 2 +- .../HttpRemoteEraClientIntegrationTests.cs | 11 ++--- .../Store/HttpRemoteEraClientTests.cs | 10 ++-- .../Store/RemoteEraStoreDecoratorTests.cs | 8 +-- .../Nethermind.EraE/Admin/AdminEraService.cs | 14 ++---- .../Nethermind.EraE/Admin/IAdminEraService.cs | 4 +- .../Nethermind.EraE/Archive/EraReader.cs | 6 +-- .../Nethermind.EraE/Archive/EraWriter.cs | 5 +- .../Nethermind.EraE/E2Store/E2StoreReader.cs | 13 +++-- .../Nethermind.EraE/Export/EraExporter.cs | 18 +++---- .../JsonRpc/EraAdminRpcModule.cs | 4 +- .../JsonRpc/IEraAdminRpcModule.cs | 8 +-- .../Nethermind.EraE/Proofs/Validator.cs | 6 +-- .../Nethermind.EraE/Store/EraStore.cs | 8 --- .../Store/HttpRemoteEraClient.cs | 10 ++-- .../Nethermind.EraE/Store/IRemoteEraClient.cs | 2 +- .../Store/RemoteEraStoreDecorator.cs | 49 ++++++++----------- .../EthStatsMessageParser.cs | 4 ++ .../Nethermind.EthStats.csproj | 1 + .../DifficultyCalculatorTests.cs | 30 ++++++------ .../BlockProcessingBenchmark.cs | 22 ++++----- .../Bls12381G1MsmPrecompile.cs | 4 +- .../Bls12381G2MsmPrecompile.cs | 4 +- .../Bls12381PairingCheckPrecompile.cs | 2 +- .../Nethermind.Evm.Precompiles/Eip2537.cs | 4 +- .../Nethermind.Evm.Test/Eip1108Tests.cs | 26 +++++----- .../Tracing/GasEstimationTests.cs | 28 +++++------ .../Tracing/ParityLikeTxTracerTests.cs | 4 +- 36 files changed, 177 insertions(+), 198 deletions(-) diff --git a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs index 0aea052a96ff..aa8ef046c12a 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs @@ -1666,7 +1666,7 @@ private IDictionary GetHeavyWriteOptions(ulong l0SizeTarget) // stalled by compaction instead of a flush. // The buffer is not compressed unlike l0File, so to account for it, its size needs to be slightly larger. ulong targetFileSize = 16UL.MiB; - ulong bufferSize = targetFileSize / (ulong)_perTableDbConfig.CompressibilityHint; + ulong bufferSize = (ulong)(targetFileSize / _perTableDbConfig.CompressibilityHint); ulong l0FileSize = targetFileSize * (ulong)_minWriteBufferToMerge; ulong maxBufferNumber = (ulong)Environment.ProcessorCount; diff --git a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs index a3d3fdd2346d..12dfe5de8298 100644 --- a/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/Era1ModuleTests.cs @@ -297,14 +297,14 @@ public async Task TestBigBlocksExportImportHistory() } } - [TestCase(true, 0L, 0L, 1000UL, 1001L, 9999L)] - [TestCase(true, 0L, 2000L, 1000UL, 1001L, 2000L)] - [TestCase(true, 3000L, 0L, 5000UL, 5001L, 9999L)] - [TestCase(true, 0L, 0L, 0UL, null, 0L)] - [TestCase(false, 0L, 0L, 0UL, 1L, 9999L)] - [TestCase(false, 0L, 0L, 2000UL, 2001L, 9999L)] + [TestCase(true, 0UL, 0UL, 1000UL, 1001UL, 9999UL)] + [TestCase(true, 0UL, 2000UL, 1000UL, 1001UL, 2000UL)] + [TestCase(true, 3000UL, 0UL, 5000UL, 5001UL, 9999UL)] + [TestCase(true, 0UL, 0UL, 0UL, null, 0UL)] + [TestCase(false, 0UL, 0UL, 0UL, 1UL, 9999UL)] + [TestCase(false, 0UL, 0UL, 2000UL, 2001UL, 9999UL)] [CancelAfter(120_000)] // macOS ARM runners need more time for 10k-block chain - public async Task EraExportAndImport(bool fastSync, long start, long end, ulong headBlockNumber, long? expectedMinSuggestedBlock, long expectedMaxSuggestedBlock, CancellationToken cancellationToken) + public async Task EraExportAndImport(bool fastSync, ulong start, ulong end, ulong headBlockNumber, ulong? expectedMinSuggestedBlock, ulong expectedMaxSuggestedBlock, CancellationToken cancellationToken) { const int ChainLength = 10000; await using IContainer outCtx = await EraTestModule.CreateExportedEraEnvWithCompleteBlockBuilder(ChainLength, cancellationToken: cancellationToken); @@ -331,8 +331,8 @@ public async Task EraExportAndImport(bool fastSync, long start, long end, ulong }) .AddSingleton(new EraConfig() { - From = (ulong)start, - To = (ulong)end, + From = start, + To = end, ImportDirectory = tmpDir, TrustedAccumulatorFile = Path.Join(tmpDir, EraExporter.AccumulatorFileName), MaxEra1Size = 16, diff --git a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs index 0c388137138b..8abeca5833e3 100644 --- a/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.Era1.Test/EraExporterTests.cs @@ -13,15 +13,15 @@ namespace Nethermind.Era1.Test; public class EraExporterTests { - [TestCase(1, 0, 1 - 1, 1UL, 1)] - [TestCase(3, 0, 3 - 1, 1UL, 3)] - [TestCase(16, 0, 16 - 1, 16UL, 1)] - [TestCase(16, 0, 0, 16UL, 1)] - [TestCase(32, 0, 32 - 1, 16UL, 2)] - [TestCase(32, 8, 0, 16UL, 2)] - [TestCase(48, 8, 40 - 1, 16UL, 2)] - [TestCase(64 * 2 + 1, 0, 64 * 2 + 1 - 1, 64UL, 3)] - public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_WithFileName(int chainLength, int start, int end, ulong size, int expectedNumberOfFiles) + [TestCase(1, 0UL, 1UL - 1, 1UL, 1)] + [TestCase(3, 0UL, 3UL - 1, 1UL, 3)] + [TestCase(16, 0UL, 16UL - 1, 16UL, 1)] + [TestCase(16, 0UL, 0UL, 16UL, 1)] + [TestCase(32, 0UL, 32UL - 1, 16UL, 2)] + [TestCase(32, 8UL, 0UL, 16UL, 2)] + [TestCase(48, 8UL, 40UL - 1, 16UL, 2)] + [TestCase(64 * 2 + 1, 0UL, 64UL * 2 + 1 - 1, 64UL, 3)] + public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_WithFileName(int chainLength, ulong start, ulong end, ulong size, int expectedNumberOfFiles) { await using IContainer container = EraTestModule.BuildContainerBuilderWithBlockTreeOfLength(chainLength) .AddSingleton(new EraConfig() { MaxEra1Size = size }) @@ -29,7 +29,7 @@ public async Task Export_ChainHasDifferentLength_CorrectNumberOfFilesCreated_Wit string tmpDirectory = container.ResolveTempDirPath(); IEraExporter sut = container.Resolve(); - await sut.Export(tmpDirectory, (ulong)start, (ulong)end); + await sut.Export(tmpDirectory, start, end); int fileCount = container.Resolve().Directory.GetFiles(tmpDirectory).Length; int metaFile = 2; diff --git a/src/Nethermind/Nethermind.Era1/EraExporter.cs b/src/Nethermind/Nethermind.Era1/EraExporter.cs index 0b1df9da3e8c..be879a6581cc 100644 --- a/src/Nethermind/Nethermind.Era1/EraExporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraExporter.cs @@ -59,15 +59,12 @@ private async Task DoExport( } using ProgressReporter progress = new("Era export", logManager, to - from + 1); - long totalProcessed = 0; + ulong totalProcessed = 0; - // Cast to long is safe: epoch numbers are small ordinals (thousands at most). ulong era1Size = _era1Size; ulong startEpoch = from / era1Size; - // Ceiling division without floating point, all ulong. ulong epochCount = (to - from + era1Size) / era1Size; - // Cast to int is safe: epochCount is bounded by chain length / era size, well within int range. using ArrayPoolList epochIdxs = new((int)epochCount); for (ulong i = 0; i < epochCount; i++) { @@ -108,7 +105,6 @@ async Task WriteEpoch(ulong epochIdx) string filePath = Path.Combine( destinationPath, - // Cast to long is safe: epoch ordinals are small and well within long range. EraPathUtils.Filename(_networkName, epoch, Keccak.Zero)); ValueHash256 accumulator; @@ -134,13 +130,12 @@ async Task WriteEpoch(ulong epochIdx) } await eraWriter.Add(block, receipts, cancellation); - progress.Update((ulong)Interlocked.Increment(ref totalProcessed)); + progress.Update(Interlocked.Increment(ref totalProcessed)); } (accumulator, sha256) = await eraWriter.Finalize(cancellation); } - // Cast to int is safe: epochIdx is bounded by epochCount which was already cast to int above. accumulators[(int)epochIdx] = accumulator; checksums[(int)epochIdx] = sha256; fileNames[(int)epochIdx] = Path.GetFileName(filePath); diff --git a/src/Nethermind/Nethermind.Era1/EraImporter.cs b/src/Nethermind/Nethermind.Era1/EraImporter.cs index 4a3e3d023d51..0d6614f42305 100644 --- a/src/Nethermind/Nethermind.Era1/EraImporter.cs +++ b/src/Nethermind/Nethermind.Era1/EraImporter.cs @@ -79,7 +79,6 @@ public async Task Import(string src, ulong from, ulong to, string? accumulatorFi if (from > to && to != 0) throw new ArgumentException($"Start block ({from}) must not be after end block ({to})"); - // blockTree.Head?.Number is now ulong; +1 is safe as head will never be ulong.MaxValue. ulong headp1 = (blockTree.Head?.Number ?? 0UL) + 1UL; if (from > headp1) { @@ -120,7 +119,6 @@ private async Task ImportInternal( CurrentPacer = pacer; ulong blockNumber = from; - // blockTree.Head?.Number is ulong; +1 is safe (head never reaches ulong.MaxValue in practice). ulong suggestFromBlock = (blockTree.Head?.Number ?? 0UL) + 1UL; if (syncConfig.FastSync && suggestFromBlock == 1UL) { @@ -188,7 +186,6 @@ async Task ImportBlock(ulong blockNumber) { throw new EraImportException($"Unable to find receipt for block {blockNumber}"); } - // block.Number is ulong; no cast needed. if (block.Number != blockNumber) { throw new EraImportException($"Unexpected block number. Expected {blockNumber}. Got {block.Number}"); diff --git a/src/Nethermind/Nethermind.Era1/EraReader.cs b/src/Nethermind/Nethermind.Era1/EraReader.cs index 4d5dcb8e7668..0bb481ec9469 100644 --- a/src/Nethermind/Nethermind.Era1/EraReader.cs +++ b/src/Nethermind/Nethermind.Era1/EraReader.cs @@ -96,8 +96,6 @@ public async Task VerifyContent(ISpecProvider specProvider, IBlock } // Note: Header.Hash is calculated by HeaderDecoder. - // Cast to int is safe: blockCount fits in int (checked above), and the difference - // between a block number and startBlock is bounded by blockCount. blockHashes[(int)(err.Block.Header.Number - startBlock)] = (err.Block.Header.Hash!, err.Block.TotalDifficulty!.Value); } }, cancellation)).ToPooledList(verifyConcurrency); diff --git a/src/Nethermind/Nethermind.Era1/EraWriter.cs b/src/Nethermind/Nethermind.Era1/EraWriter.cs index e1a8b0956f2d..0160efc3d443 100644 --- a/src/Nethermind/Nethermind.Era1/EraWriter.cs +++ b/src/Nethermind/Nethermind.Era1/EraWriter.cs @@ -15,7 +15,7 @@ public class EraWriter : IDisposable { public const int MaxEra1Size = 8192; - private long _startNumber; + private ulong _startNumber; private bool _firstBlock = true; private long _totalWritten; private readonly ArrayPoolList _entryIndexes; @@ -62,7 +62,7 @@ public async Task Add(Block block, TxReceipt[] receipts, CancellationToken cance if (_firstBlock) { - _startNumber = (long)block.Number; + _startNumber = block.Number; _totalWritten += await WriteVersion(); _firstBlock = false; } @@ -108,7 +108,7 @@ public async Task Add(Block block, TxReceipt[] receipts, CancellationToken cance int length = 16 + _entryIndexes.Count * 8; using ArrayPoolList blockIndex = new(length, length); Span blockIndexSpan = blockIndex.AsSpan(); - WriteInt64(blockIndexSpan, 0, _startNumber); + WriteInt64(blockIndexSpan, 0, (long)_startNumber); //era1:= Version | block-tuple ... | other-entries ... | Accumulator | BlockIndex //block-index := starting-number | index | index | index... | count diff --git a/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs b/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs index cd25bfb5091c..713553fd1bdf 100644 --- a/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs +++ b/src/Nethermind/Nethermind.EraE.Test/EraETestModule.cs @@ -42,7 +42,7 @@ public static ContainerBuilder BuildContainerBuilderWithBlockTreeOfLength(int le // The Merge was ~15 Sep 2022 (1663224162s). We use a round timestamp well past both. private const ulong PostMergeGenesisTimestamp = 1_663_000_000; - public static ContainerBuilder BuildContainerBuilderWithPostMergeBlockTreeOfLength(int length) + public static ContainerBuilder BuildContainerBuilderWithPostMergeBlockTreeOfLength(ulong length) { // Set genesis timestamp past beacon-chain genesis so SlotTime.GetSlot succeeds on all blocks. Block genesis = Build.A.Block.Genesis.WithTimestamp(PostMergeGenesisTimestamp).WithPostMergeRules().TestObject; @@ -56,12 +56,12 @@ public static ContainerBuilder BuildContainerBuilderWithPostMergeBlockTreeOfLeng { blockTreeBuilder .WithTransactions(ctx.Resolve()) - .OfChainLength(length); + .OfChainLength((int)length); // Post-merge blocks have TotalDifficulty=0, which never satisfies // HeadImprovementRequirementsSatisfied (0 < MainnetTTD). Force-update head // so the exporter can resolve blockTree.Head correctly. - Block? lastBlock = blockTreeBuilder.BlockTree.FindBlock((ulong)(length - 1), BlockTreeLookupOptions.None); + Block? lastBlock = blockTreeBuilder.BlockTree.FindBlock(length - 1, BlockTreeLookupOptions.None); if (lastBlock is not null) blockTreeBuilder.BlockTree.TryUpdateMainChain(lastBlock.Header, true, forceUpdateHeadBlock: true, preloadedBlocks: new[] { lastBlock }); }); @@ -78,7 +78,7 @@ public static async Task CreateExportedEraEnv(int chainLength = 512, return testCtx; } - public static async Task CreateExportedPostMergeEraEnv(int chainLength = 16) + public static async Task CreateExportedPostMergeEraEnv(ulong chainLength = 16) { IContainer testCtx = BuildContainerBuilderWithPostMergeBlockTreeOfLength(chainLength).Build(); // Start from block 1: genesis is pre-merge in all block trees. diff --git a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs index 41a27c4db671..a907e746eabc 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Export/EraExporterTests.cs @@ -181,7 +181,7 @@ public void Export_WithDestinationAsExistingFile_ThrowsArgumentException() [Test] public async Task Export_WithPostMergeChain_ProducesEpochWithNoTdProofOrAccumulatorEntries() { - const int chainLength = 16; + const ulong chainLength = 16; await using IContainer container = EraETestModule.BuildContainerBuilderWithPostMergeBlockTreeOfLength(chainLength).Build(); string tmpDirectory = container.ResolveTempDirPath(); diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientIntegrationTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientIntegrationTests.cs index a8b1889f7a2e..3ed605f1a4a5 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientIntegrationTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientIntegrationTests.cs @@ -25,7 +25,7 @@ public class HttpRemoteEraClientIntegrationTests // Epoch 0 is the smallest file (~3.5 MB) and its filename is immutable (historical data). private const string Epoch0Filename = "sepolia-00000-8e3e7dc9.erae"; - private const int Epoch0 = 0; + private const uint Epoch0 = 0; private const int MaxEraSize = 8192; private TempPath _downloadDir = null!; @@ -48,11 +48,10 @@ public void TearDown() [Test] public async Task FetchManifest_WithSepoliaServer_ParsesAllEntries() { - IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); + IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); Assert.That(manifest, Is.Not.Empty); - Assert.That(manifest.Keys.Min(), Is.EqualTo(0), "epoch 0 must be the first entry"); - Assert.That(manifest.Keys.All(epoch => epoch >= 0), Is.True); + Assert.That(manifest.Keys.Min(), Is.EqualTo(0u), "epoch 0 must be the first entry"); Assert.That(manifest.ContainsKey(Epoch0), Is.True); Assert.That(manifest[Epoch0].Filename, Is.EqualTo(Epoch0Filename), "epoch 0 filename is immutable — if this fails the server format has changed"); @@ -67,7 +66,7 @@ public async Task FetchManifest_WithSepoliaServer_ParsesAllEntries() [Test] public async Task DownloadEpochZero_WithSepoliaServer_PassesSha256Verification() { - IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); + IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); RemoteEraEntry epoch0Entry = manifest[Epoch0]; string destinationPath = Path.Join(_downloadDir.Path, epoch0Entry.Filename); @@ -84,7 +83,7 @@ public async Task DownloadEpochZero_WithSepoliaServer_PassesSha256Verification() [Test] public async Task FindBlockAndReceipts_WithRealSepoliaEpochZero_ReturnsCorrectBlock() { - IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); + IReadOnlyDictionary manifest = await _client.FetchManifestAsync(); RemoteEraEntry epoch0Entry = manifest[Epoch0]; // Pre-download so the decorator serves from cache (avoids double download in this test) diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientTests.cs index 1bbc66a3aa0b..adcee773ef45 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/HttpRemoteEraClientTests.cs @@ -17,11 +17,11 @@ public class HttpRemoteEraClientTests [Test] public async Task FetchManifestAsync_WithValidEntry_ParsesEpoch() { - IReadOnlyDictionary manifest = + IReadOnlyDictionary manifest = await FetchManifest($"{ValidHash} sepolia-00000-deadbeef.erae"); - Assert.That(manifest.ContainsKey(0), Is.True); - Assert.That(manifest[0].Filename, Is.EqualTo("sepolia-00000-deadbeef.erae")); + Assert.That(manifest.ContainsKey(0u), Is.True); + Assert.That(manifest[0u].Filename, Is.EqualTo("sepolia-00000-deadbeef.erae")); } [TestCase("../sepolia-00000-deadbeef.erae", TestName = "RelativeParentTraversal")] @@ -29,13 +29,13 @@ public async Task FetchManifestAsync_WithValidEntry_ParsesEpoch() [TestCase("/etc/sepolia-00000-deadbeef.erae", TestName = "RootedPath")] public async Task FetchManifestAsync_WhenFilenameContainsPath_SkipsEntry(string hostileFilename) { - IReadOnlyDictionary manifest = + IReadOnlyDictionary manifest = await FetchManifest($"{ValidHash} {hostileFilename}"); Assert.That(manifest, Is.Empty); } - private static async Task> FetchManifest(string manifestBody) + private static async Task> FetchManifest(string manifestBody) { StubHttpMessageHandler handler = new(manifestBody); using HttpClient httpClient = new(handler); diff --git a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs index 35c574957eb7..b7fb8b8b5b6d 100644 --- a/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs +++ b/src/Nethermind/Nethermind.EraE.Test/Store/RemoteEraStoreDecoratorTests.cs @@ -75,7 +75,7 @@ public async Task FindBlockAndReceipts_WhenEpochAbsentFromManifest_ThrowsEraExce .Returns((null, null)); _client.FetchManifestAsync(Arg.Any()) - .Returns(new Dictionary()); + .Returns(new Dictionary()); using RemoteEraStoreDecorator sut = CreateDecorator(localStore, maxEraSize: 16); @@ -90,7 +90,7 @@ public async Task FindBlockAndReceipts_WhenDownloadedFileHasWrongChecksum_Throws byte[] wrongHash = new byte[32]; _client.FetchManifestAsync(Arg.Any()) - .Returns(new Dictionary { [0] = new(filename, wrongHash) }); + .Returns(new Dictionary { [0] = new(filename, wrongHash) }); _client.DownloadFileAsync(filename, Arg.Any(), Arg.Any()) .Returns(callInfo => { @@ -170,7 +170,7 @@ private RemoteEraStoreDecorator CreateDecorator( byte[] sha256 = SHA256.HashData(await File.ReadAllBytesAsync(eraFile)); _client.FetchManifestAsync(Arg.Any()) - .Returns(new Dictionary { [(int)epoch] = new(filename, sha256) }); // BOUNDARY CAST: manifest key is int by upstream API design; epoch fits safely in int + .Returns(new Dictionary { [(uint)epoch] = new(filename, sha256) }); _client.DownloadFileAsync(filename, Arg.Any(), Arg.Any()) .Returns(callInfo => CopyFile(eraFile, callInfo.ArgAt(1))); @@ -184,7 +184,7 @@ public async Task FindBlockAndReceipts_WhenManifestFilenameEscapesDownloadDir_Th byte[] sha256 = new byte[32]; _client.FetchManifestAsync(Arg.Any()) - .Returns(new Dictionary { [0] = new(filename, sha256) }); + .Returns(new Dictionary { [0] = new(filename, sha256) }); string escapedPath = Path.GetFullPath(Path.Join(_downloadDir.Path, filename)); using RemoteEraStoreDecorator sut = CreateDecorator(localStore: null, maxEraSize: 16); diff --git a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs index d374a468bd46..8bbce46dbf71 100644 --- a/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs +++ b/src/Nethermind/Nethermind.EraE/Admin/AdminEraService.cs @@ -19,16 +19,13 @@ public sealed class AdminEraService( private int _canEnterImport = 1; private int _canEnterExport = 1; - public ResultWrapper ExportHistory(string destination, long from, long to) + public ResultWrapper ExportHistory(string destination, ulong from, ulong to) { - if (from < 0 || to < 0) - return ResultWrapper.Fail("from and to must be non-negative.", ErrorCodes.InvalidParams); - if (Interlocked.Exchange(ref _canEnterExport, 0) != 1) return ResultWrapper.Fail("An export job is already running."); _ = EraJobRunner.RunProtected( - ct => eraExporter.Export(destination, (ulong)from, (ulong)to, ct), + ct => eraExporter.Export(destination, from, to, ct), $"EraE export was cancelled. Archives in '{destination}' may be incomplete.", "EraE export error", _logger, @@ -38,16 +35,13 @@ public ResultWrapper ExportHistory(string destination, long from, long t return ResultWrapper.Success("Started EraE export task."); } - public ResultWrapper ImportHistory(string source, long from, long to, string? accumulatorFile) + public ResultWrapper ImportHistory(string source, ulong from, ulong to, string? accumulatorFile) { - if (from < 0 || to < 0) - return ResultWrapper.Fail("from and to must be non-negative.", ErrorCodes.InvalidParams); - if (Interlocked.Exchange(ref _canEnterImport, 0) != 1) return ResultWrapper.Fail("An import job is already running."); _ = EraJobRunner.RunProtected( - ct => eraImporter.Import(source, (ulong)from, (ulong)to, accumulatorFile, ct), + ct => eraImporter.Import(source, from, to, accumulatorFile, ct), $"EraE import was cancelled. State from '{source}' may be incomplete.", "EraE import error", _logger, diff --git a/src/Nethermind/Nethermind.EraE/Admin/IAdminEraService.cs b/src/Nethermind/Nethermind.EraE/Admin/IAdminEraService.cs index 675d1b531c6a..69e2ba91c46f 100644 --- a/src/Nethermind/Nethermind.EraE/Admin/IAdminEraService.cs +++ b/src/Nethermind/Nethermind.EraE/Admin/IAdminEraService.cs @@ -7,6 +7,6 @@ namespace Nethermind.EraE.Admin; public interface IAdminEraService { - ResultWrapper ExportHistory(string destination, long from, long to); - ResultWrapper ImportHistory(string source, long from, long to, string? accumulatorFile); + ResultWrapper ExportHistory(string destination, ulong from, ulong to); + ResultWrapper ImportHistory(string source, ulong from, ulong to, string? accumulatorFile); } diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs index 980f01e3f5bc..e96df4adb212 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraReader.cs @@ -25,14 +25,14 @@ public sealed class EraReader(E2StoreReader e2) : IAsyncEnumerable<(Block, TxRec private readonly BlockBodyDecoder _blockBodyDecoder = BlockBodyDecoder.Instance; private readonly HeaderDecoder _headerDecoder = new(); - public ulong FirstBlock => (ulong)e2.First; - public ulong LastBlock => (ulong)e2.LastBlock; + public ulong FirstBlock => e2.First; + public ulong LastBlock => e2.LastBlock; public EraReader(string fileName) : this(new E2StoreReader(fileName)) { } public async IAsyncEnumerator<(Block, TxReceipt[])> GetAsyncEnumerator(CancellationToken cancellation = default) { - for (ulong blockNumber = (ulong)e2.First; blockNumber <= (ulong)e2.LastBlock; blockNumber++) + for (ulong blockNumber = e2.First; blockNumber <= e2.LastBlock; blockNumber++) { (Block block, TxReceipt[] receipts) = await ReadBlockAndReceipts(blockNumber, cancellation); yield return (block, receipts); diff --git a/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs b/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs index 95f9ce17c92c..c28cf5d721ee 100644 --- a/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs +++ b/src/Nethermind/Nethermind.EraE/Archive/EraWriter.cs @@ -239,7 +239,7 @@ await _e2StoreWriter.WriteEntry( using ArrayPoolList indexBytes = new(indexDataLength, indexDataLength); Span span = indexBytes.AsSpan(); - WriteInt64(span, 0, (long)_startNumber); + WriteUInt64(span, 0, _startNumber); for (int i = 0; i < blockCount; i++) { @@ -367,4 +367,7 @@ private async Task WriteCompressed(ushort entryType, ReadOnlyMemory data, private static void WriteInt64(Span destination, int off, long value) => BinaryPrimitives.WriteInt64LittleEndian(destination.Slice(off, IndexFieldSize), value); + + private static void WriteUInt64(Span destination, int off, ulong value) => + BinaryPrimitives.WriteUInt64LittleEndian(destination.Slice(off, IndexFieldSize), value); } diff --git a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs index 8276e751de07..3d7099afdc17 100644 --- a/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs +++ b/src/Nethermind/Nethermind.EraE/E2Store/E2StoreReader.cs @@ -179,11 +179,7 @@ private void EnsureIndexLoaded() _componentIndexTlvStart = indexEntryStart; - // ComponentIndex is int64 on disk; negative starting_number is an invalid archive. - long startingNumberRaw = ReadInt64(indexEntryStart + EntryHeaderSize); - if (startingNumberRaw < 0) - throw new EraFormatException($"Negative starting block number {startingNumberRaw} in EraE ComponentIndex."); - _startBlock = (ulong)startingNumberRaw; + _startBlock = ReadUInt64(indexEntryStart + EntryHeaderSize); _indexLoaded = true; } @@ -243,4 +239,11 @@ private long ReadInt64(long position) RandomAccess.Read(_file, buff, position); return BinaryPrimitives.ReadInt64LittleEndian(buff); } + + private ulong ReadUInt64(long position) + { + Span buff = stackalloc byte[8]; + RandomAccess.Read(_file, buff, position); + return BinaryPrimitives.ReadUInt64LittleEndian(buff); + } } diff --git a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs index d649130d76b6..51cdcc317506 100644 --- a/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs +++ b/src/Nethermind/Nethermind.EraE/Export/EraExporter.cs @@ -35,7 +35,7 @@ public sealed class EraExporter( private readonly ILogger _logger = logManager.GetClassLogger(); private readonly ReceiptMessageDecoder _receiptDecoder = new(); - private readonly ulong _eraSize = eraConfig.MaxEraSize is > 0UL and <= (ulong)EraWriter.MaxEraSize + private readonly ulong _eraSize = eraConfig.MaxEraSize is > 0UL and <= EraWriter.MaxEraSize ? eraConfig.MaxEraSize : throw new ArgumentException($"MaxEraSize must be between 1 and {EraWriter.MaxEraSize} (SLOTS_PER_HISTORICAL_ROOT). Got {eraConfig.MaxEraSize}."); @@ -70,14 +70,14 @@ private async Task DoExport(string destinationPath, ulong from, ulong to, Cancel fileSystem.Directory.CreateDirectory(destinationPath); using ProgressReporter progress = new("EraE export", logManager, to - from + 1); - long totalProcessed = 0; + ulong totalProcessed = 0; ulong startEpoch = from / _eraSize; ulong endEpoch = to / _eraSize; ulong epochCount = endEpoch - startEpoch + 1; - using ArrayPoolList epochIdxs = new((int)epochCount); - for (long i = 0; i < (long)epochCount; i++) epochIdxs.Add(i); + using ArrayPoolList epochIdxs = new((int)epochCount); + for (ulong i = 0; i < epochCount; i++) epochIdxs.Add(i); using ArrayPoolList accumulators = new((int)epochCount, (int)epochCount); using ArrayPoolList checksums = new((int)epochCount, (int)epochCount); @@ -109,10 +109,10 @@ private async Task DoExport(string destinationPath, ulong from, ulong to, Cancel if (_logger.IsInfo) _logger.Info($"Finished EraE export from {from} to {to}"); - async Task WriteEpoch(long epochIdx, CancellationToken cancel) + async Task WriteEpoch(ulong epochIdx, CancellationToken cancel) { int idx = (int)epochIdx; - ulong epoch = startEpoch + (ulong)epochIdx; + ulong epoch = startEpoch + epochIdx; // Each epoch covers [epoch * eraSize, epoch * eraSize + eraSize - 1]. // Clamp to [from, to] to handle partial first and last epochs. ulong epochBlockStart = epoch * _eraSize; @@ -157,7 +157,7 @@ async Task WriteEpoch(long epochIdx, CancellationToken cancel) await eraWriter.Add(block, receipts, cancel); lastBlockHash = block.Hash!; - progress.Update((ulong)Interlocked.Increment(ref totalProcessed)); + progress.Update(Interlocked.Increment(ref totalProcessed)); } (accumulator, sha256) = await eraWriter.Finalize(cancel); @@ -217,7 +217,7 @@ private bool TrySkipExistingEpoch( ArrayPoolList fileNames, Dictionary cachedChecksums, Dictionary cachedAccumulators, - ref long totalProcessed) + ref ulong totalProcessed) { string? existingFile = null; foreach (string f in fileSystem.Directory.EnumerateFiles(destinationPath, $"{_networkName}-{epoch:D5}-*")) @@ -258,7 +258,7 @@ private bool TrySkipExistingEpoch( checksums[idx] = reader.CalculateChecksum(); } - Interlocked.Add(ref totalProcessed, (long)(writeTo - writeFrom + 1)); + Interlocked.Add(ref totalProcessed, writeTo - writeFrom + 1); if (_logger.IsDebug) _logger.Debug($"Skipping already exported epoch {epoch}."); return true; } diff --git a/src/Nethermind/Nethermind.EraE/JsonRpc/EraAdminRpcModule.cs b/src/Nethermind/Nethermind.EraE/JsonRpc/EraAdminRpcModule.cs index 1697ee715653..4a3ae5e27484 100644 --- a/src/Nethermind/Nethermind.EraE/JsonRpc/EraAdminRpcModule.cs +++ b/src/Nethermind/Nethermind.EraE/JsonRpc/EraAdminRpcModule.cs @@ -8,9 +8,9 @@ namespace Nethermind.EraE.JsonRpc; public class EraAdminRpcModule(IAdminEraService eraService) : IEraAdminRpcModule { - public Task> admin_exportEraHistory(string destinationPath, long from, long to) => + public Task> admin_exportEraHistory(string destinationPath, ulong from, ulong to) => Task.FromResult(eraService.ExportHistory(destinationPath, from, to)); - public Task> admin_importEraHistory(string sourcePath, long from = 0, long to = 0, string? accumulatorFile = null) => + public Task> admin_importEraHistory(string sourcePath, ulong from = 0, ulong to = 0, string? accumulatorFile = null) => Task.FromResult(eraService.ImportHistory(sourcePath, from, to, accumulatorFile)); } diff --git a/src/Nethermind/Nethermind.EraE/JsonRpc/IEraAdminRpcModule.cs b/src/Nethermind/Nethermind.EraE/JsonRpc/IEraAdminRpcModule.cs index 5cd32bd722ab..8ba6d5d4499a 100644 --- a/src/Nethermind/Nethermind.EraE/JsonRpc/IEraAdminRpcModule.cs +++ b/src/Nethermind/Nethermind.EraE/JsonRpc/IEraAdminRpcModule.cs @@ -18,9 +18,9 @@ Task> admin_exportEraHistory( [JsonRpcParameter(Description = "Destination path to export to.", ExampleValue = "/tmp/eraeexportdir")] string destinationPath, [JsonRpcParameter(Description = "Start block to export from.", ExampleValue = "0")] - long from, + ulong from, [JsonRpcParameter(Description = "Last block to export to. Set to 0 to export to head.", ExampleValue = "1000000")] - long to + ulong to ); [JsonRpcMethod( @@ -32,9 +32,9 @@ Task> admin_importEraHistory( [JsonRpcParameter(Description = "Source path to import from.", ExampleValue = "/tmp/eraedir")] string sourcePath, [JsonRpcParameter(Description = "Start block to import. Set to 0 for first available.", ExampleValue = "0")] - long from = 0, + ulong from = 0, [JsonRpcParameter(Description = "End block to import. Set to 0 for last available.", ExampleValue = "0")] - long to = 0, + ulong to = 0, [JsonRpcParameter(Description = "Accumulator file to trust. Set to null to skip accumulator verification.", ExampleValue = "null")] string? accumulatorFile = null ); diff --git a/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs b/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs index 8bd21d8d4ab2..be31c1d6f7d0 100644 --- a/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs +++ b/src/Nethermind/Nethermind.EraE/Proofs/Validator.cs @@ -42,7 +42,7 @@ public Validator( public bool VerifyAccumulator(ulong blockNumber, ValueHash256 accumulatorRoot) { if (!TrustedAccumulatorsProvided()) return true; - ValueHash256? trusted = GetAccumulatorForEpoch((long)(blockNumber / (ulong)HistoricalRootConstants.SlotsPerHistoricalRoot)); + ValueHash256? trusted = GetAccumulatorForEpoch(blockNumber / HistoricalRootConstants.SlotsPerHistoricalRoot); return trusted is null ? throw new EraVerificationException("Trusted accumulator root was not provided.") : trusted.Equals(accumulatorRoot); @@ -79,8 +79,8 @@ public async Task VerifyBlocksRootContext(BlocksRootContext context, Cancellatio private bool TrustedAccumulatorsProvided() => _trustedAccumulators is { Count: > 0 }; - private ValueHash256? GetAccumulatorForEpoch(long epochIdx) => - _trustedAccumulators is null || epochIdx < 0 || epochIdx >= _trustedAccumulators.Count + private ValueHash256? GetAccumulatorForEpoch(ulong epochIdx) => + _trustedAccumulators is null || epochIdx >= (ulong)_trustedAccumulators.Count ? default(ValueHash256?) : _trustedAccumulators[(int)epochIdx]; diff --git a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs index 09f5e2bcd10f..bbddcf3e8f06 100644 --- a/src/Nethermind/Nethermind.EraE/Store/EraStore.cs +++ b/src/Nethermind/Nethermind.EraE/Store/EraStore.cs @@ -34,9 +34,6 @@ public sealed class EraStore : IEraStore private readonly int _maxOpenFile; private readonly ConcurrentDictionary _openedReader = new(); - // Changed int → uint: era size is always a small positive count (e.g. 8192), - // never negative, so uint is the honest type and avoids the (ulong) cast in - // GetEpochNumber without overstating the range as ulong. private readonly ulong _maxEraSize; private readonly int _verifyConcurrency; private volatile bool _disposed; @@ -68,8 +65,6 @@ public EraStore( _blockValidator = blockValidator; _trustedAccumulators = trustedAccumulators; _validator = validator; - // Boundary cast — safe: validated > 0 immediately above, and era sizes - // are small counts (e.g. 8192) that trivially fit in uint. _maxEraSize = maxEraSize; _maxOpenFile = Environment.ProcessorCount * 2; _verifyConcurrency = verifyConcurrency == 0 ? Environment.ProcessorCount : verifyConcurrency; @@ -113,9 +108,6 @@ public EraStore( }); } - // uint promotes cleanly to ulong in the division — no cast needed. - // The (long) cast on the result is a necessary boundary: epoch dictionary - // keys are long throughout this file. private long GetEpochNumber(ulong blockNumber) => (long)(blockNumber / _maxEraSize); private EraReader GetReader(long epoch) => !_epochs.TryGetValue(epoch, out string? path) diff --git a/src/Nethermind/Nethermind.EraE/Store/HttpRemoteEraClient.cs b/src/Nethermind/Nethermind.EraE/Store/HttpRemoteEraClient.cs index abbdc448cdd4..2e0e2e63430e 100644 --- a/src/Nethermind/Nethermind.EraE/Store/HttpRemoteEraClient.cs +++ b/src/Nethermind/Nethermind.EraE/Store/HttpRemoteEraClient.cs @@ -26,7 +26,7 @@ public HttpRemoteEraClient(Uri baseUrl, string manifestFilename, HttpClient? htt _logger = (logManager ?? NullLogManager.Instance).GetClassLogger(); } - public async Task> FetchManifestAsync(CancellationToken cancellation = default) + public async Task> FetchManifestAsync(CancellationToken cancellation = default) { Uri manifestUri = new(_baseUrl, _manifestFilename); @@ -40,7 +40,7 @@ public async Task> FetchManifestAsync(C await using Stream stream = await response.Content.ReadAsStreamAsync(cancellation).ConfigureAwait(false); using StreamReader reader = new(stream); - Dictionary manifest = []; + Dictionary manifest = []; while (await reader.ReadLineAsync(cancellation).ConfigureAwait(false) is { } line) { @@ -54,7 +54,7 @@ public async Task> FetchManifestAsync(C string filename = line[(separatorIdx + 2)..].Trim(); if (!IsPlainFilename(filename)) continue; - if (!TryParseEpoch(filename, out int epoch)) continue; + if (!TryParseEpoch(filename, out uint epoch)) continue; if (!TryParseHex(hashHex, out byte[] sha256)) continue; manifest[epoch] = new RemoteEraEntry(filename, sha256); @@ -105,7 +105,7 @@ public async Task DownloadFileAsync(string filename, string destinationPath, Can private static bool IsPlainFilename(string filename) => filename == Path.GetFileName(filename) && !Path.IsPathRooted(filename); - private static bool TryParseEpoch(string filename, out int epoch) + private static bool TryParseEpoch(string filename, out uint epoch) { epoch = 0; // Expected: {network}-{epoch:05d}-{hash}[-{profile}].ere (or legacy .erae) @@ -115,7 +115,7 @@ private static bool TryParseEpoch(string filename, out int epoch) int second = name[(first + 1)..].IndexOf('-'); if (second < 0) return false; ReadOnlySpan epochPart = name[(first + 1)..(first + 1 + second)]; - return int.TryParse(epochPart, out epoch) && epoch >= 0; + return uint.TryParse(epochPart, out epoch); } private static bool TryParseHex(string hex, out byte[] bytes) diff --git a/src/Nethermind/Nethermind.EraE/Store/IRemoteEraClient.cs b/src/Nethermind/Nethermind.EraE/Store/IRemoteEraClient.cs index 543dc7e68cb3..fd1fa3729fe3 100644 --- a/src/Nethermind/Nethermind.EraE/Store/IRemoteEraClient.cs +++ b/src/Nethermind/Nethermind.EraE/Store/IRemoteEraClient.cs @@ -8,7 +8,7 @@ namespace Nethermind.EraE.Store; public interface IRemoteEraClient { /// Fetches and parses the remote checksum manifest into a map of epoch → entry. - Task> FetchManifestAsync(CancellationToken cancellation = default); + Task> FetchManifestAsync(CancellationToken cancellation = default); /// /// Downloads a single erae file to . diff --git a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs index 0abce1491db8..4ccd7c72313f 100644 --- a/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs +++ b/src/Nethermind/Nethermind.EraE/Store/RemoteEraStoreDecorator.cs @@ -25,9 +25,6 @@ public sealed class RemoteEraStoreDecorator : IEraStore private readonly IEraStore? _localStore; private readonly IRemoteEraClient _client; private readonly string _downloadDir; - // Changed int → uint: era size is always a small positive count (e.g. 8192), - // never negative, so uint is the honest type and avoids (ulong) casts in - // epoch arithmetic. private readonly ulong _maxEraSize; private readonly ISpecProvider _specProvider; private readonly IBlockValidator _blockValidator; @@ -40,21 +37,21 @@ public sealed class RemoteEraStoreDecorator : IEraStore private volatile bool _disposed; // Manifest fetched once on first remote access - private IReadOnlyDictionary? _manifest; + private IReadOnlyDictionary? _manifest; private readonly SemaphoreSlim _manifestLock = new(1, 1); // One semaphore per epoch prevents concurrent duplicate downloads. - private readonly ConcurrentDictionary _epochLocks = new(); + private readonly ConcurrentDictionary _epochLocks = new(); // Available epoch paths — populated after successful download + SHA-256 check - private readonly ConcurrentDictionary _availableEpochs = new(); + private readonly ConcurrentDictionary _availableEpochs = new(); // Epochs whose content has passed EraReader.VerifyContent (only required when ensureValidated) - private readonly ConcurrentDictionary _contentVerifiedEpochs = new(); + private readonly ConcurrentDictionary _contentVerifiedEpochs = new(); // Bounded idle reader pool — readers are checked out (TryRemove) before use and returned // (TryAdd) when done, so the eviction path can only dispose readers that are not in flight. - private readonly ConcurrentDictionary _openedReaders = new(); + private readonly ConcurrentDictionary _openedReaders = new(); // Setup path — sequential, sync-over-async is safe (see thread-safety model above) public (ulong First, ulong Last) BlockRange => GetBlockRangeAsync().GetAwaiter().GetResult(); @@ -79,8 +76,6 @@ public RemoteEraStoreDecorator( _localStore = localStore; _client = client; _downloadDir = downloadDir; - // Boundary cast — safe: validated > 0 immediately above, and era sizes - // are small counts (e.g. 8192) that trivially fit in uint. _maxEraSize = maxEraSize; _specProvider = specProvider; _blockValidator = blockValidator; @@ -100,8 +95,7 @@ public RemoteEraStoreDecorator( if (b is not null) return (b, r); } - // uint promotes cleanly to ulong — no cast needed. - int epoch = (int)(number / _maxEraSize); + uint epoch = (uint)(number / _maxEraSize); string localPath = await EnsureEpochAvailableAsync(epoch, ensureValidated, cancellation).ConfigureAwait(false); using EraRenter renter = RentReader(epoch, localPath); @@ -117,8 +111,7 @@ public ulong NextEraStart(ulong blockNumber) if (_localStore is not null && _localStore.HasEpoch(blockNumber)) return _localStore.NextEraStart(blockNumber); - // uint promotes cleanly to ulong — no cast needed. - int epoch = (int)(blockNumber / _maxEraSize); + uint epoch = (uint)(blockNumber / _maxEraSize); string localPath = EnsureEpochAvailableAsync(epoch, ensureValidated: false).GetAwaiter().GetResult(); using EraReader reader = new(localPath); return reader.LastBlock + 1; @@ -129,13 +122,13 @@ public void Dispose() _disposed = true; _localStore?.Dispose(); _manifestLock.Dispose(); - foreach (KeyValuePair kvp in _epochLocks) + foreach (KeyValuePair kvp in _epochLocks) kvp.Value.Dispose(); - foreach (KeyValuePair kvp in _openedReaders) + foreach (KeyValuePair kvp in _openedReaders) kvp.Value.Dispose(); } - private EraRenter RentReader(int epoch, string localPath) + private EraRenter RentReader(uint epoch, string localPath) { // Fast path: check out an existing idle reader. if (_openedReaders.TryRemove(epoch, out EraReader? existing)) @@ -146,8 +139,8 @@ private EraRenter RentReader(int epoch, string localPath) // least-recently-used and is safe to close. if (_openedReaders.Count >= _maxOpenReaders) { - int oldest = int.MaxValue; - foreach (KeyValuePair kvp in _openedReaders) + uint oldest = uint.MaxValue; + foreach (KeyValuePair kvp in _openedReaders) if (kvp.Key < oldest) oldest = kvp.Key; if (_openedReaders.TryRemove(oldest, out EraReader? evicted)) evicted.Dispose(); @@ -156,13 +149,13 @@ private EraRenter RentReader(int epoch, string localPath) return new EraRenter(this, new EraReader(localPath), epoch); } - private void ReturnReader(int epoch, EraReader reader) + private void ReturnReader(uint epoch, EraReader reader) { if (_disposed || !_openedReaders.TryAdd(epoch, reader)) reader.Dispose(); } - private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reader, int epoch) : IDisposable + private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reader, uint epoch) : IDisposable { public EraReader Reader => reader; public void Dispose() => store.ReturnReader(epoch, reader); @@ -172,20 +165,20 @@ private readonly struct EraRenter(RemoteEraStoreDecorator store, EraReader reade { if (_localStore is not null) return _localStore.BlockRange; - IReadOnlyDictionary manifest = await GetManifestAsync(cancellation).ConfigureAwait(false); + IReadOnlyDictionary manifest = await GetManifestAsync(cancellation).ConfigureAwait(false); if (manifest.Count == 0) throw new EraException("Remote eraE manifest is empty."); - (int minEpoch, int maxEpoch) = manifest.Keys.MinMax(); + (uint minEpoch, uint maxEpoch) = manifest.Keys.MinMax(); // First is exact: era epochs are aligned to maxEraSize boundaries. // Last is upper-bound estimate: avoids downloading the last (potentially huge) epoch file just for validation. // The actual last block may be slightly lower for a non-full final epoch. // FindBlockAndReceipts returns (null, null) when number > reader.LastBlock, so importers that // rely on this value (to=0 / auto mode) will stop naturally at the real end. - return ((ulong)minEpoch * _maxEraSize, (ulong)(maxEpoch + 1) * _maxEraSize - 1); + return (minEpoch * _maxEraSize, (maxEpoch + 1) * _maxEraSize - 1); } - private async Task> GetManifestAsync(CancellationToken cancellation = default) + private async Task> GetManifestAsync(CancellationToken cancellation = default) { if (_manifest is not null) return _manifest; @@ -202,13 +195,13 @@ private async Task> GetManifestAsync(Ca } } - private async Task EnsureEpochAvailableAsync(int epoch, bool ensureValidated, CancellationToken cancellation = default) + private async Task EnsureEpochAvailableAsync(uint epoch, bool ensureValidated, CancellationToken cancellation = default) { if (_availableEpochs.TryGetValue(epoch, out string? cached) && (!ensureValidated || _contentVerifiedEpochs.ContainsKey(epoch))) return cached; - IReadOnlyDictionary manifest = await GetManifestAsync(cancellation).ConfigureAwait(false); + IReadOnlyDictionary manifest = await GetManifestAsync(cancellation).ConfigureAwait(false); if (!manifest.TryGetValue(epoch, out RemoteEraEntry entry)) throw new EraException($"Epoch {epoch} is not available in the remote eraE manifest."); @@ -264,7 +257,7 @@ private async Task EnsureEpochAvailableAsync(int epoch, bool ensureValid } } - private async Task VerifyEpochContentAsync(int epoch, string localPath, CancellationToken cancellation) + private async Task VerifyEpochContentAsync(uint epoch, string localPath, CancellationToken cancellation) { using EraReader reader = new(localPath); ValueHash256 accumulatorRoot = diff --git a/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs b/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs index 6850df6a02b0..da1ac258335b 100644 --- a/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs +++ b/src/Nethermind/Nethermind.EthStats/EthStatsMessageParser.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; using System.Buffers.Text; +using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; @@ -34,6 +35,7 @@ internal static class EthStatsMessageParser private const string NodePong = "node-pong"; private const int StackBufferThreshold = 512; + [SkipLocalsInit] public static bool TryParse(string? message, out EthStatsIncomingMessage incomingMessage) { incomingMessage = new EthStatsIncomingMessage(string.Empty, EthStatsIncomingMessageType.Unknown, null, null); @@ -311,6 +313,7 @@ private static bool TryReadInt64(ref Utf8JsonReader reader, out long value) } } + [SkipLocalsInit] private static bool TryParseUInt64String(ref Utf8JsonReader reader, out ulong value) { // An unsigned 64-bit integer is at most 20 ASCII bytes ("18446744073709551615") @@ -335,6 +338,7 @@ private static bool TryParseUInt64String(ref Utf8JsonReader reader, out ulong va return Utf8Parser.TryParse(raw, out value, out int consumed) && consumed == raw.Length; } + [SkipLocalsInit] private static bool TryParseInt64String(ref Utf8JsonReader reader, out long value) { // A signed 64-bit integer is at most 20 ASCII bytes ("-9223372036854775808"); anything diff --git a/src/Nethermind/Nethermind.EthStats/Nethermind.EthStats.csproj b/src/Nethermind/Nethermind.EthStats/Nethermind.EthStats.csproj index 50a631c432ae..690677981827 100644 --- a/src/Nethermind/Nethermind.EthStats/Nethermind.EthStats.csproj +++ b/src/Nethermind/Nethermind.EthStats/Nethermind.EthStats.csproj @@ -2,6 +2,7 @@ enable + true diff --git a/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs b/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs index a91baf320733..e70cbd57deed 100644 --- a/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Ethash.Test/DifficultyCalculatorTests.cs @@ -51,28 +51,28 @@ public void CalculateBerlin_should_returns_expected_results() } // previous difficulty bomb + InitialDifficultyBombBlock + offset - [TestCase(9000000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] - [TestCase(9000000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] - [TestCase(9000000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] - public void London_calculation_should_not_be_equal_to_Berlin(long blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, + [TestCase(9000000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] + [TestCase(9000000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] + [TestCase(9000000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] + public void London_calculation_should_not_be_equal_to_Berlin(ulong blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, Berlin.Instance, London.Instance); // previous difficulty bomb + InitialDifficultyBombBlock + offset - [TestCase(9700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] - [TestCase(9700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] - [TestCase(9700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] - public void ArrowGlacier_calculation_should_not_be_equal_to_London0(long blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, + [TestCase(9700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] + [TestCase(9700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] + [TestCase(9700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] + public void ArrowGlacier_calculation_should_not_be_equal_to_London0(ulong blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, London.Instance, ArrowGlacier.Instance); // previous difficulty bomb + InitialDifficultyBombBlock + offset - [TestCase(10700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] - [TestCase(10700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] - [TestCase(10700000 + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] - public void GrayGlacier_calculation_should_not_be_equal_to_ArrowGlacier(long blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, + [TestCase(10700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 1)] + [TestCase(10700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 3)] + [TestCase(10700000UL + EthashDifficultyCalculator.InitialDifficultyBombBlock + 730000)] + public void GrayGlacier_calculation_should_not_be_equal_to_ArrowGlacier(ulong blocksAbove) => Calculation_should_not_be_equal_on_different_difficulty_hard_forks(blocksAbove, ArrowGlacier.Instance, GrayGlacier.Instance); private void Calculation_should_not_be_equal_on_different_difficulty_hard_forks( - long blocksAbove, IReleaseSpec firstHardfork, IReleaseSpec secondHardfork) + ulong blocksAbove, IReleaseSpec firstHardfork, IReleaseSpec secondHardfork) { UInt256 parentDifficulty = 0x55f78f7; ulong parentTimestamp = 1613570258; @@ -80,12 +80,12 @@ private void Calculation_should_not_be_equal_on_different_difficulty_hard_forks( ISpecProvider firstHardForkSpecProvider = Substitute.For(); firstHardForkSpecProvider.GetSpec(Arg.Any()).Returns(firstHardfork); EthashDifficultyCalculator firstHardforkDifficultyCalculator = new(firstHardForkSpecProvider); - UInt256 firstHardforkResult = firstHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, (ulong)blocksAbove, false); + UInt256 firstHardforkResult = firstHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, blocksAbove, false); ISpecProvider secondHardforkSpecProvider = Substitute.For(); secondHardforkSpecProvider.GetSpec(Arg.Any()).Returns(secondHardfork); EthashDifficultyCalculator secondHardforkDifficultyCalculator = new(secondHardforkSpecProvider); - UInt256 secondHardforkResult = secondHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, (ulong)blocksAbove, false); + UInt256 secondHardforkResult = secondHardforkDifficultyCalculator.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, blocksAbove, false); Assert.That(secondHardforkResult, Is.Not.EqualTo(firstHardforkResult)); } diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs index 50b01989dd15..31a2cd27dbc6 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/BlockProcessingBenchmark.cs @@ -171,7 +171,7 @@ public void GlobalSetup() // MixedBlock: 100 legacy + 60 EIP-1559 + 30 access-list + 10 contract calls Transaction[] mixedTxs = new Transaction[200]; - int nonce = 0; + ulong nonce = 0; BuildLegacyTransfers(100, nonce).CopyTo(mixedTxs, 0); nonce += 100; BuildEip1559Transfers(60, nonce).CopyTo(mixedTxs, 100); @@ -341,13 +341,13 @@ private Block BuildBlock(params Transaction[] transactions) // ── Transaction builders ────────────────────────────────────────────── - private Transaction[] BuildLegacyTransfers(int count, int startNonce) + private Transaction[] BuildLegacyTransfers(int count, ulong startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((ulong)(startNonce + i)) + .WithNonce(startNonce + (ulong)i) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(21_000) @@ -358,14 +358,14 @@ private Transaction[] BuildLegacyTransfers(int count, int startNonce) return txs; } - private Transaction[] BuildEip1559Transfers(int count, int startNonce) + private Transaction[] BuildEip1559Transfers(int count, ulong startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction .WithType(TxType.EIP1559) - .WithNonce((ulong)(startNonce + i)) + .WithNonce(startNonce + (ulong)i) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(21_000) @@ -377,14 +377,14 @@ private Transaction[] BuildEip1559Transfers(int count, int startNonce) return txs; } - private Transaction[] BuildAccessListTxs(int count, int startNonce) + private Transaction[] BuildAccessListTxs(int count, ulong startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction .WithType(TxType.AccessList) - .WithNonce((ulong)(startNonce + i)) + .WithNonce(startNonce + (ulong)i) .WithTo(TestItem.AddressC) .WithValue(1.Wei) .WithGasLimit(50_000) @@ -396,13 +396,13 @@ private Transaction[] BuildAccessListTxs(int count, int startNonce) return txs; } - private Transaction[] BuildContractDeploys(int count, int startNonce) + private Transaction[] BuildContractDeploys(int count, ulong startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((ulong)(startNonce + i)) + .WithNonce(startNonce + (ulong)i) .WithTo(null) .WithData(ContractCode) .WithGasLimit(100_000) @@ -413,13 +413,13 @@ private Transaction[] BuildContractDeploys(int count, int startNonce) return txs; } - private Transaction[] BuildContractCalls(int count, int startNonce) + private Transaction[] BuildContractCalls(int count, ulong startNonce) { Transaction[] txs = new Transaction[count]; for (int i = 0; i < count; i++) { txs[i] = Build.A.Transaction - .WithNonce((ulong)(startNonce + i)) + .WithNonce(startNonce + (ulong)i) .WithTo(TestItem.AddressB) .WithGasLimit(50_000) .WithGasPrice(2.GWei) diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs index fdcb088bc2a7..3b7c8874d0f1 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G1MsmPrecompile.cs @@ -26,8 +26,8 @@ private Bls12381G1MsmPrecompile() { } public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) { - int k = inputData.Length / ItemSize; - return 12000UL * (ulong)k * (ulong)Eip2537.DiscountForG1(k) / 1000UL; + ulong k = (uint)(inputData.Length / ItemSize); + return 12000UL * k * Eip2537.DiscountForG1(k) / 1000UL; } public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs index 54fb248dc3aa..2afbc7572fb4 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381G2MsmPrecompile.cs @@ -26,8 +26,8 @@ private Bls12381G2MsmPrecompile() { } public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) { - int k = inputData.Length / ItemSize; - return 22500UL * (ulong)k * (ulong)Eip2537.DiscountForG2(k) / 1000UL; + ulong k = (uint)(inputData.Length / ItemSize); + return 22500UL * k * Eip2537.DiscountForG2(k) / 1000UL; } public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs index b67b734e03b1..3c2b5593e66d 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls12381PairingCheckPrecompile.cs @@ -24,7 +24,7 @@ private Bls12381PairingCheckPrecompile() { } public ulong BaseGasCost(IReleaseSpec _) => 37700UL; - public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 32600UL * (ulong)(inputData.Length / PairSize); + public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec _) => 32600UL * (uint)(inputData.Length / PairSize); public partial Result Run(ReadOnlyMemory inputData, IReleaseSpec _); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Eip2537.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Eip2537.cs index 79e1c9b05241..d1d0ecb43ee9 100644 --- a/src/Nethermind/Nethermind.Evm.Precompiles/Eip2537.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Eip2537.cs @@ -164,9 +164,9 @@ private static readonly (int g1, int g2)[] _discountTable = (519, 524) // 128 ]; - internal static int DiscountForG1(int k) => k >= 128 ? _maxDiscountG1 : _discountTable[k].g1; + internal static ulong DiscountForG1(ulong k) => (ulong)(k >= 128 ? _maxDiscountG1 : _discountTable[(int)k].g1); - internal static int DiscountForG2(int k) => k >= 128 ? _maxDiscountG2 : _discountTable[k].g2; + internal static ulong DiscountForG2(ulong k) => (ulong)(k >= 128 ? _maxDiscountG2 : _discountTable[(int)k].g2); internal static Result TryDecodeRaw(this G1 p, ReadOnlySpan raw) { diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs index 6d7c43ed6b14..2cae11d9474d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs @@ -12,7 +12,7 @@ public class Eip1108Tests : VirtualMachineTestsBase { protected override ulong BlockNumber => (ulong)((long)MainnetSpecProvider.IstanbulBlockNumber + _blockNumberAdjustment); - private int _blockNumberAdjustment; + private long _blockNumberAdjustment; [TearDown] public override void TearDown() @@ -22,9 +22,9 @@ public override void TearDown() _blockNumberAdjustment = 0; } - [TestCase(-1, 500L, Description = "Before Istanbul")] - [TestCase(0, 150L, Description = "After Istanbul")] - public void Test_add(int blockAdjustment, long expectedPrecompileGas) + [TestCase(-1L, 500UL, Description = "Before Istanbul")] + [TestCase(0L, 150UL, Description = "After Istanbul")] + public void Test_add(long blockAdjustment, ulong expectedPrecompileGas) { _blockNumberAdjustment = blockAdjustment; byte[] code = Prepare.EvmCode @@ -32,12 +32,12 @@ public void Test_add(int blockAdjustment, long expectedPrecompileGas) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); + AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); } - [TestCase(-1, 50000L, 40000L, Description = "Before Istanbul")] - [TestCase(0, 10000L, 6000L, Description = "After Istanbul")] - public void Test_mul(int blockAdjustment, long gasLimit, long expectedPrecompileGas) + [TestCase(-1L, 50000L, 40000UL, Description = "Before Istanbul")] + [TestCase(0L, 10000L, 6000UL, Description = "After Istanbul")] + public void Test_mul(long blockAdjustment, long gasLimit, ulong expectedPrecompileGas) { _blockNumberAdjustment = blockAdjustment; byte[] code = Prepare.EvmCode @@ -45,12 +45,12 @@ public void Test_mul(int blockAdjustment, long gasLimit, long expectedPrecompile .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); + AssertGas(result, 21000 + 4 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); } - [TestCase(-1, 180000L, Description = "Before Istanbul")] - [TestCase(0, 79000L, Description = "After Istanbul")] - public void Test_pairing(int blockAdjustment, long expectedPrecompileGas) + [TestCase(-1L, 180000UL, Description = "Before Istanbul")] + [TestCase(0L, 79000UL, Description = "After Istanbul")] + public void Test_pairing(long blockAdjustment, ulong expectedPrecompileGas) { _blockNumberAdjustment = blockAdjustment; byte[] code = Prepare.EvmCode @@ -58,6 +58,6 @@ public void Test_pairing(int blockAdjustment, long expectedPrecompileGas) .Done; TestAllTracerWithOutput result = Execute(BlockNumber, 1000000L, code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); - AssertGas(result, 21000 + 6 * 12 + 7 * 3 + GasCostOf.CallEip150 + (ulong)expectedPrecompileGas); + AssertGas(result, 21000 + 6 * 12 + 7 * 3 + GasCostOf.CallEip150 + expectedPrecompileGas); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 36ed44365fcf..87012a738117 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -256,10 +256,10 @@ public void Handles_well_nested_calls_where_least_nested_defines_excess() Assert.That(err, Is.Null); } - [TestCase(-1)] - [TestCase(10000)] - [TestCase(10001)] - public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeException(int errorMargin) + [TestCase(ulong.MaxValue)] + [TestCase(10000UL)] + [TestCase(10001UL)] + public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeException(ulong errorMargin) { Transaction tx = Build.A.Transaction.TestObject; Block block = Build.A.Block.WithTransactions(tx).TestObject; @@ -273,17 +273,17 @@ public void Estimate_UseErrorMarginOutsideBounds_ThrowArgumentOutOfRangeExceptio MainnetSpecProvider.Instance, new BlocksConfig()); - sut.Estimate(tx, block.Header, tracer, out string? err, (ulong)errorMargin); + sut.Estimate(tx, block.Header, tracer, out string? err, errorMargin); Assert.That(err, Is.Not.Null); } - [TestCase(Transaction.BaseTxGasCost, GasEstimator.DefaultErrorMargin, false)] - [TestCase(Transaction.BaseTxGasCost, 100, false)] - [TestCase(Transaction.BaseTxGasCost, 1000, false)] - [TestCase(Transaction.BaseTxGasCost + 10000, GasEstimator.DefaultErrorMargin, true)] - [TestCase(Transaction.BaseTxGasCost + 20000, GasEstimator.DefaultErrorMargin, true)] - [TestCase(Transaction.BaseTxGasCost + 123456789, 123, true)] - public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargin(uint totalGas, int errorMargin, bool fail) + [TestCase(Transaction.BaseTxGasCost, (ulong)GasEstimator.DefaultErrorMargin, false)] + [TestCase(Transaction.BaseTxGasCost, 100UL, false)] + [TestCase(Transaction.BaseTxGasCost, 1000UL, false)] + [TestCase(Transaction.BaseTxGasCost + 10000, (ulong)GasEstimator.DefaultErrorMargin, true)] + [TestCase(Transaction.BaseTxGasCost + 20000, (ulong)GasEstimator.DefaultErrorMargin, true)] + [TestCase(Transaction.BaseTxGasCost + 123456789, 123UL, true)] + public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargin(uint totalGas, ulong errorMargin, bool fail) { Transaction tx = Build.A.Transaction.WithGasLimit(30000).TestObject; Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; @@ -297,7 +297,7 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi MainnetSpecProvider.Instance, new BlocksConfig()); - ulong result = sut.Estimate(tx, block.Header, tracer, out string? err, (ulong)errorMargin); + ulong result = sut.Estimate(tx, block.Header, tracer, out string? err, errorMargin); if (fail) { @@ -312,7 +312,7 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi using (Assert.EnterMultipleScope()) { Assert.That(err, Is.Null); - Assert.That((double)result, Is.EqualTo((double)totalGas).Within((double)totalGas * (errorMargin / 10000d + 1))); + Assert.That((double)result, Is.EqualTo((double)totalGas).Within(totalGas * (errorMargin / 10000d + 1))); } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs index 09081250fa43..c398f0ab4bf6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs @@ -45,8 +45,8 @@ public void On_failure_block_and_tx_fields_are_set() Assert.That(trace.BlockNumber, Is.EqualTo(block.Number), "number"); Assert.That(trace.TransactionPosition, Is.EqualTo(0), "tx index"); Assert.That(trace.TransactionHash, Is.EqualTo(tx.Hash), "tx hash"); - Assert.That(trace.Action.Gas, Is.EqualTo((long)tx.GasLimit - 21000), "gas"); - Assert.That(trace.Action.Value, Is.EqualTo((UInt256)tx.Value), "value"); + Assert.That(trace.Action.Gas, Is.EqualTo(tx.GasLimit - 21000), "gas"); + Assert.That(trace.Action.Value, Is.EqualTo(tx.Value), "value"); Assert.That(trace.Action.Input.ToArray(), Is.EqualTo(tx.Data.AsArray()), "input"); Assert.That(trace.Action.TraceAddress.ToArray(), Is.EqualTo(Array.Empty()), "trace address"); } From 523f83e7c12d48638845633ac920eda56a285a56 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 15:53:59 +0200 Subject: [PATCH 40/60] review: misc ulong-tightening + strip noisy "cast safe" comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EVM: - Eip152Tests / Eip1108Tests: BlockNumber rewritten to unchecked(IstanbulBlockNumber + (ulong)_blockNumberAdjustment) with long _blockNumberAdjustment — one cast, ulong wrap subsumes the sign branch. - Eip2200/3198/3855/7883/7928/8024/8037 tests: stipend / baseFee / repeat / Result / pushCount / gasUsed → ulong end-to-end. - IntrinsicGasCalculatorTests: OldCost/NewCost/FloorCost int → ulong; drops the (ulong) casts inside the assertions. - PrecompileTests.TestCase.Gas long? → ulong?. - EvmPooledMemoryTests: input/expectedResult/memoryAllocation → ulong, decimal.ToInt64 → decimal.ToUInt64. - VmStateTests: factor the duplicated `using vmState; try {…} finally { Env.Dispose(); }` into a VmStateScope that disposes both. Drops ~80 lines. - VirtualMachineTestsBase: drop the "was: long — no negative gas limits" / "gasLimit is ulong" prose comments. EVM source: - EvmInstructions.Math2Param: expSize int → ulong, drops the ExpByteCost * (ulong)expSize cast. - CodeDepositHandler: hoist length = (ulong)byteCodeLength to a local once; downstream uses drop their per-site (ulong) casts. - RefundHelper: MaxRefundQuotient[EIP3529] literals UL; drops the redundant (ulong)(spec.IsEip3529Enabled ? ... : ...) cast. - TransactionProcessor.Validate8037DelegationRefundBounds: maxRefunds int → ulong, single cast at AuthorizationList.Length. - VirtualMachine: stripped the "Cast note: 0UL is canonical…", "Both fields are ulong after IPrecompile.* migration", and the "previous form was tautologically false" comments — code reads fine without them. Facade: - ILogIndexConfig.MaxReorgDepth int? → ulong? (cascades into LogIndexConfig, LogIndexBuilder's MaxReorgDepth property loses the (ulong) cast, BlockTreeModule and PruningTrieStateFactory drop the (int) casts on pruningConfig.PruningBoundary). LogIndexStorage keeps its int-internal layout with one boundary cast at init. - LogIndexBuilder: replace the two-branch `if (number < min)… if (number > max)…` clamp with Math.Clamp; ditto end-clamp inside DoQueueBlocks. Stripped the long "CAST NOTE / LogIndex int by design / Cast back to int is safe" comments throughout. - SimulateBlockhashProvider / SimulateBridgeHelper / SimulateDictionaryHeaderStore: stripped the "Safe subtraction" / "CAST NOTE" / "Cast to long for blockhash" comments. - BlockchainBridgeTests headNumber and maxFeePerGas → ulong, drops the (ulong)/(ulong)maxFeePerGas casts. - LogIndexBuilderTests: minBarrier int → ulong. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../LogIndexStorageIntegrationTests.cs | 12 +- .../Nethermind.Db/LogIndex/ILogIndexConfig.cs | 2 +- .../Nethermind.Db/LogIndex/LogIndexConfig.cs | 2 +- .../Nethermind.Db/LogIndex/LogIndexStorage.cs | 4 +- .../Nethermind.Evm.Test/Eip1108Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip152Tests.cs | 7 +- .../Nethermind.Evm.Test/Eip2200Tests.cs | 46 +-- .../Eip3198BaseFeeTests.cs | 28 +- .../Nethermind.Evm.Test/Eip3855Tests.cs | 28 +- .../Nethermind.Evm.Test/Eip7883Tests.cs | 64 ++-- .../Nethermind.Evm.Test/Eip7928Tests.cs | 2 +- .../Nethermind.Evm.Test/Eip8024Tests.cs | 2 +- .../Eip8037BlockGasInclusionCheckTests.cs | 10 +- .../EvmPooledMemoryTests.cs | 44 +-- .../IntrinsicGasCalculatorTests.cs | 18 +- .../Nethermind.Evm.Test/PrecompileTests.cs | 4 +- .../VirtualMachineTestsBase.cs | 3 +- .../Nethermind.Evm.Test/VmStateTests.cs | 320 ++++++------------ .../Nethermind.Evm/CodeDepositHandler.cs | 12 +- .../EvmInstructions.Math2Param.cs | 4 +- src/Nethermind/Nethermind.Evm/RefundHelper.cs | 6 +- .../TransactionProcessor.cs | 6 +- .../Nethermind.Evm/VirtualMachine.cs | 12 +- .../BlockchainBridgeTests.cs | 12 +- .../LogIndexBuilderTests.cs | 12 +- .../Nethermind.Facade/Find/LogIndexBuilder.cs | 52 +-- .../Simulate/SimulateBlockhashProvider.cs | 2 - .../Simulate/SimulateBridgeHelper.cs | 1 - .../Simulate/SimulateDictionaryHeaderStore.cs | 6 +- .../Modules/BlockTreeModule.cs | 2 +- .../PruningTrieStateFactory.cs | 2 +- 31 files changed, 285 insertions(+), 442 deletions(-) diff --git a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs index 3633358b0a9b..24e40f71cfe0 100644 --- a/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/LogIndex/LogIndexStorageIntegrationTests.cs @@ -56,7 +56,7 @@ public class LogIndexStorageIntegrationTests(LogIndexStorageIntegrationTests.Tes private readonly List _createdStorages = []; private ILogIndexStorage CreateLogIndexStorage( - int compactionDistance = 262_144, int compressionParallelism = 16, int maxReorgDepth = 64, IDbFactory? dbFactory = null, + int compactionDistance = 262_144, int compressionParallelism = 16, ulong maxReorgDepth = 64, IDbFactory? dbFactory = null, string? compressionAlgo = null, int? failOnBlock = null, int? failOnCallN = null, bool failOnMerge = false ) { @@ -376,11 +376,11 @@ public async Task Set_ReorgNonexistent_Get_Test( VerifyReceipts(logIndexStorage, testData, excludedBlocks: reorgBlocks, validateMinMax: false); } - [TestCase(1, 1)] - [TestCase(32, 64)] - [TestCase(64, 64)] - [TestCase(65, 64, Explicit = true)] - public async Task Set_Compact_ReorgLast_Get_Test(int reorgDepth, int maxReorgDepth) + [TestCase(1, 1UL)] + [TestCase(32, 64UL)] + [TestCase(64, 64UL)] + [TestCase(65, 64UL, Explicit = true)] + public async Task Set_Compact_ReorgLast_Get_Test(int reorgDepth, ulong maxReorgDepth) { await using ILogIndexStorage logIndexStorage = CreateLogIndexStorage(maxReorgDepth: maxReorgDepth); diff --git a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs index 53cb3b45148c..6e22939125dd 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/ILogIndexConfig.cs @@ -25,7 +25,7 @@ public interface ILogIndexConfig : IConfig DefaultValue = "64", HiddenFromDocs = true )] - public int? MaxReorgDepth { get; set; } + public ulong? MaxReorgDepth { get; set; } [ConfigItem( Description = "Maximum number of blocks with receipts to add to index per iteration.", diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs index 5208f5ba2003..7d182099f620 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexConfig.cs @@ -13,7 +13,7 @@ public class LogIndexConfig : ILogIndexConfig public bool Reset { get; set; } = false; // set from PruningConfig via decorator - public int? MaxReorgDepth { get; set; } + public ulong? MaxReorgDepth { get; set; } public int MaxBatchSize { get; set; } = 256; public int MaxAggregationQueueSize { get; set; } = 16; diff --git a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs index 627c646b2ee5..397b79401be0 100644 --- a/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs +++ b/src/Nethermind/Nethermind.Db/LogIndex/LogIndexStorage.cs @@ -184,7 +184,7 @@ private IEnumerable DBColumns private readonly ILogger _logger; - private readonly int _maxReorgDepth; + private readonly ulong _maxReorgDepth; private readonly AllMergeOperators _mergeOperators; private readonly ICompressor _compressor; @@ -512,7 +512,7 @@ private static int SaveRangeBound(IWriteOnlyKeyValueStore dbBatch, byte[] key, i return (min, max); } - private int? GetLastReorgableBlockNumber() => _maxBlock - _maxReorgDepth; + private int? GetLastReorgableBlockNumber() => _maxBlock - (int)_maxReorgDepth; private static bool IsBlockNewer(int next, int? lastMin, int? lastMax, bool isBackwardSync) => isBackwardSync ? lastMin is null || next < lastMin diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs index 2cae11d9474d..31d163199c1f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm.Test; public class Eip1108Tests : VirtualMachineTestsBase { - protected override ulong BlockNumber => (ulong)((long)MainnetSpecProvider.IstanbulBlockNumber + _blockNumberAdjustment); + protected override ulong BlockNumber => unchecked(MainnetSpecProvider.IstanbulBlockNumber + (ulong)_blockNumberAdjustment); private long _blockNumberAdjustment; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs index 82af46f840c9..cb3086a16d4b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip152Tests.cs @@ -13,12 +13,9 @@ public class Eip152Tests : VirtualMachineTestsBase { private const int InputLength = 213; - protected override ulong BlockNumber => - _blockNumberAdjustment >= 0 - ? MainnetSpecProvider.IstanbulBlockNumber + (ulong)_blockNumberAdjustment - : MainnetSpecProvider.IstanbulBlockNumber - (ulong)-_blockNumberAdjustment; + protected override ulong BlockNumber => unchecked(MainnetSpecProvider.IstanbulBlockNumber + (ulong)_blockNumberAdjustment); - private int _blockNumberAdjustment; + private long _blockNumberAdjustment; [TearDown] public override void TearDown() diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs index dca34d16c187..0be85531e49e 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs @@ -42,31 +42,31 @@ public void Test(string codeHex, ulong gasUsed, long refund, byte originalValue) AssertGas(receipt, gasUsed + GasCostOf.Transaction - Math.Min((gasUsed + GasCostOf.Transaction) / 2, (ulong)refund)); } - [TestCase("0x60006000556000600055", 1612UL, 0, 2300, true)] - [TestCase("0x60016000556000600055", 20812UL, 0, 2300, true)] - [TestCase("0x60016000556002600055", 20812UL, 0, 2300, true)] - [TestCase("0x60016000556001600055", 20812UL, 0, 2300, true)] - [TestCase("0x60006000556000600055", 5812UL, 1, 2300, true)] - [TestCase("0x60006000556001600055", 5812UL, 1, 2300, true)] - [TestCase("0x60026000556000600055", 5812UL, 1, 2300, true)] - [TestCase("0x60026000556003600055", 5812UL, 1, 2300, true)] - [TestCase("0x60026000556001600055", 5812UL, 1, 2300, true)] - [TestCase("0x60026000556002600055", 5812UL, 1, 2300, true)] - [TestCase("0x60016000556001600055", 1612UL, 1, 2300, true)] - [TestCase("0x60006000556002600055", 5812UL, 1, 2300, true)] - [TestCase("0x60016000556000600055", 5812UL, 1, 2300, false)] - [TestCase("0x60016000556002600055", 5812UL, 1, 2300, false)] - [TestCase("0x600160005560006000556001600055", 40818UL, 0, 2300, false)] - [TestCase("0x600060005560016000556000600055", 10818UL, 1, 2300, false)] - [TestCase("0x60006000556001600055", 20812UL, 0, 2300, false)] - [TestCase("0x60006000556000600055", 1612UL, 0, 2301, false)] - [TestCase("0x60016000556001600055", 1612UL, 1, 2301, false)] - [TestCase("0x60006000556000600055", 1612UL, 0, 2299, true)] - [TestCase("0x60016000556001600055", 1612UL, 1, 2299, true)] - public void Test_at_stipend_boundary(string codeHex, ulong gasUsed, byte originalValue, int stipend, bool outOfGasExpected) + [TestCase("0x60006000556000600055", 1612UL, 0, 2300UL, true)] + [TestCase("0x60016000556000600055", 20812UL, 0, 2300UL, true)] + [TestCase("0x60016000556002600055", 20812UL, 0, 2300UL, true)] + [TestCase("0x60016000556001600055", 20812UL, 0, 2300UL, true)] + [TestCase("0x60006000556000600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60006000556001600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60026000556000600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60026000556003600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60026000556001600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60026000556002600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2300UL, true)] + [TestCase("0x60006000556002600055", 5812UL, 1, 2300UL, true)] + [TestCase("0x60016000556000600055", 5812UL, 1, 2300UL, false)] + [TestCase("0x60016000556002600055", 5812UL, 1, 2300UL, false)] + [TestCase("0x600160005560006000556001600055", 40818UL, 0, 2300UL, false)] + [TestCase("0x600060005560016000556000600055", 10818UL, 1, 2300UL, false)] + [TestCase("0x60006000556001600055", 20812UL, 0, 2300UL, false)] + [TestCase("0x60006000556000600055", 1612UL, 0, 2301UL, false)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2301UL, false)] + [TestCase("0x60006000556000600055", 1612UL, 0, 2299UL, true)] + [TestCase("0x60016000556001600055", 1612UL, 1, 2299UL, true)] + public void Test_at_stipend_boundary(string codeHex, ulong gasUsed, byte originalValue, ulong stipend, bool outOfGasExpected) { SetupStorage(originalValue); - TestAllTracerWithOutput receipt = Execute(BlockNumber, 21000 + gasUsed + (ulong)(stipend - 800), Bytes.FromHexString(codeHex)); + TestAllTracerWithOutput receipt = Execute(BlockNumber, 21000 + gasUsed + stipend - 800, Bytes.FromHexString(codeHex)); Assert.That(receipt.StatusCode, Is.EqualTo(outOfGasExpected ? 0 : 1)); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs index 809efd35990b..b06ca0742ba0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs @@ -14,17 +14,17 @@ namespace Nethermind.Evm.Test public class Eip3198BaseFeeTests : VirtualMachineTestsBase { - [TestCase(true, 0, true)] - [TestCase(true, 100, true)] - [TestCase(true, 20, true)] - [TestCase(false, 20, true)] - [TestCase(false, 0, true)] - [TestCase(true, 0, false)] - [TestCase(true, 100, false)] - [TestCase(true, 20, false)] - [TestCase(false, 20, false)] - [TestCase(false, 0, false)] - public void Base_fee_opcode_should_return_expected_results(bool eip3198Enabled, int baseFee, bool send1559Tx) + [TestCase(true, 0UL, true)] + [TestCase(true, 100UL, true)] + [TestCase(true, 20UL, true)] + [TestCase(false, 20UL, true)] + [TestCase(false, 0UL, true)] + [TestCase(true, 0UL, false)] + [TestCase(true, 100UL, false)] + [TestCase(true, 20UL, false)] + [TestCase(false, 20UL, false)] + [TestCase(false, 0UL, false)] + public void Base_fee_opcode_should_return_expected_results(bool eip3198Enabled, ulong baseFee, bool send1559Tx) { _processor = new EthereumTransactionProcessor(BlobBaseFeeCalculator.Instance, SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); byte[] code = Prepare.EvmCode @@ -35,15 +35,15 @@ public void Base_fee_opcode_should_return_expected_results(bool eip3198Enabled, ulong blockNumber = eip3198Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; (Block block, Transaction transaction) = PrepareTx((blockNumber, 0UL), 100000UL, code); - block.Header.BaseFeePerGas = (UInt256)baseFee; + block.Header.BaseFeePerGas = baseFee; if (send1559Tx) { - transaction.DecodedMaxFeePerGas = (ulong)baseFee; + transaction.DecodedMaxFeePerGas = baseFee; transaction.Type = TxType.EIP1559; } else { - transaction.GasPrice = (UInt256)baseFee; + transaction.GasPrice = baseFee; } TestAllTracerWithOutput tracer = CreateTracer(); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs index 3ac0fdc25f29..1f79d104e9e1 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3855Tests.cs @@ -13,11 +13,11 @@ public class Eip3855Tests : VirtualMachineTestsBase protected override ulong BlockNumber => MainnetSpecProvider.ParisBlockNumber; protected override ulong Timestamp => MainnetSpecProvider.ShanghaiBlockTimestamp; - private TestAllTracerWithOutput testBase(int repeat, bool isShanghai) + private TestAllTracerWithOutput testBase(ulong repeat, bool isShanghai) { ulong timestampParam = isShanghai ? Timestamp : Timestamp - 1; Prepare codeInitializer = Prepare.EvmCode; - for (int i = 0; i < repeat; i++) + for (ulong i = 0; i < repeat; i++) { codeInitializer.Op(Instruction.PUSH0); } @@ -27,24 +27,24 @@ private TestAllTracerWithOutput testBase(int repeat, bool isShanghai) return receipt; } - [TestCase(0, true)] - [TestCase(1, true)] - [TestCase(123, true)] - [TestCase(1024, true)] - public void Test_Eip3855_should_pass(int repeat, bool isShanghai) + [TestCase(0UL, true)] + [TestCase(1UL, true)] + [TestCase(123UL, true)] + [TestCase(1024UL, true)] + public void Test_Eip3855_should_pass(ulong repeat, bool isShanghai) { TestAllTracerWithOutput receipt = testBase(repeat, isShanghai); Assert.That(receipt.StatusCode, Is.EqualTo(StatusCode.Success)); - Assert.That(receipt.GasSpent, Is.EqualTo((ulong)repeat * GasCostOf.Base + GasCostOf.Transaction)); + Assert.That(receipt.GasSpent, Is.EqualTo(repeat * GasCostOf.Base + GasCostOf.Transaction)); } - [TestCase(1, false, Description = "Shanghai fork deactivated")] - [TestCase(123, false, Description = "Shanghai fork deactivated")] - [TestCase(1234, false, Description = "Shanghai fork deactivated")] - [TestCase(1025, true, Description = "Shanghai fork activated, stackoverflow")] - [TestCase(1026, true, Description = "Shanghai fork activated, stackoverflow")] - public void Test_Eip3855_should_fail(int repeat, bool isShanghai) + [TestCase(1UL, false, Description = "Shanghai fork deactivated")] + [TestCase(123UL, false, Description = "Shanghai fork deactivated")] + [TestCase(1234UL, false, Description = "Shanghai fork deactivated")] + [TestCase(1025UL, true, Description = "Shanghai fork activated, stackoverflow")] + [TestCase(1026UL, true, Description = "Shanghai fork activated, stackoverflow")] + public void Test_Eip3855_should_fail(ulong repeat, bool isShanghai) { TestAllTracerWithOutput receipt = testBase(repeat, isShanghai); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs index 5c95265a02f8..3816be81560b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7883Tests.cs @@ -21,7 +21,7 @@ public void DataGasCost([ValueSource(nameof(Eip7883TestCases))] Eip7883TestCase IReleaseSpec? spec = test.FusakaEnabled ? Osaka.Instance : Prague.Instance; ulong gas = ModExpPrecompile.Instance.DataGasCost(inputData, spec); - Assert.That(gas, Is.EqualTo((ulong)test.Result)); + Assert.That(gas, Is.EqualTo(test.Result)); } public class Eip7883TestCase @@ -31,7 +31,7 @@ public class Eip7883TestCase public UInt256 BaseLength { get; set; } public UInt256 ExpLength { get; set; } public UInt256 ModulusLength { get; set; } - public long Result { get; set; } + public ulong Result { get; set; } public override string ToString() => $"Lp: {Lp}, " + $"FusakaEnabled: {FusakaEnabled}, " + $"BaseLength: {BaseLength}, " + @@ -44,67 +44,67 @@ private static IEnumerable Eip7883TestCases() { // eip enabled test cases yield return new Eip7883TestCase - { Lp = 1, FusakaEnabled = true, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 4080L }; + { Lp = 1, FusakaEnabled = true, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 4080UL }; yield return new Eip7883TestCase - { Lp = 2, FusakaEnabled = true, BaseLength = 32, ExpLength = 32, ModulusLength = 1024, Result = 8355840L }; + { Lp = 2, FusakaEnabled = true, BaseLength = 32, ExpLength = 32, ModulusLength = 1024, Result = 8355840UL }; yield return new Eip7883TestCase - { Lp = 3, FusakaEnabled = true, BaseLength = 32, ExpLength = 1024, ModulusLength = 32, Result = 258032L }; + { Lp = 3, FusakaEnabled = true, BaseLength = 32, ExpLength = 1024, ModulusLength = 32, Result = 258032UL }; yield return new Eip7883TestCase - { Lp = 4, FusakaEnabled = true, BaseLength = 1024, ExpLength = 32, ModulusLength = 32, Result = 8355840L }; + { Lp = 4, FusakaEnabled = true, BaseLength = 1024, ExpLength = 32, ModulusLength = 32, Result = 8355840UL }; yield return new Eip7883TestCase - { Lp = 5, FusakaEnabled = true, BaseLength = 32, ExpLength = 1024, ModulusLength = 1024, Result = 528449536L }; + { Lp = 5, FusakaEnabled = true, BaseLength = 32, ExpLength = 1024, ModulusLength = 1024, Result = 528449536UL }; yield return new Eip7883TestCase - { Lp = 6, FusakaEnabled = true, BaseLength = 10000, ExpLength = 1024, ModulusLength = 32, Result = 50396875000L }; + { Lp = 6, FusakaEnabled = true, BaseLength = 10000, ExpLength = 1024, ModulusLength = 32, Result = 50396875000UL }; yield return new Eip7883TestCase - { Lp = 7, FusakaEnabled = true, BaseLength = 1024, ExpLength = 10000, ModulusLength = 1024, Result = 5234458624L }; + { Lp = 7, FusakaEnabled = true, BaseLength = 1024, ExpLength = 10000, ModulusLength = 1024, Result = 5234458624UL }; yield return new Eip7883TestCase - { Lp = 8, FusakaEnabled = true, BaseLength = 1024, ExpLength = 1024, ModulusLength = 10000, Result = 50396875000L }; + { Lp = 8, FusakaEnabled = true, BaseLength = 1024, ExpLength = 1024, ModulusLength = 10000, Result = 50396875000UL }; yield return new Eip7883TestCase // testing exponent >32bytes - { Lp = 9, FusakaEnabled = true, BaseLength = 8, ExpLength = 81, ModulusLength = 8, Result = 16624L }; + { Lp = 9, FusakaEnabled = true, BaseLength = 8, ExpLength = 81, ModulusLength = 8, Result = 16624UL }; yield return new Eip7883TestCase // testing base/modulo below 32 bytes - { Lp = 10, FusakaEnabled = true, BaseLength = 8, ExpLength = 8, ModulusLength = 8, Result = 1008L }; + { Lp = 10, FusakaEnabled = true, BaseLength = 8, ExpLength = 8, ModulusLength = 8, Result = 1008UL }; yield return new Eip7883TestCase // testing 3x general pricing mechanism - { Lp = 11, FusakaEnabled = true, BaseLength = 32, ExpLength = 5, ModulusLength = 32, Result = 624L }; + { Lp = 11, FusakaEnabled = true, BaseLength = 32, ExpLength = 5, ModulusLength = 32, Result = 624UL }; yield return new Eip7883TestCase // testing bump of min price - { Lp = 12, FusakaEnabled = true, BaseLength = 32, ExpLength = 1, ModulusLength = 32, Result = 500L }; + { Lp = 12, FusakaEnabled = true, BaseLength = 32, ExpLength = 1, ModulusLength = 32, Result = 500UL }; yield return new Eip7883TestCase // testing base >32bytes - { Lp = 13, FusakaEnabled = true, BaseLength = 40, ExpLength = 8, ModulusLength = 32, Result = 3150L }; + { Lp = 13, FusakaEnabled = true, BaseLength = 40, ExpLength = 8, ModulusLength = 32, Result = 3150UL }; yield return new Eip7883TestCase // testing modulo >32bytes - { Lp = 14, FusakaEnabled = true, BaseLength = 32, ExpLength = 8, ModulusLength = 40, Result = 3150L }; + { Lp = 14, FusakaEnabled = true, BaseLength = 32, ExpLength = 8, ModulusLength = 40, Result = 3150UL }; yield return new Eip7883TestCase // testing base&modulo >32bytes - { Lp = 15, FusakaEnabled = true, BaseLength = 40, ExpLength = 8, ModulusLength = 40, Result = 3150L }; + { Lp = 15, FusakaEnabled = true, BaseLength = 40, ExpLength = 8, ModulusLength = 40, Result = 3150UL }; // eip disabled test cases yield return new Eip7883TestCase - { Lp = 101, FusakaEnabled = false, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 1360L }; + { Lp = 101, FusakaEnabled = false, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 1360UL }; yield return new Eip7883TestCase - { Lp = 102, FusakaEnabled = false, BaseLength = 32, ExpLength = 32, ModulusLength = 10000, Result = 132812500L }; + { Lp = 102, FusakaEnabled = false, BaseLength = 32, ExpLength = 32, ModulusLength = 10000, Result = 132812500UL }; yield return new Eip7883TestCase - { Lp = 103, FusakaEnabled = false, BaseLength = 32, ExpLength = 10000, ModulusLength = 32, Result = 426661L }; + { Lp = 103, FusakaEnabled = false, BaseLength = 32, ExpLength = 10000, ModulusLength = 32, Result = 426661UL }; yield return new Eip7883TestCase - { Lp = 104, FusakaEnabled = false, BaseLength = 10000, ExpLength = 32, ModulusLength = 32, Result = 132812500L }; + { Lp = 104, FusakaEnabled = false, BaseLength = 10000, ExpLength = 32, ModulusLength = 32, Result = 132812500UL }; yield return new Eip7883TestCase - { Lp = 105, FusakaEnabled = false, BaseLength = 32, ExpLength = 10000, ModulusLength = 10000, Result = 41666145833L }; + { Lp = 105, FusakaEnabled = false, BaseLength = 32, ExpLength = 10000, ModulusLength = 10000, Result = 41666145833UL }; yield return new Eip7883TestCase - { Lp = 106, FusakaEnabled = false, BaseLength = 10000, ExpLength = 10000, ModulusLength = 32, Result = 41666145833L }; + { Lp = 106, FusakaEnabled = false, BaseLength = 10000, ExpLength = 10000, ModulusLength = 32, Result = 41666145833UL }; yield return new Eip7883TestCase - { Lp = 107, FusakaEnabled = false, BaseLength = 10000, ExpLength = 32, ModulusLength = 10000, Result = 132812500L }; + { Lp = 107, FusakaEnabled = false, BaseLength = 10000, ExpLength = 32, ModulusLength = 10000, Result = 132812500UL }; yield return new Eip7883TestCase - { Lp = 108, FusakaEnabled = false, BaseLength = 10000, ExpLength = 10000, ModulusLength = 10000, Result = 41666145833L }; + { Lp = 108, FusakaEnabled = false, BaseLength = 10000, ExpLength = 10000, ModulusLength = 10000, Result = 41666145833UL }; yield return new Eip7883TestCase - { Lp = 109, FusakaEnabled = false, BaseLength = 8, ExpLength = 81, ModulusLength = 8, Result = 215L }; + { Lp = 109, FusakaEnabled = false, BaseLength = 8, ExpLength = 81, ModulusLength = 8, Result = 215UL }; yield return new Eip7883TestCase - { Lp = 110, FusakaEnabled = false, BaseLength = 8, ExpLength = 8, ModulusLength = 8, Result = 200L }; + { Lp = 110, FusakaEnabled = false, BaseLength = 8, ExpLength = 8, ModulusLength = 8, Result = 200UL }; yield return new Eip7883TestCase - { Lp = 111, FusakaEnabled = false, BaseLength = 32, ExpLength = 5, ModulusLength = 32, Result = 208L }; + { Lp = 111, FusakaEnabled = false, BaseLength = 32, ExpLength = 5, ModulusLength = 32, Result = 208UL }; yield return new Eip7883TestCase - { Lp = 112, FusakaEnabled = false, BaseLength = 32, ExpLength = 1, ModulusLength = 32, Result = 200L }; + { Lp = 112, FusakaEnabled = false, BaseLength = 32, ExpLength = 1, ModulusLength = 32, Result = 200UL }; yield return new Eip7883TestCase - { Lp = 113, FusakaEnabled = false, BaseLength = 40, ExpLength = 8, ModulusLength = 32, Result = 525L }; + { Lp = 113, FusakaEnabled = false, BaseLength = 40, ExpLength = 8, ModulusLength = 32, Result = 525UL }; yield return new Eip7883TestCase - { Lp = 114, FusakaEnabled = false, BaseLength = 32, ExpLength = 8, ModulusLength = 40, Result = 525L }; + { Lp = 114, FusakaEnabled = false, BaseLength = 32, ExpLength = 8, ModulusLength = 40, Result = 525UL }; yield return new Eip7883TestCase - { Lp = 115, FusakaEnabled = false, BaseLength = 40, ExpLength = 8, ModulusLength = 40, Result = 525L }; + { Lp = 115, FusakaEnabled = false, BaseLength = 40, ExpLength = 8, ModulusLength = 40, Result = 525UL }; } private static ReadOnlyMemory PrepareInput(UInt256 baseLength, UInt256 expLength, UInt256 modulusLength) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs index 65c009c9f96d..c8da1aaf11dc 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs @@ -989,7 +989,7 @@ public void Eip7928_selfdestruct_to_sender_coalesces_sender_changes(IReleaseSpec CallOutputTracer tracer = new(); TransactionResult res = processor.Execute(tx, tracer); BlockAccessListAtIndex bal = tracedState.GetGeneratingBlockAccessList()!; - UInt256 gasUsed = (UInt256)tracer.GasSpent; + ulong gasUsed = tracer.GasSpent; AccountChangesAtIndex? senderChanges = bal.GetAccountChanges(TestItem.AddressA); AccountChangesAtIndex? victimChanges = bal.GetAccountChanges(_callTargetAddress); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs index 51bdedc986b5..97562da350b0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8024Tests.cs @@ -124,7 +124,7 @@ public void InvalidOperation_Fails(byte[] code) private static IEnumerable GasCostTestCases() { - static ulong Gas(int pushCount) => GasCostOf.Transaction + GasCostOf.VeryLow * (ulong)pushCount + GasCostOf.VeryLow; + static ulong Gas(ulong pushCount) => GasCostOf.Transaction + GasCostOf.VeryLow * pushCount + GasCostOf.VeryLow; yield return new TestCaseData(PushNValues(20).Op(Instruction.DUPN).Data(0x80).Op(Instruction.STOP).Done, Gas(20)).SetName("DupN_GasCost"); yield return new TestCaseData(PushNValues(20).Op(Instruction.SWAPN).Data(0x80).Op(Instruction.STOP).Done, Gas(20)).SetName("SwapN_GasCost"); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs index 046bdaadbb1b..c961486fd9f7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip8037BlockGasInclusionCheckTests.cs @@ -170,14 +170,14 @@ public void Calculate_block_regular_gas_keeps_valid_transcripts_non_negative() } } - [TestCase(300L, 100L, TestName = "Calculate_block_regular_gas_floor_clamps_low_regular_gas")] - [TestCase(0L, 0L, TestName = "Calculate_block_regular_gas_allows_negative_execution_intermediate")] - public void Calculate_block_regular_gas_clamps_to_floor(long initialRegular, long remainingRegular) + [TestCase(300UL, 100UL, TestName = "Calculate_block_regular_gas_floor_clamps_low_regular_gas")] + [TestCase(0UL, 0UL, TestName = "Calculate_block_regular_gas_allows_negative_execution_intermediate")] + public void Calculate_block_regular_gas_clamps_to_floor(ulong initialRegular, ulong remainingRegular) { ulong blockRegularGas = Eip8037BlockGasInclusionCheck.CalculateBlockRegularGas( intrinsicRegularGas: 21_000, - initialRegularGas: (ulong)initialRegular, - remainingRegularGas: (ulong)remainingRegular, + initialRegularGas: initialRegular, + remainingRegularGas: remainingRegular, stateGasSpill: 200, stateGasSpillReclassified: 0, floorGas: 53_000); diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index 0ca41e7841c0..bbca97731c05 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -24,36 +24,36 @@ namespace Nethermind.Evm.Test; public class EvmPooledMemoryTests : EvmMemoryTestsBase { - [TestCase(32, 1)] - [TestCase(0, 0)] - [TestCase(33, 2)] - [TestCase(64, 2)] - [TestCase(int.MaxValue, int.MaxValue / 32 + 1)] - public void Div32Ceiling(int input, int expectedResult) - { - ulong result = EvmCalculations.Div32Ceiling((ulong)input); + [TestCase(32UL, 1UL)] + [TestCase(0UL, 0UL)] + [TestCase(33UL, 2UL)] + [TestCase(64UL, 2UL)] + [TestCase((ulong)int.MaxValue, (ulong)(int.MaxValue / 32 + 1))] + public void Div32Ceiling(ulong input, ulong expectedResult) + { + ulong result = EvmCalculations.Div32Ceiling(input); TestContext.Out.WriteLine($"Memory cost (gas): {result}"); - Assert.That(result, Is.EqualTo((ulong)expectedResult)); + Assert.That(result, Is.EqualTo(expectedResult)); } private const int MaxCodeSize = CodeSizeConstants.MaxCodeSizeEip170; - [TestCase(0, 0)] - [TestCase(0, 32)] - [TestCase(0, 256)] - [TestCase(0, 2048)] - [TestCase(0, MaxCodeSize)] - [TestCase(10 * MaxCodeSize, MaxCodeSize)] - [TestCase(100 * MaxCodeSize, MaxCodeSize)] - [TestCase(1000 * MaxCodeSize, MaxCodeSize)] - [TestCase(0, MemorySizes.MiB)] + [TestCase(0UL, 0UL)] + [TestCase(0UL, 32UL)] + [TestCase(0UL, 256UL)] + [TestCase(0UL, 2048UL)] + [TestCase(0UL, (ulong)MaxCodeSize)] + [TestCase(10UL * MaxCodeSize, (ulong)MaxCodeSize)] + [TestCase(100UL * MaxCodeSize, (ulong)MaxCodeSize)] + [TestCase(1000UL * MaxCodeSize, (ulong)MaxCodeSize)] + [TestCase(0UL, (ulong)MemorySizes.MiB)] // Note: Int32.MaxValue was removed as a test case because after word alignment // it exceeds the maximum allowed memory size and correctly returns out-of-gas. - public void MemoryCost(int destination, int memoryAllocation) + public void MemoryCost(ulong destination, ulong memoryAllocation) { EvmPooledMemory memory = new(); - UInt256 dest = (UInt256)destination; - ulong result = memory.CalculateMemoryCost(in dest, (UInt256)memoryAllocation, out bool outOfGas); + UInt256 dest = destination; + ulong result = memory.CalculateMemoryCost(in dest, memoryAllocation, out bool outOfGas); Assert.That(outOfGas, Is.EqualTo(false)); TestContext.Out.WriteLine($"Gas cost of allocating {memoryAllocation} starting from {dest}: {result}"); } @@ -132,7 +132,7 @@ public void CalculateMemoryCost_TotalSizeExceedsIntMaxAfterWordAlignment_ShouldR public void CalculateMemoryCost_MaxAllowedSize_ShouldReturnExpectedCostForBothLengthOverloads() { decimal maxWords = EvmPooledMemory.MaxMemoryWords; - ulong expectedCost = (ulong)decimal.ToInt64( + ulong expectedCost = decimal.ToUInt64( maxWords * GasCostOf.Memory + decimal.Floor((maxWords * maxWords) / 512m)); diff --git a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs index 0e5b97f7c80b..a1df1a372e08 100644 --- a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs @@ -43,13 +43,13 @@ public class IntrinsicGasCalculatorTests yield return (new List { Address.Zero, (UInt256)1, Address.Zero, (UInt256)1 }, 8600UL); } - public static IEnumerable<(byte[] Data, int OldCost, int NewCost, int FloorCost)> DataTestCaseSource() + public static IEnumerable<(byte[] Data, ulong OldCost, ulong NewCost, ulong FloorCost)> DataTestCaseSource() { - yield return ([0], 4, 4, 21010); - yield return ([1], 68, 16, 21040); - yield return ([0, 0, 1], 76, 24, 21060); - yield return ([1, 1, 0], 140, 36, 21090); - yield return ([0, 0, 1, 1], 144, 40, 21100); + yield return ([0], 4UL, 4UL, 21010UL); + yield return ([1], 68UL, 16UL, 21040UL); + yield return ([0, 0, 1], 76UL, 24UL, 21060UL); + yield return ([1, 1, 0], 140UL, 36UL, 21090UL); + yield return ([0, 0, 1, 1], 144UL, 40UL, 21100UL); } [TestCaseSource(nameof(TestCaseSource))] public void Intrinsic_cost_is_calculated_properly((Transaction Tx, ulong Cost, string Description) testCase) @@ -103,7 +103,7 @@ void Test(IReleaseSpec spec, bool supportsAccessLists) } [TestCaseSource(nameof(DataTestCaseSource))] - public void Intrinsic_cost_of_data_is_calculated_properly((byte[] Data, int OldCost, int NewCost, int FloorCost) testCase) + public void Intrinsic_cost_of_data_is_calculated_properly((byte[] Data, ulong OldCost, ulong NewCost, ulong FloorCost) testCase) { Transaction tx = Build.A.Transaction.SignedAndResolved().WithData(testCase.Data).TestObject; @@ -115,8 +115,8 @@ void Test(IReleaseSpec spec, GasOptions options) bool isAfterRepricing = options.HasFlag(GasOptions.AfterRepricing); bool floorCostEnabled = options.HasFlag(GasOptions.FloorCostEnabled); - Assert.That(gas.Standard, Is.EqualTo(21000UL + (ulong)(isAfterRepricing ? testCase.NewCost : testCase.OldCost)), $"{spec.Name}: {testCase.Data.ToHexString()}"); - Assert.That(gas.FloorGas, Is.EqualTo((ulong)(floorCostEnabled ? testCase.FloorCost : 0))); + Assert.That(gas.Standard, Is.EqualTo(21000UL + (isAfterRepricing ? testCase.NewCost : testCase.OldCost)), $"{spec.Name}: {testCase.Data.ToHexString()}"); + Assert.That(gas.FloorGas, Is.EqualTo(floorCostEnabled ? testCase.FloorCost : 0UL)); Assert.That(gas, Is.EqualTo(new EthereumIntrinsicGas( Standard: 21000UL + (ulong)(isAfterRepricing ? testCase.NewCost : testCase.OldCost), diff --git a/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs index 2079e376bad1..f90ae68f2a55 100644 --- a/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/PrecompileTests.cs @@ -20,7 +20,7 @@ public abstract class PrecompileTests : IPrecompileTests where TTests : PrecompileTests, IPrecompileTests { [method: JsonConstructor] - public record TestCase(ReadOnlyMemory Input, byte[]? Expected, string Name, long? Gas, string? ExpectedError) + public record TestCase(ReadOnlyMemory Input, byte[]? Expected, string Name, ulong? Gas, string? ExpectedError) { public IReleaseSpec Spec { get; internal set; } = DefaultSpec; @@ -93,7 +93,7 @@ private static void RunTestCore(TestCase testCase, string? reason = null) if (testCase.Gas is not null) { - Assert.That((long)gas, Is.EqualTo(testCase.Gas), reason); + Assert.That(gas, Is.EqualTo(testCase.Gas), reason); } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index d648633f212c..916323a224c0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -29,7 +29,7 @@ public abstract class VirtualMachineTestsBase protected const string SampleHexData1 = "a01234"; protected const string SampleHexData2 = "b15678"; protected const string HexZero = "00"; - protected const ulong DefaultBlockGasLimit = 8000000; // was: long — no negative gas limits exist + protected const ulong DefaultBlockGasLimit = 8000000; private IEthereumEcdsa _ethereumEcdsa; protected ITransactionProcessor _processor; @@ -95,7 +95,6 @@ protected GethLikeTxTrace ExecuteAndTrace(ulong blockNumber, ulong gasLimit, par return tracer.BuildResult(); } - // gasLimit is ulong — gas limits are non-negative by definition protected GethLikeTxTrace ExecuteAndTrace(ulong gasLimit, params byte[] code) { (Block block, Transaction transaction) = PrepareTx(Activation, gasLimit, code); diff --git a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs index 9fa3f10de0f1..e6e81faa6aad 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VmStateTests.cs @@ -15,329 +15,209 @@ public class VmStateTests [Test] public void Things_are_cold_to_start_with() { - using VmState vmState = CreateEvmState(); - try - { - StorageCell storageCell = new(TestItem.AddressA, 1); - Assert.That(vmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); - Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.True); - } - finally - { - vmState.Env.Dispose(); - } + using VmStateScope scope = CreateEvmStateScope(); + StorageCell storageCell = new(TestItem.AddressA, 1); + Assert.That(scope.VmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); + Assert.That(scope.VmState.AccessTracker.IsCold(storageCell), Is.True); } [Test] public void Can_warm_address_up_twice() { - using VmState vmState = CreateEvmState(); - try - { - Address address = TestItem.AddressA; - vmState.AccessTracker.WarmUp(address); - vmState.AccessTracker.WarmUp(address); - Assert.That(vmState.AccessTracker.IsCold(address), Is.False); - } - finally - { - vmState.Env.Dispose(); - } + using VmStateScope scope = CreateEvmStateScope(); + Address address = TestItem.AddressA; + scope.VmState.AccessTracker.WarmUp(address); + scope.VmState.AccessTracker.WarmUp(address); + Assert.That(scope.VmState.AccessTracker.IsCold(address), Is.False); } [Test] public void Can_warm_up_many() { - using VmState vmState = CreateEvmState(); - try + using VmStateScope scope = CreateEvmStateScope(); + for (int i = 0; i < TestItem.Addresses.Length; i++) { - for (int i = 0; i < TestItem.Addresses.Length; i++) - { - vmState.AccessTracker.WarmUp(TestItem.Addresses[i]); - vmState.AccessTracker.WarmUp(new StorageCell(TestItem.Addresses[i], 1)); - } - - for (int i = 0; i < TestItem.Addresses.Length; i++) - { - Assert.That(vmState.AccessTracker.IsCold(TestItem.Addresses[i]), Is.False); - Assert.That(vmState.AccessTracker.IsCold(new StorageCell(TestItem.Addresses[i], 1)), Is.False); - } + scope.VmState.AccessTracker.WarmUp(TestItem.Addresses[i]); + scope.VmState.AccessTracker.WarmUp(new StorageCell(TestItem.Addresses[i], 1)); } - finally + + for (int i = 0; i < TestItem.Addresses.Length; i++) { - vmState.Env.Dispose(); + Assert.That(scope.VmState.AccessTracker.IsCold(TestItem.Addresses[i]), Is.False); + Assert.That(scope.VmState.AccessTracker.IsCold(new StorageCell(TestItem.Addresses[i], 1)), Is.False); } } [Test] public void Can_warm_storage_up_twice() { - using VmState vmState = CreateEvmState(); - try - { - Address address = TestItem.AddressA; - StorageCell storageCell = new(address, 1); - vmState.AccessTracker.WarmUp(storageCell); - vmState.AccessTracker.WarmUp(storageCell); - Assert.That(vmState.AccessTracker.IsCold(storageCell), Is.False); - } - finally - { - vmState.Env.Dispose(); - } + using VmStateScope scope = CreateEvmStateScope(); + Address address = TestItem.AddressA; + StorageCell storageCell = new(address, 1); + scope.VmState.AccessTracker.WarmUp(storageCell); + scope.VmState.AccessTracker.WarmUp(storageCell); + Assert.That(scope.VmState.AccessTracker.IsCold(storageCell), Is.False); } [Test] public void Nothing_to_commit() { - using VmState parentVmState = CreateEvmState(); - try - { - using VmState vmState = CreateEvmState(parentVmState); - vmState.CommitToParent(parentVmState); - } - finally - { - parentVmState.Env.Dispose(); - } + using VmStateScope parent = CreateEvmStateScope(); + using VmStateScope child = CreateEvmStateScope(parent.VmState); + child.VmState.CommitToParent(parent.VmState); } [Test] public void Nothing_to_restore() { - using VmState parentVmState = CreateEvmState(); - try - { - using VmState vmState = CreateEvmState(parentVmState); - } - finally - { - parentVmState.Env.Dispose(); - } + using VmStateScope parent = CreateEvmStateScope(); + using VmStateScope _ = CreateEvmStateScope(parent.VmState); } [Test] public void Address_to_commit_keeps_it_warm() { - using VmState parentVmState = CreateEvmState(); - try + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.WarmUp(TestItem.AddressA); - vmState.CommitToParent(parentVmState); - } - - Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.False); - } - finally - { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.WarmUp(TestItem.AddressA); + child.VmState.CommitToParent(parent.VmState); } + + Assert.That(parent.VmState.AccessTracker.IsCold(TestItem.AddressA), Is.False); } [Test] public void Address_to_restore_keeps_it_cold() { - using VmState parentVmState = CreateEvmState(); - try + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.WarmUp(TestItem.AddressA); - } - - Assert.That(parentVmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); - } - finally - { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.WarmUp(TestItem.AddressA); } + + Assert.That(parent.VmState.AccessTracker.IsCold(TestItem.AddressA), Is.True); } [Test] public void Storage_to_commit_keeps_it_warm() { - using VmState parentVmState = CreateEvmState(); - try - { - StorageCell storageCell = new(TestItem.AddressA, 1); - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.WarmUp(storageCell); - vmState.CommitToParent(parentVmState); - } - - Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.False); - } - finally + using VmStateScope parent = CreateEvmStateScope(); + StorageCell storageCell = new(TestItem.AddressA, 1); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.WarmUp(storageCell); + child.VmState.CommitToParent(parent.VmState); } + + Assert.That(parent.VmState.AccessTracker.IsCold(storageCell), Is.False); } [Test] public void Storage_to_restore_keeps_it_cold() { - using VmState parentVmState = CreateEvmState(); - try - { - StorageCell storageCell = new(TestItem.AddressA, 1); - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.WarmUp(storageCell); - } - - Assert.That(parentVmState.AccessTracker.IsCold(storageCell), Is.True); - } - finally + using VmStateScope parent = CreateEvmStateScope(); + StorageCell storageCell = new(TestItem.AddressA, 1); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.WarmUp(storageCell); } + + Assert.That(parent.VmState.AccessTracker.IsCold(storageCell), Is.True); } [Test] public void Logs_are_committed() { - using VmState parentVmState = CreateEvmState(); - try - { - LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.Logs.Add(logEntry); - vmState.CommitToParent(parentVmState); - } - - Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.True); - } - finally + using VmStateScope parent = CreateEvmStateScope(); + LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.Logs.Add(logEntry); + child.VmState.CommitToParent(parent.VmState); } + + Assert.That(parent.VmState.AccessTracker.Logs.Contains(logEntry), Is.True); } [Test] public void Logs_are_restored() { - using VmState parentVmState = CreateEvmState(); - try + using VmStateScope parent = CreateEvmStateScope(); + LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - LogEntry logEntry = new(Address.Zero, Bytes.Empty, []); - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.Logs.Add(logEntry); - } - - Assert.That(parentVmState.AccessTracker.Logs.Contains(logEntry), Is.False); - } - finally - { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.Logs.Add(logEntry); } + + Assert.That(parent.VmState.AccessTracker.Logs.Contains(logEntry), Is.False); } [Test] public void Destroy_list_is_committed() { - using VmState parentVmState = CreateEvmState(); - try + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.ToBeDestroyed(Address.Zero); - vmState.CommitToParent(parentVmState); - } - - Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.True); - } - finally - { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.ToBeDestroyed(Address.Zero); + child.VmState.CommitToParent(parent.VmState); } + + Assert.That(parent.VmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.True); } [Test] public void Destroy_list_is_restored() { - using VmState parentVmState = CreateEvmState(); - try - { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.AccessTracker.ToBeDestroyed(Address.Zero); - } - - Assert.That(parentVmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.False); - } - finally + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - parentVmState.Env.Dispose(); + child.VmState.AccessTracker.ToBeDestroyed(Address.Zero); } + + Assert.That(parent.VmState.AccessTracker.DestroyList.Contains(Address.Zero), Is.False); } [Test] public void Commit_adds_refunds() { - using VmState parentVmState = CreateEvmState(); - try - { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.Refund = 333; - vmState.CommitToParent(parentVmState); - } - - Assert.That(parentVmState.Refund, Is.EqualTo(333)); - } - finally + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - parentVmState.Env.Dispose(); + child.VmState.Refund = 333; + child.VmState.CommitToParent(parent.VmState); } + + Assert.That(parent.VmState.Refund, Is.EqualTo(333)); } [Test] public void Restore_does_not_add_refunds() { - using VmState parentVmState = CreateEvmState(); - try + using VmStateScope parent = CreateEvmStateScope(); + using (VmStateScope child = CreateEvmStateScope(parent.VmState)) { - using (VmState vmState = CreateEvmState(parentVmState)) - { - vmState.Refund = 333; - } - - Assert.That(parentVmState.Refund, Is.EqualTo(0)); - } - finally - { - parentVmState.Env.Dispose(); + child.VmState.Refund = 333; } + + Assert.That(parent.VmState.Refund, Is.EqualTo(0)); } [Test] public void Can_dispose_without_init() { - using VmState vmState = CreateEvmState(); - vmState.Env.Dispose(); + using VmStateScope scope = CreateEvmStateScope(); } [Test] public void Can_dispose_after_init() { - using VmState vmState = CreateEvmState(); - try - { - vmState.InitializeStacks(default, out EvmStack _); - } - finally - { - vmState.Env.Dispose(); - } + using VmStateScope scope = CreateEvmStateScope(); + scope.VmState.InitializeStacks(default, out EvmStack _); } - private static VmState CreateEvmState(VmState parentVmState = null, bool isContinuation = false) => - parentVmState is null + private static VmStateScope CreateEvmStateScope(VmState parentVmState = null) => + new(parentVmState is null ? VmState.RentTopLevel(EthereumGasPolicy.FromULong(10000), ExecutionType.CALL, RentExecutionEnvironment(), @@ -351,9 +231,23 @@ parentVmState is null false, RentExecutionEnvironment(), parentVmState.AccessTracker, - Snapshot.Empty); + Snapshot.Empty)); private static ExecutionEnvironment RentExecutionEnvironment() => ExecutionEnvironment.Rent(null, null, null, null, 0, default, default); + + // VmState.Dispose only releases its ExecutionEnvironment for non-top-level frames; the + // top-level Env is caller-owned and otherwise leaks. Bundle both so tests dispose cleanly. + private readonly struct VmStateScope(VmState vmState) : System.IDisposable + { + public VmState VmState { get; } = vmState; + + public void Dispose() + { + ExecutionEnvironment env = VmState.Env; + VmState.Dispose(); + env.Dispose(); + } + } } } diff --git a/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs b/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs index 236887880583..0620f2827bf3 100644 --- a/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs +++ b/src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs @@ -33,13 +33,14 @@ public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, out ulon return false; } + ulong length = (ulong)byteCodeLength; if (!spec.IsEip8037Enabled) { - regularCost = GasCostOf.CodeDeposit * (ulong)byteCodeLength; + regularCost = GasCostOf.CodeDeposit * length; return true; } - ulong words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); + ulong words = EvmCalculations.Div32Ceiling(length, out bool outOfGas); if (outOfGas) { regularCost = ulong.MaxValue; @@ -48,7 +49,7 @@ public static bool CalculateCost(IReleaseSpec spec, int byteCodeLength, out ulon } regularCost = GasCostOf.CodeDepositRegularPerWord * words; - stateCost = GasCostOf.CodeDepositState * (ulong)byteCodeLength; + stateCost = GasCostOf.CodeDepositState * length; return true; } @@ -63,13 +64,14 @@ public static bool CalculateCost(IReleaseSpec spec, int byteCodeLeng return false; } + ulong length = (ulong)byteCodeLength; if (!spec.IsEip8037Enabled) { - regularCost = GasCostOf.CodeDeposit * (ulong)byteCodeLength; + regularCost = GasCostOf.CodeDeposit * length; return true; } - ulong words = EvmCalculations.Div32Ceiling((ulong)byteCodeLength, out bool outOfGas); + ulong words = EvmCalculations.Div32Ceiling(length, out bool outOfGas); if (outOfGas) { regularCost = ulong.MaxValue; diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs index fa2b989df588..fc9db00c8970 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs @@ -281,9 +281,9 @@ public static EvmExceptionType InstructionExp(VirtualM return stack.PushOne(); } - int expSize = 32 - leadingZeros; + ulong expSize = (ulong)(32 - leadingZeros); // Deduct gas proportional to the number of 32-byte words needed to represent the exponent. - TGasPolicy.Consume(ref gas, vm.Spec.GasCosts.ExpByteCost * (ulong)expSize); + TGasPolicy.Consume(ref gas, vm.Spec.GasCosts.ExpByteCost * expSize); if (a.IsZero) { diff --git a/src/Nethermind/Nethermind.Evm/RefundHelper.cs b/src/Nethermind/Nethermind.Evm/RefundHelper.cs index e8618e4d6d04..c8fb32d03121 100644 --- a/src/Nethermind/Nethermind.Evm/RefundHelper.cs +++ b/src/Nethermind/Nethermind.Evm/RefundHelper.cs @@ -9,13 +9,13 @@ namespace Nethermind.Evm { public static class RefundHelper { - public const ulong MaxRefundQuotient = 2L; + public const ulong MaxRefundQuotient = 2UL; - public const ulong MaxRefundQuotientEIP3529 = 5L; + public const ulong MaxRefundQuotientEIP3529 = 5UL; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong CalculateClaimableRefund(ulong spentGas, ulong totalRefund, IReleaseSpec spec) { - ulong maxRefundQuotient = (ulong)(spec.IsEip3529Enabled ? MaxRefundQuotientEIP3529 : MaxRefundQuotient); + ulong maxRefundQuotient = spec.IsEip3529Enabled ? MaxRefundQuotientEIP3529 : MaxRefundQuotient; return Math.Min(spentGas / maxRefundQuotient, totalRefund); } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index a558df17cbd3..f037e014f89b 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -626,12 +626,12 @@ private TransactionResult Validate8037DelegationRefundBounds(Transaction tx, IRe ulong newAccountStateCost = TGasPolicy.GetNewAccountStateCost(in gasAvailable); ulong perAuthBaseStateCost = TGasPolicy.GetPerAuthBaseStateCost(in gasAvailable); - int maxRefunds = tx.AuthorizationList.Length; + ulong maxRefunds = (ulong)tx.AuthorizationList.Length; if (!TryCalculate8037DelegationRefund( newAccountStateCost, perAuthBaseStateCost, - (ulong)maxRefunds, - (ulong)maxRefunds, + maxRefunds, + maxRefunds, out _)) { TraceLogInvalidTx(tx, "AUTHORIZATION_REFUND_OVERFLOW"); diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 8a2191ca814a..f7335f2c627c 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -479,8 +479,6 @@ private void TryChargeAndDepositCode( } else if (!chargedCodeDeposit && _txTracer.IsTracingActions) { - // Cast note: 0UL is the canonical gas value here — no gas remains after a failed-but-non-halting - // deposit. ReportActionEnd takes ulong; using 0UL avoids any implicit narrowing ambiguity. _txTracer.ReportActionEnd(0UL, callCodeOwner, code); } } @@ -660,9 +658,8 @@ internal void CreditStateGasRefund(ref TGasPolicy gas, ulong amount, bool trackS ulong pendingRefund = amount - appliedRefund; if (pendingRefund > 0) { - // The restored state gas may have been paid by an ancestor frame. It is still - // immediately spendable in the restoring frame, but the state-gas-used reduction - // must propagate upward separately so child state gas is not erased on return. + // Restored state gas paid by an ancestor frame stays spendable here; the + // state-gas-used reduction must propagate upward separately. TGasPolicy.AddStateGasRefundToReservoir(ref gas, pendingRefund, trackSpillRefund); vmState.StateGasRefundPending += pendingRefund; vmState.StateGasRefundAdvanced += pendingRefund; @@ -995,7 +992,6 @@ private CallResult RunPrecompile(VmState state) IPrecompile precompile = state.Env.CodeInfo.Precompile!; IReleaseSpec spec = BlockExecutionContext.Spec; - // Both fields are ulong after IPrecompile.BaseGasCost / DataGasCost interface migration. ulong baseGasCost = precompile.BaseGasCost(spec); ulong dataGasCost = precompile.DataGasCost(callData, spec); @@ -1017,9 +1013,7 @@ private CallResult RunPrecompile(VmState state) _parityTouchBugAccount.ShouldDelete = true; } - // Guard against addition overflow before summing into UpdateGas. - // The previous form — (ulong)a + (ulong)b > ulong.MaxValue — was tautologically false: - // the addition already happened in ulong and silently wrapped before the comparison. + // Guard against ulong overflow before summing into UpdateGas. if (baseGasCost > ulong.MaxValue - dataGasCost || !TGasPolicy.UpdateGas(ref gas, baseGasCost + dataGasCost)) { diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 09434d4f393f..0a996851dda4 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -217,11 +217,11 @@ public void Call_uses_valid_beneficiary() Arg.Any()); } - [TestCase(7)] - [TestCase(0)] - public void Bridge_head_is_correct(long headNumber) + [TestCase(7UL)] + [TestCase(0UL)] + public void Bridge_head_is_correct(ulong headNumber) { - Block head = Build.A.Block.WithNumber((ulong)headNumber).TestObject; + Block head = Build.A.Block.WithNumber(headNumber).TestObject; Block bestSuggested = Build.A.Block.WithNumber(8UL).TestObject; _blockTree.Head.Returns(head); @@ -566,12 +566,12 @@ private static IEnumerable MinerPremiumNegativeCases() Address sender = TestItem.AddressA; UInt256 baseFee = 146_283_608_928UL; - UInt256 maxFeePerGas = 140_000_000_000UL; + ulong maxFeePerGas = 140_000_000_000UL; Transaction descriptiveTx = new() { GasLimit = 56786, SenderAddress = sender, - DecodedMaxFeePerGas = (ulong)maxFeePerGas, + DecodedMaxFeePerGas = maxFeePerGas, Type = TxType.EIP1559 }; yield return new TestCaseData( diff --git a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs index d225f194a09f..4a713787ee2c 100644 --- a/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/LogIndexBuilderTests.cs @@ -163,7 +163,7 @@ public async Task TearDownAsync() [Test] [CancelAfter(60_000)] public async Task Should_SyncToBarrier( - [Values(1, 10)] int minBarrier, + [Values(1UL, 10UL)] ulong minBarrier, [Values(1, 16, MaxBlock)] int batchSize, [Values( new[] { -1, -1 }, // -1 is treated as null @@ -177,10 +177,10 @@ CancellationToken cancellation ) { _config.MaxBatchSize = batchSize; - _syncConfig.AncientReceiptsBarrier = (ulong)minBarrier; + _syncConfig.AncientReceiptsBarrier = minBarrier; Assert.That(_syncConfig.AncientReceiptsBarrierCalc, Is.EqualTo(minBarrier)); - int expectedMin = minBarrier <= 1 ? 0 : synced[0] < 0 ? minBarrier : Math.Min(synced[0], minBarrier); + int expectedMin = minBarrier <= 1 ? 0 : synced[0] < 0 ? (int)minBarrier : Math.Min(synced[0], (int)minBarrier); TestLogIndexStorage storage = new() { MinBlockNumber = synced[0] < 0 ? null : synced[0], @@ -230,13 +230,13 @@ public async Task Should_ForwardErrorAndStopWithoutDeadlock(int failAfter) [Test] [Sequential] public async Task Should_CompleteImmediately_IfAlreadySynced( - [Values(1, 10, 10, 10)] int minBarrier, + [Values(1UL, 10UL, 10UL, 10UL)] ulong minBarrier, [Values(0, 00, 05, 10)] int minBlock ) { - Assert.That(minBlock, Is.LessThanOrEqualTo(minBarrier)); + Assert.That((ulong)minBlock, Is.LessThanOrEqualTo(minBarrier)); - _syncConfig.AncientReceiptsBarrier = (ulong)minBarrier; + _syncConfig.AncientReceiptsBarrier = minBarrier; LogIndexBuilder builder = GetService(new FailingLogIndexStorage(0, new("Should not set new receipts.")) { MinBlockNumber = minBlock, diff --git a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs index 32618d159f3a..2a7c3b61e60e 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogIndexBuilder.cs @@ -51,7 +51,7 @@ private struct DirectionStates private readonly CancellationTokenSource _cancellationSource = new(); private CancellationToken CancellationToken => _cancellationSource.Token; - private ulong MaxReorgDepth => (ulong)_config.MaxReorgDepth!.Value; + private ulong MaxReorgDepth => _config.MaxReorgDepth!.Value; private static readonly TimeSpan NewBlockWaitTimeout = TimeSpan.FromSeconds(5); private readonly ILogIndexStorage _logIndexStorage; @@ -101,9 +101,8 @@ public LogIndexBuilder(ILogIndexStorage logIndexStorage, ILogIndexConfig config, private void StartProcessing(bool isForward) { - // Do not start backward sync if the target is already reached. - // null MinBlockNumber means nothing is indexed yet — do not skip. - // Explicit null-check before ulong widening avoids wrapping a negative int to a huge ulong. + // Skip backward sync if storage already reached the target. Null MinBlockNumber + // means nothing indexed yet — must not skip. if (!isForward && _logIndexStorage.MinBlockNumber is { } minStored && (ulong)minStored <= MinTargetBlockNumber) { MarkCompleted(false); @@ -129,8 +128,6 @@ public async Task StartAsync() _receiptStorage.ReceiptsInserted += OnReceiptsInserted; - // Explicit null-pattern before widening: avoids InvalidOperationException on null, - // and prevents a negative int from wrapping to a huge ulong. TrySetPivot(_logIndexStorage.MaxBlockNumber is { } storedMax ? (ulong)storedMax : null); TrySetPivot(_blockTree.SyncPivot.BlockNumber); @@ -228,10 +225,7 @@ private bool TrySetPivot(ulong? blockNumber) if (_pivotSource.Task.IsCompleted) return false; - if (number < MinTargetBlockNumber) - number = MinTargetBlockNumber; - if (number > MaxTargetBlockNumber) - number = MaxTargetBlockNumber; + number = Math.Clamp(number, MinTargetBlockNumber, MaxTargetBlockNumber); if (number is 0) return false; @@ -248,14 +242,10 @@ private bool TrySetPivot(ulong? blockNumber) private void OnReceiptsInserted(object? sender, ReceiptsEventArgs args) { - // BlockNumber is now ulong; TrySetPivot already accepts ulong?. - ulong next = args.BlockHeader.Number; - if (TrySetPivot(next)) + if (TrySetPivot(args.BlockHeader.Number)) _receiptStorage.ReceiptsInserted -= OnReceiptsInserted; } - // CAST NOTE: LogIndexStorage uses int block numbers by design (performance). BestKnownNumber - // is ulong; the subtraction is guarded by Math.Max so the result is always >= 0 and fits in ulong. public ulong MaxTargetBlockNumber => _blockTree.BestKnownNumber >= MaxReorgDepth ? _blockTree.BestKnownNumber - MaxReorgDepth : 0UL; @@ -337,8 +327,6 @@ private async Task AddReceiptsAsync(LogIndexAggregate aggregate, bool isForward) UpdateProgress(); - // Cast to int is safe: MinTargetBlockNumber is derived from AncientReceiptsBarrierCalc which - // is a chain config value well within int range. MinBlockNumber is int by LogIndex design. if (_logIndexStorage.MinBlockNumber <= (int)MinTargetBlockNumber) MarkCompleted(false); } @@ -351,15 +339,11 @@ private async Task DoQueueBlocks(bool isForward) ProcessingQueue queue = Direction(isForward).Queue!; - // Cast to int is safe here: LogIndex storage uses int block numbers for performance. - // pivotNumber is bounded by MaxTargetBlockNumber which is derived from BestKnownNumber - // and will not exceed int.MaxValue in practice (~2 billion blocks). int start = GetNextBlockNumber(isForward) ?? (isForward ? (int)pivotNumber : (int)pivotNumber - 1); BlockReceipts[] buffer = new BlockReceipts[_config.MaxBatchSize]; while (!CancellationToken.IsCancellationRequested) { - // Cast to int is safe: MinTargetBlockNumber fits in int (see MinTargetBlockNumber property). if (!isForward && start < (int)MinTargetBlockNumber) { if (_logger.IsTrace) @@ -370,9 +354,7 @@ private async Task DoQueueBlocks(bool isForward) int batchSize = _config.MaxBatchSize; int end = isForward ? start + batchSize - 1 : start - batchSize + 1; - // Cast to int is safe: MinTargetBlockNumber/MaxTargetBlockNumber are bounded within int range for LogIndex. - end = Math.Max(end, (int)MinTargetBlockNumber); - end = Math.Min(end, (int)MaxTargetBlockNumber); + end = Math.Clamp(end, (int)MinTargetBlockNumber, (int)MaxTargetBlockNumber); // from - inclusive, to - exclusive (int from, int to) = isForward @@ -414,13 +396,9 @@ private void UpdateProgress() if (forward.Progress is { HasEnded: false } forwardProgress) { ulong bestKnown = _blockTree.BestKnownNumber; - // Guard against underflow: BestKnownNumber - MaxReorgDepth - pivotNumber + 1 - ulong forwardTarget = bestKnown >= MaxReorgDepth + pivotNumber + forwardProgress.TargetValue = bestKnown >= MaxReorgDepth + pivotNumber ? bestKnown - MaxReorgDepth - pivotNumber + 1UL : 0UL; - forwardProgress.TargetValue = forwardTarget; - // Guard against underflow: storage may not have caught up to pivotNumber yet. - // (ulong)max is safe: LogIndex MaxBlockNumber is a non-negative int by design. forwardProgress.Update(_logIndexStorage.MaxBlockNumber is { } max && (ulong)max >= pivotNumber ? (ulong)max - pivotNumber + 1UL : 0UL); @@ -430,14 +408,9 @@ private void UpdateProgress() ref DirectionState backward = ref Direction(isForward: false); if (backward.Progress is { HasEnded: false } backwardProgress) { - // Both pivotNumber and MinTargetBlockNumber are ulong; no cast needed. - // Guard against underflow: MinTargetBlockNumber should never exceed pivotNumber in normal - // operation, but we defend explicitly to avoid wrapping on ulong subtraction. backwardProgress.TargetValue = pivotNumber >= MinTargetBlockNumber ? pivotNumber - MinTargetBlockNumber : 0UL; - // (ulong)min is safe: LogIndex MinBlockNumber is a non-negative int by design. - // Guard against underflow: min should never exceed pivotNumber in normal operation. backwardProgress.Update(_logIndexStorage.MinBlockNumber is { } min && pivotNumber >= (ulong)min ? pivotNumber - (ulong)min : 0UL); @@ -471,9 +444,6 @@ private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts if (to - from > buffer.Length) throw new InvalidOperationException($"{GetLogPrefix()}: buffer size is too small: {buffer.Length} / {to - from}"); - // LogIndex uses int block numbers internally for performance. The checked cast from int to - // ulong is safe here because 'from' and 'to' are always non-negative LogIndex int values - // (bounded by MinTargetBlockNumber / MaxTargetBlockNumber checks in DoQueueBlocks). int nextIndex = isForward ? from : to - 1; if (!TryGetBlockReceipts((ulong)nextIndex, out buffer[0])) return ReadOnlySpan.Empty; @@ -485,25 +455,19 @@ private ReadOnlySpan GetNextBatch(int from, int to, BlockReceipts }, i => { int bufferIndex = isForward ? i - from : to - 1 - i; - // Cast to ulong is safe: i is a non-negative LogIndex int block number (see above). if (buffer[bufferIndex] == default) TryGetBlockReceipts((ulong)i, out buffer[bufferIndex]); }); - // Array.IndexOf returns int; -1 means no default element found (full buffer valid). int endIndex = Array.IndexOf(buffer, default); return endIndex < 0 ? buffer : buffer.AsSpan(..endIndex); } // TODO: move to IReceiptStorage? - // CAST NOTE: blockNumber is a LogIndex int block number promoted to ulong at the call site. - // LogIndex intentionally keeps int internally for performance; the caller is responsible for - // ensuring the value is non-negative before widening (guaranteed by DoQueueBlocks bounds checks). private bool TryGetBlockReceipts(ulong blockNumber, out BlockReceipts blockReceipts) { blockReceipts = default; - // BlockNumber is now ulong throughout the codebase; no cast needed here. if (_blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.ExcludeTxHashes) is not { Hash: not null } block) { return false; @@ -511,7 +475,6 @@ private bool TryGetBlockReceipts(ulong blockNumber, out BlockReceipts blockRecei if (!block.Header.HasTransactions) { - // Cast back to int is safe: blockNumber originates from a LogIndex int (see above). blockReceipts = new((int)blockNumber, []); return true; } @@ -523,7 +486,6 @@ private bool TryGetBlockReceipts(ulong blockNumber, out BlockReceipts blockRecei return false; // block should have transactions but nothing in storage } - // Cast back to int is safe: blockNumber originates from a LogIndex int (see above). blockReceipts = new((int)blockNumber, receipts); return true; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index c29364813341..5f11d1d6becf 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -16,8 +16,6 @@ public sealed class SimulateBlockhashProvider(IBlockhashProvider blockhashProvid { public Hash256? GetBlockhash(BlockHeader currentBlock, ulong number, IReleaseSpec spec) { - // CAST NOTE: BestKnownNumber is ulong; safe to cast to long for blockhash lookup since - // block numbers reachable by the blockhash opcode are well within long range. ulong bestKnown = blockTree.BestKnownNumber; return bestKnown < number && blockTree.BestSuggestedHeader is not null ? blockhashProvider.GetBlockhash(blockTree.BestSuggestedHeader!, bestKnown, spec) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 0700c323eb7f..f9fbe3e6bd9b 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -237,7 +237,6 @@ private static BlockHeader GetParent(BlockHeader parent, SimulatePayload 0 && firstBlock.BlockOverrides?.Number < lastKnown) { - // CAST NOTE: firstBlock.BlockOverrides.Number is ulong and > 0, so subtracting 1 is safe. Block? searchResult = blockTree.FindBlock(firstBlock.BlockOverrides.Number.Value - 1); if (searchResult is not null) { diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs index 7afa2f8bb431..e402c67b9ca5 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs @@ -71,11 +71,9 @@ public IOwnedReadOnlyList FindReversedHeaders(ulong endBlockNumber, if (cursor is null) return ArrayPoolList.Empty(); ArrayPoolList result = new(count) { cursor }; - while (result.Count < count && cursor.ParentHash is not null) + while (result.Count < count && cursor.ParentHash is not null && cursor.Number > 0) { - // Safe subtraction: block 0 has no parent, so cursor.Number > 0 here - ulong parentNumber = cursor.Number > 0 ? cursor.Number - 1 : 0; - cursor = Get(cursor.ParentHash, shouldCache: false, blockNumber: parentNumber); + cursor = Get(cursor.ParentHash, shouldCache: false, blockNumber: cursor.Number - 1); if (cursor is null) break; result.Add(cursor); } diff --git a/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs b/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs index 264f5a6f8f5f..fefe17693ad9 100644 --- a/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/BlockTreeModule.cs @@ -50,7 +50,7 @@ protected override void Load(ContainerBuilder builder) .AddDecorator((ctx, config) => { IPruningConfig pruningConfig = ctx.Resolve(); - config.MaxReorgDepth ??= (int)pruningConfig.PruningBoundary; + config.MaxReorgDepth ??= pruningConfig.PruningBoundary; return config; }); diff --git a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs index f7d9aea04e0f..af546409308a 100644 --- a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs +++ b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs @@ -122,7 +122,7 @@ ILogManager logManager if (syncConfig.SnapServingEnabled == true && pruningConfig.PruningBoundary < syncConfig.SnapServingMaxDepth) { - logIndexConfig.MaxReorgDepth ??= (int)pruningConfig.PruningBoundary; + logIndexConfig.MaxReorgDepth ??= pruningConfig.PruningBoundary; if (_logger.IsInfo) _logger.Info($"Snap serving enabled, but {nameof(pruningConfig.PruningBoundary)} is less than {syncConfig.SnapServingMaxDepth}. Setting to {syncConfig.SnapServingMaxDepth}."); pruningConfig.PruningBoundary = syncConfig.SnapServingMaxDepth; From 441a4aa0fbc04d610eed491c047c3efa3cfe201a Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 16:05:58 +0200 Subject: [PATCH 41/60] review: ulong-ify retention spec + RLP encode(ulong), SaturatingSub usages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IReleaseSpec.MinHistoryRetentionEpochs / MinBalRetentionEpochs long → ulong cascades through ReleaseSpec / ReleaseSpecDecorator / OverridableReleaseSpec / ChainParameters / ChainSpecParamsJson. HistoryPruner's local fields and the matching test parameters move to ulong end-to-end. Rlp.Encode now has a dedicated ulong overload (mirrors the long one minus the negative-value branch); HistoryPruner stops casting to long when persisting the delete pointers. ValidateSubmissionHandler / HistoryPruner: replace the `x > 0 ? x - 1 : 0` and `a > b ? a - b : 0` patterns with the existing `ulong.SaturatingSub` extension; strips the explanatory underflow-guard comments. BlockchainBridge.RunEstimateGas: - (UInt256)tx.ValueRef → tx.ValueRef (ref readonly auto-dereferences). - (ulong)UInt256.Min(...) → UInt256.Min(...).u0 (Min already caps at ulong.MaxValue, so .u0 is the value without the wrapping cast). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Nethermind.Core/Specs/IReleaseSpec.cs | 4 ++-- .../Nethermind.Core/Specs/ReleaseSpecDecorator.cs | 4 ++-- .../Nethermind.Facade/BlockchainBridge.cs | 4 ++-- .../Handlers/ValidateSubmissionHandler.cs | 7 ++----- .../Nethermind.History.Test/HistoryPrunerTests.cs | 10 +++++----- src/Nethermind/Nethermind.History/HistoryPruner.cs | 4 ++-- src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs | 14 ++++++++++++++ .../OverridableReleaseSpec.cs | 4 ++-- .../ChainSpecStyle/ChainParameters.cs | 4 ++-- .../ChainSpecStyle/Json/ChainSpecParamsJson.cs | 4 ++-- src/Nethermind/Nethermind.Specs/ReleaseSpec.cs | 4 ++-- 11 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index a1aabff44c6b..387b2bddef4b 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -17,8 +17,8 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec long MaximumExtraDataSize { get; } long MaxCodeSize { get; } ulong MinGasLimit { get; } - long MinHistoryRetentionEpochs { get; } - long MinBalRetentionEpochs { get; } + ulong MinHistoryRetentionEpochs { get; } + ulong MinBalRetentionEpochs { get; } ulong GasLimitBoundDivisor { get; } UInt256 BlockReward { get; } ulong DifficultyBombDelay { get; } diff --git a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs index 064ab6ad800d..c466eae2dd4b 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs @@ -13,8 +13,8 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual long MaximumExtraDataSize => spec.MaximumExtraDataSize; public virtual long MaxCodeSize => spec.MaxCodeSize; public virtual ulong MinGasLimit => spec.MinGasLimit; - public virtual long MinHistoryRetentionEpochs => spec.MinHistoryRetentionEpochs; - public virtual long MinBalRetentionEpochs => spec.MinBalRetentionEpochs; + public virtual ulong MinHistoryRetentionEpochs => spec.MinHistoryRetentionEpochs; + public virtual ulong MinBalRetentionEpochs => spec.MinBalRetentionEpochs; public virtual ulong GasLimitBoundDivisor => spec.GasLimitBoundDivisor; public virtual UInt256 BlockReward => spec.BlockReward; public virtual ulong DifficultyBombDelay => spec.DifficultyBombDelay; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 77205c662a12..5873c567e8c8 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -228,12 +228,12 @@ private CallOutput RunEstimateGas(IStateReader nonceReader, ITransactionProcesso IReleaseSpec spec = specProvider.GetSpec(header.Number + 1, header.Timestamp + blocksConfig.SecondsPerSlot); UInt256 senderBalance = worldState.GetBalance(tx.SenderAddress ?? Address.Zero); UInt256 feeCap = tx.CalculateFeeCap(); - if (feeCap > UInt256.Zero && !UInt256.SubtractUnderflow(senderBalance, (UInt256)tx.ValueRef, out UInt256 availableForGas)) + if (feeCap > UInt256.Zero && !UInt256.SubtractUnderflow(senderBalance, tx.ValueRef, out UInt256 availableForGas)) { if (!BlobGasCalculator.TrySubtractBlobFee(spec, tx, ref availableForGas)) availableForGas = UInt256.Zero; - ulong allowance = (ulong)UInt256.Min(availableForGas / feeCap, (UInt256)ulong.MaxValue); + ulong allowance = UInt256.Min(availableForGas / feeCap, ulong.MaxValue).u0; if (tx.GasLimit > allowance) tx.GasLimit = allowance; } diff --git a/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs b/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs index 9e86c5d537bc..67976d636077 100644 --- a/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs +++ b/src/Nethermind/Nethermind.Flashbots/Handlers/ValidateSubmissionHandler.cs @@ -8,6 +8,7 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Evm; @@ -292,11 +293,7 @@ private ulong GetGasLimit(BlockHeader parentHeader, ulong desiredGasLimit, IRele ulong gasLimit = parentGasLimit; ulong newBlockNumber = parentHeader.Number + 1; - // Non-trivial: GasLimitBoundDivisor is a positive ulong; dividing a ulong by it is safe. - // The subtraction `/ divisor - 1` could underflow if parentGasLimit < divisor, hence - // the Math.Max(0, ...) guard — replicated here using ulong-safe clamping. - ulong rawDiff = parentGasLimit / releaseSpec.GasLimitBoundDivisor; - ulong maxGasLimitDifference = rawDiff > 0 ? rawDiff - 1 : 0; + ulong maxGasLimitDifference = (parentGasLimit / releaseSpec.GasLimitBoundDivisor).SaturatingSub(1); if (desiredGasLimit > parentGasLimit) { diff --git a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs index 6851d24fd459..2a47074b7da6 100644 --- a/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs +++ b/src/Nethermind/Nethermind.History.Test/HistoryPrunerTests.cs @@ -257,11 +257,11 @@ public async Task Does_not_prune_when_disabled() CheckHeadPreserved(testBlockchain, blocks); } - [TestCase(0, 100000u, 0L, 3533u, false)] - [TestCase(100, 10u, 0L, 3533u, true)] // block retention below min - [TestCase(0, 100000u, 3533L, 3000u, true)] // BAL retention below min - [TestCase(0, 100000u, 3533L, 3533u, false)] // BAL retention exactly at min - public void Validates_config(int minHistoryRetentionEpochs, uint retentionEpochs, long minBalRetentionEpochs, uint balRetentionEpochs, bool shouldThrow) + [TestCase(0UL, 100000u, 0UL, 3533u, false)] + [TestCase(100UL, 10u, 0UL, 3533u, true)] // block retention below min + [TestCase(0UL, 100000u, 3533UL, 3000u, true)] // BAL retention below min + [TestCase(0UL, 100000u, 3533UL, 3533u, false)] // BAL retention exactly at min + public void Validates_config(ulong minHistoryRetentionEpochs, uint retentionEpochs, ulong minBalRetentionEpochs, uint balRetentionEpochs, bool shouldThrow) { IHistoryConfig historyConfig = new HistoryConfig { diff --git a/src/Nethermind/Nethermind.History/HistoryPruner.cs b/src/Nethermind/Nethermind.History/HistoryPruner.cs index a487e4190129..40d69e0d3fcf 100644 --- a/src/Nethermind/Nethermind.History/HistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/HistoryPruner.cs @@ -44,8 +44,8 @@ public class HistoryPruner : IHistoryPruner private readonly bool _enabled; private readonly ulong _pruningInterval; // MinHistoryRetentionEpochs / MinBalRetentionEpochs come from IReleaseSpec which still returns long. - private readonly long _minHistoryRetentionEpochs; - private readonly long _minBalRetentionEpochs; + private readonly ulong _minHistoryRetentionEpochs; + private readonly ulong _minBalRetentionEpochs; private readonly ulong _ancientBarrier; private readonly ulong _minDeletableBlockNumber; diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs index 84cc8eb3488b..ed0b6bde15d7 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs @@ -309,6 +309,20 @@ public static Rlp Encode(int value) _ => new([136, (byte)(value >> 56), (byte)(value >> 48), (byte)(value >> 40), (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), }; + public static Rlp Encode(ulong value) => value switch + { + 0UL => OfZero, + < 0x80 => new((byte)value), + < 0x100 => new([129, (byte)value]), + < 0x1_0000 => new([130, (byte)(value >> 8), (byte)value]), + < 0x100_0000 => new([131, (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + < 0x1_0000_0000 => new([132, (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + < 0x100_0000_0000 => new([133, (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + < 0x1_0000_0000_0000 => new([134, (byte)(value >> 40), (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + < 0x100_0000_0000_0000 => new([135, (byte)(value >> 48), (byte)(value >> 40), (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + _ => new([136, (byte)(value >> 56), (byte)(value >> 48), (byte)(value >> 40), (byte)(value >> 32), (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value]), + }; + // caller is responsible for allocating buffer large enough (max 9 bytes) [SuppressMessage("ReSharper", "IntVariableOverflowInUncheckedContext")] public static Span Encode(ulong value, Span buffer) diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index ea1205b3d0c6..1bb8ed7cf92c 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -19,8 +19,8 @@ public class OverridableReleaseSpec(IReleaseSpec spec) : IReleaseSpec public long MaximumExtraDataSize { get; set; } = spec.MaximumExtraDataSize; public long MaxCodeSize { get; set; } = spec.MaxCodeSize; public ulong MinGasLimit { get; set; } = spec.MinGasLimit; - public long MinHistoryRetentionEpochs { get; set; } = spec.MinHistoryRetentionEpochs; - public long MinBalRetentionEpochs { get; set; } = spec.MinBalRetentionEpochs; + public ulong MinHistoryRetentionEpochs { get; set; } = spec.MinHistoryRetentionEpochs; + public ulong MinBalRetentionEpochs { get; set; } = spec.MinBalRetentionEpochs; public ulong GasLimitBoundDivisor { get; set; } = spec.GasLimitBoundDivisor; public UInt256 BlockReward { get; set; } = spec.BlockReward; public ulong DifficultyBombDelay { get; set; } = spec.DifficultyBombDelay; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs index e74436186982..1c37f77f75ef 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs @@ -18,8 +18,8 @@ public class ChainParameters public Address Registrar { get; set; } public long MaximumExtraDataSize { get; set; } public ulong MinGasLimit { get; set; } - public long MinHistoryRetentionEpochs { get; set; } - public long MinBalRetentionEpochs { get; set; } + public ulong MinHistoryRetentionEpochs { get; set; } + public ulong MinBalRetentionEpochs { get; set; } public Hash256 ForkCanonHash { get; set; } public ulong? ForkBlock { get; set; } public ulong? Eip7Transition { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs index 58c15033acb0..10a74c673cf2 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs @@ -28,9 +28,9 @@ public class ChainSpecParamsJson : IHasNamedForks public ulong? MinGasLimit { get; set; } - public long? MinHistoryRetentionEpochs { get; set; } + public ulong? MinHistoryRetentionEpochs { get; set; } - public long? MinBalRetentionEpochs { get; set; } + public ulong? MinBalRetentionEpochs { get; set; } public ulong? ForkBlock { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs index 1a88cfd807a6..7550981050f3 100644 --- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs @@ -18,8 +18,8 @@ public class ReleaseSpec : IReleaseSpec public long MaximumExtraDataSize { get; set; } public long MaxCodeSize { get; set; } public ulong MinGasLimit { get; set; } - public long MinHistoryRetentionEpochs { get; set; } - public long MinBalRetentionEpochs { get; set; } + public ulong MinHistoryRetentionEpochs { get; set; } + public ulong MinBalRetentionEpochs { get; set; } public ulong GasLimitBoundDivisor { get; set; } public UInt256 BlockReward { get; set; } public ulong DifficultyBombDelay { get; set; } From 9ee3a91661b6c1529f0050ffd786771adab5fc12 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 16:21:21 +0200 Subject: [PATCH 42/60] review: restore Json converter special cases; ulong MemoryHint/MaxGasLimit/MaxBlockGas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Serialization.Json: - LongConverter / ULongConverter FromString(string): restore master's shape with the Bytes.ZeroHexValue fast path and the StartsWith("0x0") vs StartsWith("0x") branch (which prepends "0" to even out the hex length for long.Parse). The PR had simplified this to a single AllowHexSpecifier call that wrapped Bytes.WithoutLeadingZeros input inconsistently. - LongConverter / ULongConverter ReadCore + ReadAsPropertyName: call FromString(span) instead of NumericConverterHelper.Parse directly, so the converter's public API stays the boundary. - NumericConverterHelper.Parse: restore the "0x0"u8 SequenceEqual fast-path — micro-opt for the most common JSON-RPC zero value (skips TryParse for ~half of get-block/get-receipt traffic). - Long/ULongRawJsonConverter Read: delegate to LongConverter.ReadCore / ULongConverter.ReadCore (matches master). The PR had inlined a duplicate, simpler parser that skipped the special cases. - NullableLongConverter / NullableRawULongConverter Read: collapse the if/else block to a one-line ternary. Config: - IInitConfig.MemoryHint long? → ulong? (cascades through InitConfig, MemoryHintMan, and the corresponding tests / TestCase literals). - IBlocksConfig.MaxGasLimit long → ulong (cascades through BlocksConfig and the ConfigFilesTests assertion). - RlpLimit.MaxBlockGas / InitMaxBlockGas long → ulong; drops the (ulong) cast in BlockBodyDecoder.TransactionsCountLimit and SetCodeTxDecoder.AuthorizationListLimit. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Nethermind/Nethermind.Api/IInitConfig.cs | 2 +- src/Nethermind/Nethermind.Api/InitConfig.cs | 2 +- .../Nethermind.Config/BlocksConfig.cs | 2 +- .../Nethermind.Config/IBlocksConfig.cs | 2 +- .../ConfigFilesTests.cs | 24 ++++++++-------- .../MemoryHintManTests.cs | 24 ++++++++-------- .../LongConverter.cs | 22 ++++++++++++--- .../LongRawJsonConverter.cs | 24 +--------------- .../NullableLongConvertercs.cs | 28 +++---------------- .../NumericConverterHelper.cs | 6 ++++ .../ULongConverter.cs | 21 +++++++++++--- .../ULongRawJsonConverter.cs | 24 +--------------- .../BlockBodyDecoder.cs | 2 +- .../Nethermind.Serialization.Rlp/RlpLimit.cs | 4 +-- .../TxDecoders/SetCodeTxDecoder.cs | 2 +- 15 files changed, 79 insertions(+), 110 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/IInitConfig.cs b/src/Nethermind/Nethermind.Api/IInitConfig.cs index f687aab856a5..ff43d502ed8d 100644 --- a/src/Nethermind/Nethermind.Api/IInitConfig.cs +++ b/src/Nethermind/Nethermind.Api/IInitConfig.cs @@ -67,7 +67,7 @@ public interface IInitConfig : IConfig string RpcDbUrl { get; set; } [ConfigItem(Description = "The hint on the max memory limit, in bytes, to configure the database and networking memory allocations.", DefaultValue = "null")] - long? MemoryHint { get; set; } + ulong? MemoryHint { get; set; } [ConfigItem(Description = "The maximum number of bad blocks observed on the network that will be stored on disk.", DefaultValue = "100")] long? BadBlocksStored { get; set; } diff --git a/src/Nethermind/Nethermind.Api/InitConfig.cs b/src/Nethermind/Nethermind.Api/InitConfig.cs index 1527f3640a16..97c5aed4be8b 100644 --- a/src/Nethermind/Nethermind.Api/InitConfig.cs +++ b/src/Nethermind/Nethermind.Api/InitConfig.cs @@ -30,7 +30,7 @@ public class InitConfig : IInitConfig public DumpOptions AutoDump { get; set; } = DumpOptions.Default; public string RpcDbUrl { get; set; } = string.Empty; - public long? MemoryHint { get; set; } + public ulong? MemoryHint { get; set; } public long? BadBlocksStored { get; set; } = 100; public bool DisableGcOnNewPayload { get; set; } = true; public bool DisableMallocOpts { get; set; } = false; diff --git a/src/Nethermind/Nethermind.Config/BlocksConfig.cs b/src/Nethermind/Nethermind.Config/BlocksConfig.cs index a23b12e384f9..a9c6fea93bf2 100644 --- a/src/Nethermind/Nethermind.Config/BlocksConfig.cs +++ b/src/Nethermind/Nethermind.Config/BlocksConfig.cs @@ -108,6 +108,6 @@ public string ExtraData public long SlowBlockPerTxThresholdMs { get; set; } = -1; - public long MaxGasLimit { get; set; } = 1_000_000_000; + public ulong MaxGasLimit { get; set; } = 1_000_000_000; } } diff --git a/src/Nethermind/Nethermind.Config/IBlocksConfig.cs b/src/Nethermind/Nethermind.Config/IBlocksConfig.cs index ddfc5eb92ca2..74018c8a37f3 100644 --- a/src/Nethermind/Nethermind.Config/IBlocksConfig.cs +++ b/src/Nethermind/Nethermind.Config/IBlocksConfig.cs @@ -95,5 +95,5 @@ public interface IBlocksConfig : IConfig "Used to inherit some RLP limits. ", DefaultValue = "1000000000", HiddenFromDocs = true)] - long MaxGasLimit { get; set; } + ulong MaxGasLimit { get; set; } } diff --git a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs index 1b5ba8576459..da0db56f41b8 100644 --- a/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/ConfigFilesTests.cs @@ -91,17 +91,17 @@ public void Ethstats_values_are_correct(string configWildcard, string host) [TestCase("*")] public void Eth_stats_disabled_by_default(string configWildcard) => Test(configWildcard, static c => c.Enabled, false); - [TestCase("mainnet archive", 4096000000)] - [TestCase("mainnet ^archive", 1024000000)] - [TestCase("volta archive", 768000000)] - [TestCase("volta ^archive", 768000000)] - [TestCase("gnosis archive", 1024000000)] - [TestCase("gnosis ^archive", 768000000)] - [TestCase("poacore archive", 1024000000)] - [TestCase("poacore ^archive", 768000000)] - [TestCase("spaceneth.json", 64000000)] - [TestCase("spaceneth_persistent.json", 128000000)] - public void Memory_hint_values_are_correct(string configWildcard, long expectedValue) => Test(configWildcard, static c => c.MemoryHint, expectedValue); + [TestCase("mainnet archive", 4096000000UL)] + [TestCase("mainnet ^archive", 1024000000UL)] + [TestCase("volta archive", 768000000UL)] + [TestCase("volta ^archive", 768000000UL)] + [TestCase("gnosis archive", 1024000000UL)] + [TestCase("gnosis ^archive", 768000000UL)] + [TestCase("poacore archive", 1024000000UL)] + [TestCase("poacore ^archive", 768000000UL)] + [TestCase("spaceneth.json", 64000000UL)] + [TestCase("spaceneth_persistent.json", 128000000UL)] + public void Memory_hint_values_are_correct(string configWildcard, ulong expectedValue) => Test(configWildcard, static c => c.MemoryHint, expectedValue); [TestCase("*")] public void Metrics_disabled_by_default(string configWildcard) @@ -334,7 +334,7 @@ public void TargetBlockGasLimit_does_not_exceed_DefaultMaxBlockGasLimit() Test("*", static c => c.TargetBlockGasLimit, (configFile, value) => { if (value is not null) - Assert.That(value.Value, Is.LessThanOrEqualTo((ulong)defaultConfig.MaxGasLimit), configFile); + Assert.That(value.Value, Is.LessThanOrEqualTo(defaultConfig.MaxGasLimit), configFile); }); } diff --git a/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs b/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs index 8501a5196276..74e005f1da08 100755 --- a/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/MemoryHintManTests.cs @@ -19,8 +19,8 @@ namespace Nethermind.Runner.Test [TestFixture] public class MemoryHintManTests { - private const long GB = 1000 * 1000 * 1000; - private const long MB = 1000 * 1000; + private const ulong GB = 1000 * 1000 * 1000; + private const ulong MB = 1000 * 1000; private IDbConfig _dbConfig; private ISyncConfig _syncConfig; @@ -60,11 +60,11 @@ private void SetMemoryAllowances(uint cpuCount) => _memoryHintMan.SetMemoryAllow [TestCase(2000 * MB, 12u, 24u, 10)] [TestCase(1000 * MB, 12u, 8u, 11)] [TestCase(2000 * MB, 12u, 8u, 11)] - public void Netty_arena_order_is_configured_correctly(long memoryHint, uint cpuCount, uint maxArenaCount, int expectedArenaOrder) + public void Netty_arena_order_is_configured_correctly(ulong memoryHint, uint cpuCount, uint maxArenaCount, int expectedArenaOrder) { _txPoolConfig.Size = 128; _initConfig.DiagnosticMode = DiagnosticMode.MemDb; - _initConfig.MemoryHint = (long)memoryHint; + _initConfig.MemoryHint = memoryHint; _networkConfig.MaxNettyArenaCount = maxArenaCount; SetMemoryAllowances(cpuCount); Assert.That(_networkConfig.NettyArenaOrder, Is.EqualTo(expectedArenaOrder)); @@ -73,12 +73,12 @@ public void Netty_arena_order_is_configured_correctly(long memoryHint, uint cpuC [Test] public void Db_size_are_computed_correctly( [Values(256 * MB, 512 * MB, 1 * GB, 4 * GB, 6 * GB, 16 * GB, 32 * GB, 64 * GB, 128 * GB)] - long memoryHint, + ulong memoryHint, [Values(1u, 2u, 3u, 4u, 8u, 32u)] uint cpuCount, [Values(true, false)] bool fastSync) { // OK to throw here - if (memoryHint == 256.MB) + if (memoryHint == (ulong)256.MB) { _txPoolConfig.Size = 128; _initConfig.DiagnosticMode = DiagnosticMode.MemDb; @@ -90,17 +90,17 @@ public void Db_size_are_computed_correctly( SyncConfig syncConfig = new(); syncConfig.FastSync = fastSync; - Assert.That(_memoryHintMan.DbMemory, Is.GreaterThan((ulong)((memoryHint - 100.MB) * 0.5))); - Assert.That(_memoryHintMan.DbMemory, Is.LessThan((ulong)((memoryHint - 100.MB) * 0.9))); + Assert.That(_memoryHintMan.DbMemory, Is.GreaterThan((ulong)((memoryHint - (ulong)100.MB) * 0.5))); + Assert.That(_memoryHintMan.DbMemory, Is.LessThan((ulong)((memoryHint - (ulong)100.MB) * 0.9))); } [TestCase(100 * GB, 16u, -1)] [TestCase(100 * GB, 16u, 1)] [TestCase(384 * MB, 1u, -1)] [TestCase(384 * MB, 1u, 1)] - public void Will_not_change_non_default_arena_order(long memoryHint, uint cpuCount, int differenceFromDefault) + public void Will_not_change_non_default_arena_order(ulong memoryHint, uint cpuCount, int differenceFromDefault) { - _initConfig.MemoryHint = (long)memoryHint; + _initConfig.MemoryHint = memoryHint; int manuallyConfiguredArenaOrder = INetworkConfig.DefaultNettyArenaOrder + differenceFromDefault; _networkConfig.NettyArenaOrder = manuallyConfiguredArenaOrder; SetMemoryAllowances(cpuCount); @@ -108,7 +108,7 @@ public void Will_not_change_non_default_arena_order(long memoryHint, uint cpuCou } [TestCase(4 * GB, 0u)] - public void Incorrect_input_throws(long memoryHint, uint cpuCount) + public void Incorrect_input_throws(ulong memoryHint, uint cpuCount) { _initConfig.MemoryHint = memoryHint; Assert.Throws( @@ -116,7 +116,7 @@ public void Incorrect_input_throws(long memoryHint, uint cpuCount) } [TestCase(500 * GB)] - public void Big_value_at_memory_hint(long memoryHint) + public void Big_value_at_memory_hint(ulong memoryHint) { _initConfig.MemoryHint = memoryHint; SetMemoryAllowances(1); diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs index 3dcc2cae7fde..76765d160584 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongConverter.cs @@ -9,6 +9,7 @@ using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; +using Nethermind.Core.Extensions; namespace Nethermind.Serialization.Json; @@ -21,18 +22,31 @@ public static long FromString(string s) throw new JsonException("null cannot be assigned to long"); } - if (s.StartsWith("0x")) + if (s == Bytes.ZeroHexValue) + { + return 0L; + } + + if (s.StartsWith("0x0")) { return long.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); } + if (s.StartsWith("0x")) + { + Span withZero = new(new char[s.Length - 1]); + withZero[0] = '0'; + s.AsSpan(2).CopyTo(withZero[1..]); + return long.Parse(withZero, NumberStyles.AllowHexSpecifier); + } + return long.Parse(s, NumberStyles.Integer); } public override long ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - return NumericConverterHelper.Parse(hex); + return FromString(hex); } public static long FromString(ReadOnlySpan s) => NumericConverterHelper.Parse(s); @@ -47,8 +61,8 @@ internal static long ReadCore(ref Utf8JsonReader reader) if (reader.TokenType == JsonTokenType.String) { return !reader.HasValueSequence - ? NumericConverterHelper.Parse(reader.ValueSpan) - : NumericConverterHelper.Parse(reader.ValueSequence.ToArray()); + ? FromString(reader.ValueSpan) + : FromString(reader.ValueSequence.ToArray()); } ThrowJsonException(); diff --git a/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs index 1972b011a8cc..fae6524caaf2 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/LongRawJsonConverter.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -#nullable enable using System; using System.Text.Json; using System.Text.Json.Serialization; @@ -13,28 +12,7 @@ public class LongRawJsonConverter : JsonConverter public override long Read( ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Number) - { - return reader.GetInt64(); - } - - if (reader.TokenType == JsonTokenType.String) - { - string? s = reader.GetString(); - if (s is not null) - { - if (s.StartsWith("0x")) - { - return long.Parse(s.AsSpan(2), System.Globalization.NumberStyles.AllowHexSpecifier); - } - return long.Parse(s, System.Globalization.NumberStyles.Integer); - } - } - - throw new JsonException(); - } + JsonSerializerOptions options) => LongConverter.ReadCore(ref reader); public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs b/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs index 1c091ecaf006..adf42c2ed7d7 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NullableLongConvertercs.cs @@ -13,18 +13,8 @@ public class NullableRawLongConverter : JsonConverter { private readonly LongConverter _converter = new(); - public override long? Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Null) - { - return null; - } - - return _converter.Read(ref reader, typeToConvert, options); - } + public override long? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + reader.TokenType == JsonTokenType.Null ? null : _converter.Read(ref reader, typeToConvert, options); public override void Write( Utf8JsonWriter writer, @@ -46,18 +36,8 @@ public class NullableRawULongConverter : JsonConverter { private readonly ULongConverter _converter = new(); - public override ulong? Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Null) - { - return null; - } - - return _converter.Read(ref reader, typeToConvert, options); - } + public override ulong? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + reader.TokenType == JsonTokenType.Null ? null : _converter.Read(ref reader, typeToConvert, options); public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs index 0ed2b38c9ac7..433b08861ad0 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/NumericConverterHelper.cs @@ -28,6 +28,12 @@ public static T Parse(ReadOnlySpan s) where T : struct, INumberBase ThrowNullAssignment(typeof(T).Name); } + // Fast path for the canonical zero — skips TryParse for the most common JSON-RPC value. + if (s.SequenceEqual("0x0"u8)) + { + return T.Zero; + } + if (s.StartsWith("0x"u8)) { s = s[2..]; diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index e81c3ebc4bab..073ebc977318 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -20,11 +20,24 @@ public static ulong FromString(string s) { ArgumentNullException.ThrowIfNull(s); - if (s.StartsWith("0x")) + if (s == Nethermind.Core.Extensions.Bytes.ZeroHexValue) + { + return 0UL; + } + + if (s.StartsWith("0x0")) { return ulong.Parse(s.AsSpan(2), NumberStyles.AllowHexSpecifier); } + if (s.StartsWith("0x")) + { + Span withZero = new(new char[s.Length - 1]); + withZero[0] = '0'; + s.AsSpan(2).CopyTo(withZero[1..]); + return ulong.Parse(withZero, NumberStyles.AllowHexSpecifier); + } + return ulong.Parse(s, NumberStyles.Integer); } @@ -44,8 +57,8 @@ internal static ulong ReadCore(ref Utf8JsonReader reader) if (reader.TokenType == JsonTokenType.String) { return !reader.HasValueSequence - ? NumericConverterHelper.Parse(reader.ValueSpan) - : NumericConverterHelper.Parse(reader.ValueSequence.ToArray()); + ? FromString(reader.ValueSpan) + : FromString(reader.ValueSequence.ToArray()); } ThrowJsonException(); @@ -63,6 +76,6 @@ public override ulong Read( public override ulong ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan hex = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - return NumericConverterHelper.Parse(hex); + return FromString(hex); } } diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs index a40189087a0c..06107e788c41 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongRawJsonConverter.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -#nullable enable using System; using System.Text.Json; using System.Text.Json.Serialization; @@ -13,28 +12,7 @@ public class ULongRawJsonConverter : JsonConverter public override ulong Read( ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Number) - { - return reader.GetUInt64(); - } - - if (reader.TokenType == JsonTokenType.String) - { - string? s = reader.GetString(); - if (s is not null) - { - if (s.StartsWith("0x")) - { - return ulong.Parse(s.AsSpan(2), System.Globalization.NumberStyles.AllowHexSpecifier); - } - return ulong.Parse(s, System.Globalization.NumberStyles.Integer); - } - } - - throw new JsonException(); - } + JsonSerializerOptions options) => ULongConverter.ReadCore(ref reader); public override void Write( Utf8JsonWriter writer, diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/BlockBodyDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/BlockBodyDecoder.cs index fe517413b088..f4008f78cabe 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/BlockBodyDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/BlockBodyDecoder.cs @@ -10,7 +10,7 @@ namespace Nethermind.Serialization.Rlp; public sealed class BlockBodyDecoder(IHeaderDecoder? headerDecoder = null) : RlpDecoder { private static RlpLimit TransactionsCountLimit => RlpLimit.For( - checked((int)((ulong)RlpLimit.MaxBlockGas / GasCostOf.Transaction + 1)), + checked((int)(RlpLimit.MaxBlockGas / GasCostOf.Transaction + 1)), nameof(BlockBody.Transactions) ); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/RlpLimit.cs b/src/Nethermind/Nethermind.Serialization.Rlp/RlpLimit.cs index 196347cf949d..8c2facd8af5a 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/RlpLimit.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/RlpLimit.cs @@ -23,8 +23,8 @@ public record struct RlpLimit(int Limit, string TypeName = "", ReadOnlyMemory - public static long MaxBlockGas { get; private set; } = 1_000_000_000; - public static void InitMaxBlockGas(long maxBlockGas) => MaxBlockGas = maxBlockGas; + public static ulong MaxBlockGas { get; private set; } = 1_000_000_000; + public static void InitMaxBlockGas(ulong maxBlockGas) => MaxBlockGas = maxBlockGas; public RlpLimit() : this((int)4.MiB) { } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/SetCodeTxDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/SetCodeTxDecoder.cs index c518850b8313..36a14072a61c 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/SetCodeTxDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoders/SetCodeTxDecoder.cs @@ -10,7 +10,7 @@ public sealed class SetCodeTxDecoder(Func? transactionFactory = null) : BaseEIP1559TxDecoder(TxType.SetCode, transactionFactory) where T : Transaction, new() { private static RlpLimit AuthorizationListLimit => RlpLimit.For( - checked((int)((ulong)RlpLimit.MaxBlockGas / GasCostOf.PerAuthBaseCost + 1)), + checked((int)(RlpLimit.MaxBlockGas / GasCostOf.PerAuthBaseCost + 1)), nameof(Transaction.AuthorizationList) ); From 553420f423dd2d0296c37fad2e1716e11eb04ba1 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 16:48:14 +0200 Subject: [PATCH 43/60] review: more ulong cascades + SaturatingSub + ToULong byte-span helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit State/Snap: - LastNStateRootTracker / FlatStateRootIndex: _lastN int → ulong; ctors take ulong; PruningTrieStateFactory + FlatWorldStateModule drop the (int)SnapServingMaxDepth casts at construction. JsonRpc/Eth: - GasPriceOracle.GetBlocks: collapsed the while(true)+post-yield-break into a do-while(currentBlockNumber-- != 0). Merge.Plugin: - BeaconPivot.PivotDestinationNumber: replace the `>= Reorganization. MaxDepth ? a - b + 1 : 1` ternary with SaturatingSub + 1. - ChainLevelHelper: ulong.MinValue → 0UL (same value, clearer intent). - StartingSyncPivotUpdater.TryGetFromPeers: drop the `is { } h ? h.Number : null` pattern in favor of `?.Number`. Network: - TransactionBuilder.WithNonce gains a `WithNonce(int)` overload so the Eth65/Eth68 protocol tests stop casting their loop indices. - ReceiptsMessageSerializer: hoist the ulong.MaxValue sentinel to a `NoBlockSeenYet` const and drop the inline comments. - ReceiptMessageDecoder69 / OptimismReceiptMessageDecoder: drop the `(ulong)ctx.DecodePositiveLong()` and `(ulong)firstItem.ToPositiveLong()` pairs — use ctx.DecodeULong() (already existed) and a new ReadOnlySpan ToULong() helper for the byte-array path. - New Nethermind.Core.Extensions.SpanExtensions.ToULong(ReadOnlySpan) + byte[] overload. Mirrors ToPositiveLong's structure but skips the long-overflow guard. OpcodeTracing: - OpcodeTraceRecorder / TraceConfiguration: replace the `x > 0 ? x - 1 : 0` and `tip >= n - 1 ? tip - n + 1 : 0` patterns with SaturatingSub. Optimism: - ICostHelper.ComputeOperatorCost(long) → (ulong); OptimismCostHelper and OptimismTransactionProcessor drop the (long)tx.GasLimit / (long)spentGas casts at all three call sites. - DepositTransactionForRpc.ToTransaction: drop the (ulong)(Value ?? throw) cast — Transaction.Value is already UInt256, no narrowing needed. Mining.Test/HintBasedCacheTests: use Ethash.GetEpoch(200000UL) instead of the inlined (uint)(200000UL / EpochLength). Init.Snapshot: - SnapshotDownloader.initialProgress long → ulong (no more (ulong) cast in progress.Update). - HumanReadableSize takes ulong (drops the `< 0 throw` arm — unsigned by construction); FormatBytes drops the (long) wrap on logger.CurrentValue. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Utils/LastNStateRootTracker.cs | 8 +-- .../Builders/TransactionBuilder.cs | 3 +- .../Extensions/SpanExtensions.cs | 52 +++++++++++++++++++ .../SnapshotDownloader.cs | 11 ++-- .../Modules/FlatWorldStateModule.cs | 2 +- .../PruningTrieStateFactory.cs | 2 +- .../Modules/Eth/GasPrice/GasPriceOracle.cs | 9 +--- .../Synchronization/BeaconPivot.cs | 4 +- .../Synchronization/ChainLevelHelper.cs | 2 +- .../StartingSyncPivotUpdater.cs | 4 +- .../HintBasedCacheTests.cs | 2 +- .../V63/Messages/ReceiptsMessageSerializer.cs | 8 +-- .../V69/Messages/ReceiptMessageDecoder69.cs | 9 ++-- .../TraceConfiguration.cs | 6 +-- .../Tracing/OpcodeTraceRecorder.cs | 3 +- .../Nethermind.Optimism/ICostHelper.cs | 2 +- .../Nethermind.Optimism/OptimismCostHelper.cs | 2 +- .../OptimismReceiptMessageDecoder.cs | 3 +- .../OptimismTransactionProcessor.cs | 6 +-- .../Rpc/DepositTransactionForRpc.cs | 2 +- .../Sync/Snap/FlatStateRootIndexTests.cs | 2 +- .../Sync/Snap/FlatStateRootIndex.cs | 8 +-- 22 files changed, 96 insertions(+), 54 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Utils/LastNStateRootTracker.cs b/src/Nethermind/Nethermind.Blockchain/Utils/LastNStateRootTracker.cs index 268d47ce021b..94f431c082c2 100644 --- a/src/Nethermind/Nethermind.Blockchain/Utils/LastNStateRootTracker.cs +++ b/src/Nethermind/Nethermind.Blockchain/Utils/LastNStateRootTracker.cs @@ -16,13 +16,13 @@ namespace Nethermind.Blockchain.Utils; public class LastNStateRootTracker : ILastNStateRootTracker, IDisposable { private readonly IBlockTree _blockTree; - private readonly int _lastN = 0; + private readonly ulong _lastN = 0; private Hash256? _lastQueuedStateRoot = null; private Queue _stateRootQueue = new(); private NonBlocking.ConcurrentDictionary _availableStateRoots = new(); - public LastNStateRootTracker(IBlockTree blockTree, int lastN) + public LastNStateRootTracker(IBlockTree blockTree, ulong lastN) { _blockTree = blockTree; _lastN = lastN; @@ -47,7 +47,7 @@ private void ResetAvailableStateRoots(BlockHeader? newHead, bool resetQueue) newHead.StateRoot, static (_) => 1, static (_, oldValue) => oldValue + 1); - while (_stateRootQueue.Count >= _lastN && _stateRootQueue.TryDequeue(out Hash256 oldStateRoot)) + while ((ulong)_stateRootQueue.Count >= _lastN && _stateRootQueue.TryDequeue(out Hash256 oldStateRoot)) { int newNum = _availableStateRoots.AddOrUpdate( oldStateRoot, @@ -65,7 +65,7 @@ private void ResetAvailableStateRoots(BlockHeader? newHead, bool resetQueue) newStateRootSet.TryAdd(newHead.StateRoot, 1); stateRoots.Add(newHead.StateRoot); - while (parent is not null && stateRoots.Count < _lastN) + while (parent is not null && (ulong)stateRoots.Count < _lastN) { newStateRootSet.AddOrUpdate( parent.StateRoot, diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs index 9a520701ea2d..c9c6450e35da 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/TransactionBuilder.cs @@ -26,13 +26,14 @@ namespace Nethermind.Core.Test.Builders Timestamp = 0, }; - // Nonce is ulong — nonces are non-negative and fit well within ulong range public TransactionBuilder WithNonce(ulong nonce) { TestObjectInternal.Nonce = nonce; return this; } + public TransactionBuilder WithNonce(int nonce) => WithNonce((ulong)nonce); + public TransactionBuilder WithHash(Hash256? hash) { TestObjectInternal.Hash = hash; diff --git a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs index ad1bfc153d9e..b23a22168ee6 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs @@ -595,6 +595,58 @@ static void ThrowExceedsMaxValue(ReadOnlySpan bytes) } } + /// + /// Decodes a big-endian byte span (up to 8 bytes long) into an unsigned 64-bit integer. + /// Inputs longer than 8 bytes are accepted only if all leading bytes are zero. + /// + public static ulong ToULong(this ReadOnlySpan bytes) + { + return bytes.Length switch + { + 0 => 0UL, + < 8 => ReadUInt64BigEndian1To7(bytes), + 8 => BinaryPrimitives.ReadUInt64BigEndian(bytes), + _ => ParseLargeSpan(bytes), + }; + + static ulong ParseLargeSpan(ReadOnlySpan bytes) + { + int prefixLen = bytes.Length - 8; + if (bytes.Slice(0, prefixLen).IndexOfAnyExcept((byte)0) >= 0) + ThrowExceedsMaxValue(bytes); + return BinaryPrimitives.ReadUInt64BigEndian(bytes.Slice(prefixLen)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static ulong ReadUInt64BigEndian1To7(ReadOnlySpan s) + { + Debug.Assert((uint)s.Length - 1u < 7u); + + ref byte r0 = ref MemoryMarshal.GetReference(s); + + return s.Length switch + { + 1 => r0, + 2 => ((ulong)r0 << 8) | Unsafe.Add(ref r0, 1), + 3 => ((ulong)r0 << 16) | ((ulong)Unsafe.Add(ref r0, 1) << 8) | Unsafe.Add(ref r0, 2), + 4 => BinaryPrimitives.ReadUInt32BigEndian(s), + 5 => ((ulong)BinaryPrimitives.ReadUInt32BigEndian(s) << 8) | Unsafe.Add(ref r0, 4), + 6 => ((ulong)BinaryPrimitives.ReadUInt32BigEndian(s) << 16) | ((ulong)Unsafe.Add(ref r0, 4) << 8) | Unsafe.Add(ref r0, 5), + 7 => ((ulong)BinaryPrimitives.ReadUInt32BigEndian(s) << 24) | ((ulong)Unsafe.Add(ref r0, 4) << 16) | ((ulong)Unsafe.Add(ref r0, 5) << 8) | Unsafe.Add(ref r0, 6), + _ => 0 + }; + } + + [DoesNotReturn, StackTraceHidden] + static void ThrowExceedsMaxValue(ReadOnlySpan bytes) + { + BigInteger value = new(bytes, isUnsigned: true, isBigEndian: true); + throw new OverflowException($"Value {value} exceeds maximum allowed value"); + } + } + + public static ulong ToULong(this byte[] bytes) => ToULong((ReadOnlySpan)bytes); + /// /// Computes a very fast, non-cryptographic 64-bit hash of exactly 32 bytes. /// diff --git a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotDownloader.cs b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotDownloader.cs index 5108d84acb4f..535c4f728b6d 100644 --- a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotDownloader.cs +++ b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotDownloader.cs @@ -69,10 +69,10 @@ public async Task DownloadAsync(string url, string destinationPath, Cancellation await using Stream contentStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); await using FileStream fileStream = new(destinationPath, fileMode, FileAccess.Write, FileShare.None, BufferSize, useAsync: true); - long initialProgress = fileMode == FileMode.Append ? existingSize : 0; + ulong initialProgress = fileMode == FileMode.Append ? (ulong)existingSize : 0UL; using ProgressReporter progress = new("Snapshot download", logManager, (ulong)(totalSize ?? 0), ProgressInterval); progress.Logger.SetFormat(FormatBytes(totalSize)); - progress.Update((ulong)initialProgress); + progress.Update(initialProgress); if (bytesToSkip > 0) await SkipBytesAsync(contentStream, bytesToSkip, cancellationToken).ConfigureAwait(false); @@ -181,13 +181,12 @@ private static async Task CopyWithProgressAsync( private static Func FormatBytes(long? totalBytes) => totalBytes is null - ? static logger => $"Snapshot download {HumanReadableSize((long)logger.CurrentValue)}" - : logger => $"Snapshot download {HumanReadableSize((long)logger.CurrentValue)} out of {HumanReadableSize(totalBytes.Value)}"; + ? static logger => $"Snapshot download {HumanReadableSize(logger.CurrentValue)}" + : logger => $"Snapshot download {HumanReadableSize(logger.CurrentValue)} out of {HumanReadableSize((ulong)totalBytes.Value)}"; - private static string HumanReadableSize(long byteCount) => + private static string HumanReadableSize(ulong byteCount) => byteCount switch { - < 0 => throw new ArgumentOutOfRangeException(nameof(byteCount), "Cannot be negative"), < MemorySizes.KiB => $"{byteCount:0.##}B", < MemorySizes.MiB => $"{(float)byteCount / MemorySizes.KiB:0.##}KB", < MemorySizes.GiB => $"{(float)byteCount / MemorySizes.MiB:0.##}MB", diff --git a/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs b/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs index fcd4d412c9df..d00faa04bd6a 100644 --- a/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/FlatWorldStateModule.cs @@ -66,7 +66,7 @@ protected override void Load(ContainerBuilder builder) .AddSingleton() .AddSingleton((ctx) => new FlatStateRootIndex( ctx.Resolve(), - (int)ctx.Resolve().SnapServingMaxDepth)) + ctx.Resolve().SnapServingMaxDepth)) .AddSingleton() .AddSingleton() diff --git a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs index af546409308a..48d609b35fd2 100644 --- a/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs +++ b/src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs @@ -74,7 +74,7 @@ public class PruningTrieStateFactory( dbProvider, logManager, pruningConfig, - new LastNStateRootTracker(blockTree, (int)syncConfig.SnapServingMaxDepth)); + new LastNStateRootTracker(blockTree, syncConfig.SnapServingMaxDepth)); disposeStack.Push(mainWorldTrieStore); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs index 9a38c18e6d95..afd20d160e43 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs @@ -90,16 +90,11 @@ private IEnumerable GetGasPricesFromRecentBlocks(ulong blockNumber, int { IEnumerable GetBlocks(ulong currentBlockNumber) { - while (true) + do { if (_logger.IsTrace) _logger.Trace($"GasPriceOracle - searching for block number {currentBlockNumber}"); yield return _blockFinder.FindBlock(currentBlockNumber)!; - if (currentBlockNumber == 0) - { - break; - } - currentBlockNumber--; - } + } while (currentBlockNumber-- != 0); } return GetGasPricesFromRecentBlocks(GetBlocks(blockNumber), numberOfBlocks, calculateGasFromTransaction); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index 875670d9ffb4..d48fad7ff9a4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs @@ -7,6 +7,7 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Logging; @@ -84,8 +85,7 @@ public ulong PivotDestinationNumber if (_blockTree.Head is not null && _blockTree.Head?.Number != 0) { // However, the head may not be canon, so the destination need to be before that. - ulong headNumber = _blockTree.Head!.Number; - return headNumber > Reorganization.MaxDepth ? headNumber - Reorganization.MaxDepth + 1 : 1; + return _blockTree.Head!.Number.SaturatingSub(Reorganization.MaxDepth) + 1; } return _blockTree.SyncPivot.BlockNumber + 1; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs index 85b4ef8113ec..63bb74ed46ea 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/ChainLevelHelper.cs @@ -37,7 +37,7 @@ private void OnMissingBeaconHeader(ulong blockNumber) // A gap is expected when forward sync hasn't reached `blockNumber` yet (best beacon header // still below it) or when backward beacon sync hasn't reached it yet (lowest beacon header // still above it). Trigger a new beacon sync to close the gap. - bool aboveBeaconCoverage = (_blockTree.BestSuggestedBeaconHeader?.Number ?? ulong.MinValue) < blockNumber; + bool aboveBeaconCoverage = (_blockTree.BestSuggestedBeaconHeader?.Number ?? 0UL) < blockNumber; bool belowBeaconCoverage = (_blockTree.LowestInsertedBeaconHeader?.Number ?? ulong.MaxValue) > blockNumber; bool expectedDuringSync = aboveBeaconCoverage || belowBeaconCoverage; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs index 9b644768c326..c0a7ec133a6b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/StartingSyncPivotUpdater.cs @@ -182,9 +182,7 @@ private async Task TrySetFreshPivot(CancellationToken cancellationToken) BlockHeader? header = await peer.GetHeadBlockHeader(hash256, token); // Only accept a header that is actually the requested block; a peer must not substitute another. return header is not null && header.Hash == hash256 ? header : null; - }, type)) is { } h - ? h.Number - : null; + }, type))?.Number; protected async Task TryGetFromPeers(T id, CancellationToken cancellationToken, Func> getHeader, string? type = Pivot) diff --git a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs index f9657ffe12d8..bb7dcd300937 100644 --- a/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs +++ b/src/Nethermind/Nethermind.Mining.Test/HintBasedCacheTests.cs @@ -56,7 +56,7 @@ public void Sync_hint_and_get() { HintBasedCache hintBasedCache = new(static e => new NullDataSet(), LimboLogs.Instance); hintBasedCache.Hint(_guidA, 200000, 200000); - Assert.That(hintBasedCache.Get((uint)(200000UL / Ethash.EpochLength)), Is.Not.Null); + Assert.That(hintBasedCache.Get(Ethash.GetEpoch(200000UL)), Is.Not.Null); } [Test] diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs index c3dfdd831cf4..ecba3433e032 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Messages/ReceiptsMessageSerializer.cs @@ -14,6 +14,8 @@ namespace Nethermind.Network.P2P.Subprotocols.Eth.V63.Messages { public class ReceiptsMessageSerializer : IZeroInnerMessageSerializer { + private const ulong NoBlockSeenYet = ulong.MaxValue; + private static readonly RlpLimit ReceiptsRlpLimit = RlpLimit.For(NethermindSyncLimits.MaxHashesFetch, nameof(ReceiptsMessage.TxReceipts)); private static readonly RlpLimit BlockReceiptsRlpLimit = RlpLimit.For(NethermindSyncLimits.MaxHashesFetch, nameof(ReceiptsMessage.TxReceipts)); private readonly ISpecProvider _specProvider; @@ -37,8 +39,7 @@ public void Serialize(IByteBuffer byteBuffer, ReceiptsMessage message) NettyRlpStream stream = new(byteBuffer); stream.StartSequence(contentLength); - // Track the last ‐ seen block number & its RLP behavior - ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet + ulong lastBlockNumber = NoBlockSeenYet; RlpBehaviors behaviors = RlpBehaviors.None; foreach (TxReceipt?[]? txReceipts in message.TxReceipts.AsSpan()) @@ -147,8 +148,7 @@ private int GetInnerLength(TxReceipt?[]? txReceipts) int contentLength = 0; - // Track the last‐seen block number and its spec - ulong lastBlockNumber = ulong.MaxValue; // Sentinel: no block seen yet + ulong lastBlockNumber = NoBlockSeenYet; RlpBehaviors behaviors = RlpBehaviors.None; for (int i = 0; i < txReceipts.Length; i++) diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs index a35a7a769090..06bb1b25177a 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V69/Messages/ReceiptMessageDecoder69.cs @@ -35,19 +35,16 @@ public sealed class ReceiptMessageDecoder69(bool skipStateAndStatus = false) : R if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; - // safe: DecodePositiveLong guarantees a non-negative result - txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } else if (firstItem.Length is >= 1 and <= 4) { - // safe: ToPositiveLong guarantees a non-negative result - txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = firstItem.ToULong(); } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Hash256(firstItem); - // safe: DecodePositiveLong guarantees a non-negative result - txReceipt.GasUsedTotal = (ulong)ctx.DecodePositiveLong(); + txReceipt.GasUsedTotal = ctx.DecodeULong(); } int lastCheck = ctx.ReadSequenceLength() + ctx.Position; diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs index 0d7c436006de..261cd00d07cf 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/TraceConfiguration.cs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Nethermind.Core.Extensions; + namespace Nethermind.OpcodeTracing.Plugin; /// @@ -142,9 +144,7 @@ public static TraceConfiguration FromConfig(IOpcodeTracingConfig config, ulong c { // Retrospective and RetrospectiveExecution: recent N blocks from chain tip effectiveEnd = currentChainTip; - effectiveStart = currentChainTip >= config.RecentBlocks.Value - 1 - ? currentChainTip - config.RecentBlocks.Value + 1 - : 0; + effectiveStart = currentChainTip.SaturatingSub(config.RecentBlocks.Value - 1); if (effectiveStart == 0 && config.RecentBlocks.Value > currentChainTip + 1) { diff --git a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs index 3d7b096d4e2c..d02ddc2e602d 100644 --- a/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs +++ b/src/Nethermind/Nethermind.OpcodeTracing.Plugin/Tracing/OpcodeTraceRecorder.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.Tracing; using Nethermind.Consensus.Processing; +using Nethermind.Core.Extensions; using Nethermind.Logging; using Nethermind.OpcodeTracing.Plugin.Output; using Nethermind.OpcodeTracing.Plugin.Utilities; @@ -105,7 +106,7 @@ public Task PrepareAsync(INethermindApi api, CancellationToken cancellationToken // Initialize progress tracker _progress = new TracingProgress(_traceConfig.EffectiveStartBlock, _traceConfig.EffectiveEndBlock); - _lastProcessedBlock = _traceConfig.EffectiveStartBlock > 0 ? _traceConfig.EffectiveStartBlock - 1 : 0; + _lastProcessedBlock = _traceConfig.EffectiveStartBlock.SaturatingSub(1); if (_logger.IsInfo) { diff --git a/src/Nethermind/Nethermind.Optimism/ICostHelper.cs b/src/Nethermind/Nethermind.Optimism/ICostHelper.cs index b863c14a74c5..48cc6351545a 100644 --- a/src/Nethermind/Nethermind.Optimism/ICostHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/ICostHelper.cs @@ -11,7 +11,7 @@ public interface ICostHelper { UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState worldState); - UInt256 ComputeOperatorCost(long gas, BlockHeader header, IWorldState worldState); + UInt256 ComputeOperatorCost(ulong gas, BlockHeader header, IWorldState worldState); UInt256 ComputeDaFootprint(Block block); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs b/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs index 1bba8fa76f39..ca83d58323fc 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismCostHelper.cs @@ -102,7 +102,7 @@ public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState wor } } - public UInt256 ComputeOperatorCost(long gas, BlockHeader header, IWorldState worldState) + public UInt256 ComputeOperatorCost(ulong gas, BlockHeader header, IWorldState worldState) { if (!opSpecHelper.IsIsthmus(header)) return UInt256.Zero; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs index d654b072ea0f..9bcb0af6380d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs @@ -37,8 +37,7 @@ protected override OptimismTxReceipt DecodeInternal(ref Rlp.ValueDecoderContext } else if (firstItem.Length is >= 1 and <= 4) { - // safe: ToPositiveLong guarantees a non-negative result - txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = firstItem.ToULong(); } else { diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 89e9e57094c3..c1e5d25f1999 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -99,7 +99,7 @@ protected override TransactionResult BuyGas(Transaction tx, IReleaseSpec spec, I } UInt256 l1Cost = _currentTxL1Cost ??= costHelper.ComputeL1Cost(tx, header, WorldState); - UInt256 maxOperatorCost = costHelper.ComputeOperatorCost((long)tx.GasLimit, header, WorldState); + UInt256 maxOperatorCost = costHelper.ComputeOperatorCost(tx.GasLimit, header, WorldState); if (UInt256.SubtractUnderflow(balanceLeft, l1Cost + maxOperatorCost, out balanceLeft)) { @@ -158,8 +158,8 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec if (opSpecHelper.IsIsthmus(header)) { - UInt256 operatorCostMax = costHelper.ComputeOperatorCost((long)tx.GasLimit, header, WorldState); - UInt256 operatorCostUsed = costHelper.ComputeOperatorCost((long)spentGas, header, WorldState); + UInt256 operatorCostMax = costHelper.ComputeOperatorCost(tx.GasLimit, header, WorldState); + UInt256 operatorCostUsed = costHelper.ComputeOperatorCost(spentGas, header, WorldState); if (operatorCostMax > operatorCostUsed) { diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs b/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs index f4f3dd039561..44316c6c747d 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/DepositTransactionForRpc.cs @@ -75,7 +75,7 @@ public override Result ToTransaction(bool validateUserInput = false tx.SenderAddress = From ?? throw new ArgumentNullException(nameof(From)); tx.To = To; tx.Mint = Mint ?? 0; - tx.Value = (ulong)(Value ?? throw new ArgumentNullException(nameof(Value))); + tx.Value = Value ?? throw new ArgumentNullException(nameof(Value)); tx.IsOPSystemTransaction = IsSystemTx ?? false; tx.Data = Input ?? throw new ArgumentNullException(nameof(Input)); diff --git a/src/Nethermind/Nethermind.State.Flat.Test/Sync/Snap/FlatStateRootIndexTests.cs b/src/Nethermind/Nethermind.State.Flat.Test/Sync/Snap/FlatStateRootIndexTests.cs index 7dc6c82c37b6..90a135c0b388 100644 --- a/src/Nethermind/Nethermind.State.Flat.Test/Sync/Snap/FlatStateRootIndexTests.cs +++ b/src/Nethermind/Nethermind.State.Flat.Test/Sync/Snap/FlatStateRootIndexTests.cs @@ -30,7 +30,7 @@ private static List BuildChain(int length) return blocks; } - private static (BlockTree tree, List blocks, FlatStateRootIndex index) BuildIndex(int chainLength, int lastN = 10) + private static (BlockTree tree, List blocks, FlatStateRootIndex index) BuildIndex(int chainLength, ulong lastN = 10) { List blocks = BuildChain(chainLength); BlockTree tree = Build.A.BlockTree().WithBlocks(blocks.ToArray()).TestObject; diff --git a/src/Nethermind/Nethermind.State.Flat/Sync/Snap/FlatStateRootIndex.cs b/src/Nethermind/Nethermind.State.Flat/Sync/Snap/FlatStateRootIndex.cs index f220b3fe235a..e5a50afd845d 100644 --- a/src/Nethermind/Nethermind.State.Flat/Sync/Snap/FlatStateRootIndex.cs +++ b/src/Nethermind/Nethermind.State.Flat/Sync/Snap/FlatStateRootIndex.cs @@ -16,12 +16,12 @@ namespace Nethermind.State.Flat.Sync.Snap; public class FlatStateRootIndex : IFlatStateRootIndex, IDisposable { private readonly IBlockTree _blockTree; - private readonly int _lastN; + private readonly ulong _lastN; private Hash256? _lastQueuedStateRoot; private Queue _stateRootQueue = new(); private NonBlocking.ConcurrentDictionary _availableStateRoots = new(); - public FlatStateRootIndex(IBlockTree blockTree, int lastN) + public FlatStateRootIndex(IBlockTree blockTree, ulong lastN) { _blockTree = blockTree; _lastN = lastN; @@ -44,7 +44,7 @@ private void ResetAvailableStateRoots(BlockHeader? newHead, bool resetQueue) { // Queue is intact - just add the new state root _availableStateRoots[newHead.StateRoot] = new StateId(newHead); - while (_stateRootQueue.Count >= _lastN && _stateRootQueue.TryDequeue(out Hash256? oldStateRoot)) + while ((ulong)_stateRootQueue.Count >= _lastN && _stateRootQueue.TryDequeue(out Hash256? oldStateRoot)) { if (oldStateRoot is not null) _availableStateRoots.TryRemove(oldStateRoot, out _); @@ -61,7 +61,7 @@ private void ResetAvailableStateRoots(BlockHeader? newHead, bool resetQueue) stateRoots.Add((newHead.StateRoot, new StateId(newHead))); BlockHeader? current = parent; - while (current?.StateRoot is not null && stateRoots.Count < _lastN) + while (current?.StateRoot is not null && (ulong)stateRoots.Count < _lastN) { StateId stateId = new(current); newStateRootSet[current.StateRoot] = stateId; From 98652826b7b6dfcbf5d91df8522f8de6da50bcae Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 17:01:42 +0200 Subject: [PATCH 44/60] review: revert GetBlobCount to int + Optimism/Migration/Simulate cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transaction.GetBlobCount() ulong → int (matches BlobVersionedHashes Length); GetBlobGas() picks up the (ulong) cast once at the boundary. Call sites that operated on ulong (TxPoolTxSource, ProcessingStats, BlobGasCalculator, PayloadPreparationService, TxPoolSourceTests) gain a single (ulong) cast each; BlobsBundleV1/V2 lose the `?? 0UL` + (int) double-cast. Optimism: - BatchV1.Decode{Legacy,AccessList,Eip1559}Transaction: inline the decode chain back into the tuple return — the rlp ValueDecoderContext advances left-to-right inside the tuple expression. - ICostHelper.ComputeOperatorCost(long → ulong) (re-applied with imports). Merge.Plugin: - NewPayloadHandler.GetGasChange: rewrite to CompareTo + switch — drops the nested ternary. - SszRest QueryParams.TryReadLong: deleted (unused — only TryReadUlong is referenced). JsonRpc/SimulateTxExecutor: `BlockOverrides.Time is not null` → `is { } blockTime` to drop the `(ulong)BlockOverrides.Time` cast in the following line. Same-name local on the else-branch removed by reusing lastBlockTime. Runner.Test/ReceiptMigrationTests: `for (int i = 1; …; i++)` → `for (ulong i = 1; …; i++)` so FindBlock takes the loop counter directly; removes the "Safe: i is a loop counter" comment. Runner.Test/TotalDifficultyFixMigrationTest: TestCase parameter types long/long? → ulong/ulong?; the `-1` sentinel for "broken level out of range" becomes ulong.MaxValue, which the body now checks with `< numberOfBlocks`. Drops three `(ulong)x` casts and three explanatory comments. Facade/BlockchainBridge: stripped the "//Ignore nonce" CAST NOTE block — the comment was repeating the call signature. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../TxPoolSourceTests.cs | 2 +- .../Processing/ProcessingStats.cs | 2 +- .../Producers/TxPoolTxSource.cs | 8 ++-- .../Nethermind.Core/TransactionExtensions.cs | 4 +- .../Nethermind.Evm/BlobGasCalculator.cs | 2 +- .../Nethermind.Facade/BlockchainBridge.cs | 2 - .../Modules/Eth/SimulateTxExecutor.cs | 8 ++-- .../PayloadPreparationService.cs | 2 +- .../Data/BlobsBundleV1.cs | 2 +- .../Data/BlobsBundleV2.cs | 2 +- .../Handlers/NewPayloadHandler.cs | 10 +++-- .../SszRest/Handlers/QueryParams.cs | 27 ------------- .../CL/Decoding/BatchV1.cs | 24 +++--------- .../Steps/Migrations/ReceiptMigrationTests.cs | 6 +-- .../TotalDifficultyFixMigrationTest.cs | 38 +++++++++---------- 15 files changed, 46 insertions(+), 93 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs index 727c17077440..f8faa7443336 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs @@ -48,7 +48,7 @@ public void GetTransactions_should_respect_customizable_blob_gas_limit(int[] blo TxPoolTxSource transactionSelector = new(txPool, specProvider, transactionComparerProvider, LimboLogs.Instance, txFilterPipeline, new BlocksConfig { SecondsPerSlot = 12, BlockProductionBlobLimit = customBlobLimit }); IEnumerable txs = transactionSelector.GetTransactions(new BlockHeader(), long.MaxValue); - ulong blobsCount = txs.Aggregate(0UL, (sum, tx) => sum + tx.GetBlobCount()); + ulong blobsCount = txs.Aggregate(0UL, (sum, tx) => sum + (ulong)tx.GetBlobCount()); Assert.That(blobsCount, Is.LessThanOrEqualTo((ulong)Cancun.Instance.MaxProductionBlobCount(customBlobLimit))); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 3c621f52b316..54599568020e 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -225,7 +225,7 @@ public void UpdateStats(IReadOnlyList blocks, BlockHeader? baseBlock, lon transactionCount += transactions.Length; for (int j = 0; j < transactions.Length; j++) { - blobCount += transactions[j].GetBlobCount(); + blobCount += (ulong)transactions[j].GetBlobCount(); } } diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 27447857d56a..1495e464b06d 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -165,7 +165,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain ArrayPoolList<(Transaction tx, ulong blobChain)>? candidates = null; foreach ((Transaction blobTx, ulong blobChain) in blobTransactions) { - ulong txBlobCount = blobTx.GetBlobCount(); + ulong txBlobCount = (ulong)blobTx.GetBlobCount(); if (txBlobCount > (ulong)maxBlobs) { if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space."); @@ -264,7 +264,7 @@ private static void ChooseBestBlobTransactions( } // How many blobs does this tx actually consume? - ulong blobCount = tx.GetBlobCount(); + ulong blobCount = (ulong)tx.GetBlobCount(); // If this tx has explicit dependencies (i.e. it requires k prior blobs // from the *same address* to be in the block before it), include them here. // We'll need a capacity of blobDependenciesCount slots *plus* its own blobCount. @@ -335,7 +335,7 @@ private static void ChooseBestBlobTransactions( if (isChosen[i * maxCapacity + remainingCapacity]) { Transaction tx = candidateTxs[i].tx; - ulong blobCount = tx.GetBlobCount(); + ulong blobCount = (ulong)tx.GetBlobCount(); selectedBlobTxs.Add(tx); remainingCapacity -= (int)blobCount; } @@ -382,7 +382,7 @@ protected virtual IEnumerable GetOrderedTransactions(IDictionary GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, int maxBlobs = 0) => - OrderCore(pendingTransactions, comparer, static tx => tx.GetBlobCount(), filter, (ulong)maxBlobs); + OrderCore(pendingTransactions, comparer, static tx => (ulong)tx.GetBlobCount(), filter, (ulong)maxBlobs); protected virtual IComparer GetComparer(BlockHeader parent, BlockPreparationContext blockPreparationContext) => _transactionComparerProvider.GetDefaultProducerComparer(blockPreparationContext); diff --git a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs index d44bda1e5465..3d6a82a414b5 100644 --- a/src/Nethermind/Nethermind.Core/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.Core/TransactionExtensions.cs @@ -56,8 +56,8 @@ public UInt256 CalculateMaxPriorityFeePerGas(bool eip1559Enabled, in UInt256 bas public bool IsAboveInitCode(IReleaseSpec spec) => tx.IsContractCreation && spec.IsEip3860Enabled && tx.DataLength > spec.MaxInitCodeSize; - public ulong GetBlobGas() => tx.GetBlobCount() * Eip4844Constants.GasPerBlob; - public ulong GetBlobCount() => (ulong)(tx.BlobVersionedHashes?.Length ?? 0); + public ulong GetBlobGas() => (ulong)tx.GetBlobCount() * Eip4844Constants.GasPerBlob; + public int GetBlobCount() => tx.BlobVersionedHashes?.Length ?? 0; public void CapGasLimit(ulong? gasCap) { diff --git a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs index cef48365a609..ad475be6730e 100644 --- a/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs @@ -48,7 +48,7 @@ public static ulong CalculateBlobGas(Transaction[] transactions) { if (tx.SupportsBlobs) { - blobCount += tx.GetBlobCount(); + blobCount += (ulong)tx.GetBlobCount(); } } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 5873c567e8c8..6f30e9fa243c 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -419,8 +419,6 @@ private TransactionResult CallAndRestore( transaction.SenderAddress ??= Address.Zero; //Ignore nonce on all CallAndRestore calls - // CAST NOTE: GetNonce returns UInt256 (IStateReader interface). Transaction.Nonce is ulong. - // Nonce values beyond ulong.MaxValue are not realistically reachable. transaction.Nonce = nonceReader.GetNonce(blockHeader, transaction.SenderAddress); BlockHeader callHeader = blockHeader.Clone(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index caefcc1fa2f6..348509d6353e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -154,9 +154,8 @@ public override ResultWrapper>> Execut blockToSimulate.BlockOverrides.Number = givenNumber; - if (blockToSimulate.BlockOverrides.Time is not null) + if (blockToSimulate.BlockOverrides.Time is { } blockTime) { - ulong blockTime = (ulong)blockToSimulate.BlockOverrides.Time; if (blockTime <= lastBlockTime) { return ResultWrapper>>.Fail($"Block timestamp out of order {blockToSimulate.BlockOverrides.Time} is <= than given base timestamp of {lastBlockTime}!", ErrorCodes.BlockTimestampNotIncreased); @@ -165,9 +164,8 @@ public override ResultWrapper>> Execut } else { - ulong blockTime = lastBlockTime + _secondsPerSlot; - blockToSimulate.BlockOverrides.Time = blockTime; - lastBlockTime = blockTime; + lastBlockTime += _secondsPerSlot; + blockToSimulate.BlockOverrides.Time = lastBlockTime; } lastBlockNumber = givenNumber; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs index c78bff22759c..d2628a8ba5d7 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs @@ -355,7 +355,7 @@ private void LogProductionResult(Task t, Block currentBestBlock, UInt256 UInt256 gas = 0; foreach (Transaction tx in block.Transactions) { - ulong blobCount = tx.GetBlobCount(); + ulong blobCount = (ulong)tx.GetBlobCount(); if (blobCount > 0UL) { blobs += blobCount; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs index 66ff4c78548d..3871f06deb10 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV1.cs @@ -20,7 +20,7 @@ public BlobsBundleV1(Block block) int blobsCount = 0; foreach (Transaction? tx in block.Transactions) { - blobsCount += (int)(tx?.GetBlobCount() ?? 0UL); + blobsCount += tx?.GetBlobCount() ?? 0; } Commitments = new byte[blobsCount][]; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs index 832b28858d03..f24b29f65f8e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/BlobsBundleV2.cs @@ -23,7 +23,7 @@ public BlobsBundleV2(Block block) int blobsCount = 0; foreach (Transaction? tx in block.Transactions) { - blobsCount += (int)(tx?.GetBlobCount() ?? 0UL); + blobsCount += tx?.GetBlobCount() ?? 0; } Commitments = new byte[blobsCount][]; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs index 07b1bc392cd9..78694ac34287 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs @@ -96,10 +96,12 @@ public NewPayloadHandler( _processingQueue.BlockRemoved += GetProcessingQueueOnBlockRemoved; } - private string GetGasChange(ulong blockGasLimit) => - blockGasLimit > _lastBlockGasLimit ? "👆" - : blockGasLimit < _lastBlockGasLimit ? "👇" - : " "; + private string GetGasChange(ulong blockGasLimit) => blockGasLimit.CompareTo(_lastBlockGasLimit) switch + { + > 0 => "👆", + < 0 => "👇", + _ => " " + }; /// /// Processes the execution payload and returns the diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/QueryParams.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/QueryParams.cs index 22b0871ca418..44ce5c77d002 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/QueryParams.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/Handlers/QueryParams.cs @@ -10,33 +10,6 @@ namespace Nethermind.Merge.Plugin.SszRest.Handlers; internal static class QueryParams { - /// - /// Reads a required query parameter named and - /// validates it with . On failure, - /// is set to a pending 400 invalid-request response that the caller MUST await. - /// - public static bool TryReadLong( - HttpContext ctx, - string name, - Func isValid, - string validationDescription, - out long value, - [NotNullWhen(false)] out Task? errorTask) - { - if (long.TryParse(ctx.Request.Query[name], out value) && isValid(value)) - { - errorTask = null; - return true; - } - - errorTask = SszEndpointHandlerBase.WriteErrorAsync( - ctx, - StatusCodes.Status400BadRequest, - $"Missing or invalid '{name}' query parameter: {validationDescription}", - SszRestErrorCodes.InvalidRequest); - return false; - } - /// /// Reads a required query parameter named and /// validates it with . On failure, diff --git a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs index 613ca3ab84f3..eaf7ead37461 100644 --- a/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs +++ b/src/Nethermind/Nethermind.Optimism/CL/Decoding/BatchV1.cs @@ -156,35 +156,23 @@ public IEnumerable ToSingularBatches(ulong chainId, ulong genesis { // rlp_encode(value, gasPrice, data) Rlp.ValueDecoderContext decoder = new(encoded); - int length = decoder.ReadSequenceLength(); - UInt256 value = decoder.DecodeUInt256(); - UInt256 gasPrice = decoder.DecodeUInt256(); - byte[] data = decoder.DecodeByteArray(); - return (value, gasPrice, data); + decoder.ReadSequenceLength(); + return (decoder.DecodeUInt256(), decoder.DecodeUInt256(), decoder.DecodeByteArray()); } private (UInt256 Value, UInt256 GasPrice, byte[] Data, AccessList? AccessList) DecodeAccessListTransaction(ReadOnlySpan encoded) { // 0x01 ++ rlp_encode(value, gasPrice, data, accessList) Rlp.ValueDecoderContext decoder = new(encoded); - int length = decoder.ReadSequenceLength(); - UInt256 value = decoder.DecodeUInt256(); - UInt256 gasPrice = decoder.DecodeUInt256(); - byte[] data = decoder.DecodeByteArray(); - AccessList? accessList = AccessListDecoder.Instance.Decode(ref decoder); - return (value, gasPrice, data, accessList); + decoder.ReadSequenceLength(); + return (decoder.DecodeUInt256(), decoder.DecodeUInt256(), decoder.DecodeByteArray(), AccessListDecoder.Instance.Decode(ref decoder)); } private (UInt256 Value, UInt256 MaxPriorityFeePerGas, UInt256 MaxFeePerGas, byte[] Data, AccessList? AccessList) DecodeEip1559Transaction(ReadOnlySpan encoded) { // 0x02 ++ rlp_encode(value, max_priority_fee_per_gas, max_fee_per_gas, data, access_list) Rlp.ValueDecoderContext decoder = new(encoded); - int length = decoder.ReadSequenceLength(); - UInt256 value = decoder.DecodeUInt256(); - UInt256 maxPriorityFeePerGas = decoder.DecodeUInt256(); - UInt256 maxFeePerGas = decoder.DecodeUInt256(); - byte[] data = decoder.DecodeByteArray(); - AccessList? accessList = AccessListDecoder.Instance.Decode(ref decoder); - return (value, maxPriorityFeePerGas, maxFeePerGas, data, accessList); + decoder.ReadSequenceLength(); + return (decoder.DecodeUInt256(), decoder.DecodeUInt256(), decoder.DecodeUInt256(), decoder.DecodeByteArray(), AccessListDecoder.Instance.Decode(ref decoder)); } } diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs index 312e1df5f2cc..f153fc9d7d64 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/ReceiptMigrationTests.cs @@ -59,10 +59,9 @@ public async Task RunMigration(ulong? commandStartBlockNumber, ulong currentMigr // Insert the blocks int txIndex = 0; - for (int i = 1; i < chainLength; i++) + for (ulong i = 1; i < (ulong)chainLength; i++) { - // Safe: i is a loop counter in [1, chainLength), always a valid non-negative block number. - Block block = blockTree.FindBlock((ulong)i); + Block block = blockTree.FindBlock(i); inMemoryReceiptStorage.Insert(block, new[] { Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject, Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject @@ -75,7 +74,6 @@ public async Task RunMigration(ulong? commandStartBlockNumber, ulong currentMigr TestMemDb defaultDb = (TestMemDb)receiptColumnDb.GetColumnDb(ReceiptsColumns.Default); // Put the last block receipt encoding - // Safe: chainLength - 1 is a small positive integer well within ulong range. Block lastBlock = blockTree.FindBlock((ulong)(chainLength - 1)); TxReceipt[] receipts = inMemoryReceiptStorage.Get(lastBlock); using (NettyRlpStream nettyStream = receiptArrayStorageDecoder.EncodeToNewNettyStream(receipts, RlpBehaviors.Storage)) diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs index ff82a20f7f84..8567d79dce2f 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/Migrations/TotalDifficultyFixMigrationTest.cs @@ -19,13 +19,13 @@ namespace Nethermind.Runner.Test.Ethereum.Steps.Migrations; public class TotalDifficultyFixMigrationTest { - [TestCase(null, 4, 15)] - [TestCase(5, 4, 15)] - [TestCase(9, 9, 55)] - [TestCase(3, 3, 10)] - [TestCase(3, 4, -1)] - [TestCase(4, 1, -1)] - public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, long expectedTd) + [TestCase(null, 4UL, 15UL)] + [TestCase(5UL, 4UL, 15UL)] + [TestCase(9UL, 9UL, 55UL)] + [TestCase(3UL, 3UL, 10UL)] + [TestCase(3UL, 4UL, ulong.MaxValue)] + [TestCase(4UL, 1UL, ulong.MaxValue)] + public async Task Should_fix_td_when_broken(ulong? lastBlock, ulong brokenLevel, ulong expectedTd) { ulong numberOfBlocks = 10; ulong firstBlock = 3; @@ -63,16 +63,15 @@ public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, l { FixTotalDifficulty = true, FixTotalDifficultyStartingBlock = firstBlock, - // lastBlock is long? from TestCase; null means "no upper bound", negative means sentinel for "broken level out of range" - // Safe cast: test cases only pass non-negative values or null here when meaningful - FixTotalDifficultyLastBlock = lastBlock.HasValue ? (ulong?)lastBlock.Value : null + FixTotalDifficultyLastBlock = lastBlock }; TotalDifficultyFixMigration migration = new(chainLevelInfoRepository, blockTree, syncConfig, new TestLogManager()); - // Break level — brokenLevel is long from TestCase; safe to cast since array is sized by ulong numberOfBlocks - // and brokenLevel is always within [0, numberOfBlocks) in valid test cases - ulong brokenLevelUlong = (ulong)brokenLevel; - levels[brokenLevelUlong].BlockInfos[0].TotalDifficulty = 9999; + // Sentinel: brokenLevel == ulong.MaxValue means "broken level out of range". + if (brokenLevel < numberOfBlocks) + { + levels[brokenLevel].BlockInfos[0].TotalDifficulty = 9999; + } // Run await migration.Run(CancellationToken.None); @@ -80,13 +79,10 @@ public async Task Should_fix_td_when_broken(long? lastBlock, long brokenLevel, l // Check level fixed for (ulong i = 0; i < numberOfBlocks; ++i) { - // brokenLevel may be a sentinel negative value in some test cases (meaning "not in range"), - // so compare as long to handle that gracefully - ulong? lastBlockUlong = lastBlock.HasValue ? (ulong?)lastBlock.Value : null; - bool isBroken = brokenLevel >= 0 - && i == brokenLevelUlong - && firstBlock <= brokenLevelUlong - && brokenLevelUlong <= (lastBlockUlong ?? numberOfBlocks); + bool isBroken = brokenLevel < numberOfBlocks + && i == brokenLevel + && firstBlock <= brokenLevel + && brokenLevel <= (lastBlock ?? numberOfBlocks); if (isBroken) { From 99e1b937f620bf44575e1f894dcf0a2d8a6be4fc Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 17:05:51 +0200 Subject: [PATCH 45/60] review: HeaderDecoder ulong + receipt ToULong + comment strip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Serialization.Rlp: - HeaderDecoder.AuRaStep: decode via DecodeULong() instead of (ulong)DecodeUInt256() — the encode side already calls Encode(ulong) so the wire format is variable-length ulong, not UInt256. - ReceiptMessageDecoder (and the V69/Optimism variants in the previous commit): swap `(ulong)firstItem.ToPositiveLong()` for the new ReadOnlySpan.ToULong() — same shape minus the long-overflow guard (gas-used is non-negative by construction). Merge.Plugin: - SszCodec.DecodeGetPayloadBodiesByRangeRequest: drop the inline comment restating the wire types. - GetPayloadDirectResponseTests / PoSSwitcherTests: drop the "ERROR FIX (line X)" annotation comments — they referenced PR-time line numbers that no longer match. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../GetPayloadDirectResponseTests.cs | 1 - .../Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs | 3 --- src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs | 1 - src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs | 2 +- .../Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs | 3 +-- 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs index 2efc163d5689..a3eca52bbd94 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/GetPayloadDirectResponseTests.cs @@ -426,7 +426,6 @@ private static Block CreateBlock( BalKind balKind, ulong? slotNumber) { - // ERROR FIX (line 365): WithNumber now takes ulong; changed int literal 12 to ulong literal 12UL. Block block = Build.A.Block .WithPostMergeRules() .WithNumber(12UL) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs index f15184e8a44b..a08d7d3983eb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/PoSSwitcherTests.cs @@ -197,8 +197,6 @@ public void Switch_when_TTD_is_reached() public void Can_load_parameters_after_the_restart() { using MemDb metadataDb = new(); - // ERROR FIX (line 208): terminalBlock is used in assertions against MergeBlockNumber?.BlockNumber - // which is now ulong. Changed type from int to ulong so terminalBlock + 1 is unambiguously ulong. ulong terminalBlock = 4; TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = 5000000; @@ -207,7 +205,6 @@ public void Can_load_parameters_after_the_restart() PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, metadataDb, specProvider); Assert.That(poSSwitcher.HasEverReachedTerminalBlock(), Is.EqualTo(false)); - // WithNumber and WithParent still take long; cast terminalBlock at the call site. Block block = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(terminalBlock).WithParent(blockTree.Head!).WithDifficulty(1000000L).TestObject; blockTree.SuggestBlock(block); blockTree.TryUpdateMainChain(block.Header, true, preloadedBlocks: new[] { block }); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs index 316deeb54bc3..084440686beb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/SszRest/SszCodec.cs @@ -214,7 +214,6 @@ public static Hash256[] DecodeGetPayloadBodiesByHashRequest(ReadOnlySequence buf) { GetPayloadBodiesByRangeRequestWire.Decode(buf, out GetPayloadBodiesByRangeRequestWire wire); - // wire.Start and wire.Count are SSZ uint64 fields — already ulong, no cast needed. return (wire.Start, wire.Count); } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index 51684d573168..5dac794a0c1f 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -69,7 +69,7 @@ public sealed class HeaderDecoder() : RlpDecoder, IHeaderDecoder } else { - blockHeader.AuRaStep = (ulong)decoderContext.DecodeUInt256(); + blockHeader.AuRaStep = decoderContext.DecodeULong(); blockHeader.AuRaSignature = decoderContext.DecodeByteArray(); } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs index 4b91dea1eeb5..a651e1e6e433 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs @@ -42,8 +42,7 @@ protected override TxReceipt DecodeInternal(ref Rlp.ValueDecoderContext ctx, Rlp } else if (firstItem.Length is >= 1 and <= 4) { - // safe: ToPositiveLong guarantees a non-negative result - txReceipt.GasUsedTotal = (ulong)firstItem.ToPositiveLong(); + txReceipt.GasUsedTotal = firstItem.ToULong(); } else { From d9bc1b2a6b328bca4da7f33267d6d9ac84984ba1 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 17:12:52 +0200 Subject: [PATCH 46/60] review: EthCapabilities ulong end-to-end + EthSimulate test cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EthCapabilities: - ChainHead.Number long → ulong; ResourceAvailability.OldestBlock long? → ulong?; DeleteStrategy.RetentionBlocks long → ulong (with ULongRawJsonConverter instead of LongRawJsonConverter). - EthCapabilitiesProvider: drops the (long) round-trips on head.Number / historyFloor / lowestReceipt / lowestBlock / retention. windowOldest rewritten via SaturatingSub. - EthRpcModuleTests.Capabilities: TestCase / const local types long → ulong end-to-end. Suffix literals UL. JsonRpc/Test/EthSimulateTestsBlocksAndTransactions: replace `(ulong)20.GWei` with the raw `20_000_000_000UL` — same numeric value, no UInt256→ulong round-trip. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Eth/EthRpcModuleTests.Capabilities.cs | 20 +++++++++--------- .../EthSimulateTestsBlocksAndTransactions.cs | 2 +- .../Modules/Eth/EthCapabilities.cs | 6 +++--- .../Modules/Eth/EthCapabilitiesProvider.cs | 21 ++++++++++--------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs index 5232f406e29b..deb56f9822c9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs @@ -22,7 +22,7 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public partial class EthRpcModuleTests { - private static readonly ResourceAvailability Available = new(Disabled: false, OldestBlock: 0L); + private static readonly ResourceAvailability Available = new(Disabled: false, OldestBlock: 0UL); private static readonly ResourceAvailability Disabled = new(Disabled: true, OldestBlock: null); private static EthCapabilities GetCaps( @@ -106,7 +106,7 @@ private static IEnumerable CapabilitiesScenarios() SyncConfig = new SyncConfig { FastSync = true, PivotNumber = 18_000_000, DownloadReceiptsInFastSync = true }, }; - const long bodiesBarrier = 5_000_000; + const ulong bodiesBarrier = 5_000_000; ResourceAvailability barrierBound = new(Disabled: false, OldestBlock: bodiesBarrier); yield return new CapabilitiesScenario( Name: "fast_sync_with_ancient_bodies_barrier_caps_blocks_and_receipts", @@ -126,8 +126,8 @@ private static IEnumerable CapabilitiesScenarios() ExpectedReceipts: Disabled, ExpectedBlocks: Disabled) { HeadNumber = 18_001_000, OldestStateBlock = 0, SyncConfig = new SyncConfig { FastSync = true, PivotNumber = 18_000_000, DownloadBodiesInFastSync = false } }; - const long bodiesBarrierLow = 3_000_000; - const long receiptsBarrierHigh = 6_000_000; + const ulong bodiesBarrierLow = 3_000_000; + const ulong receiptsBarrierHigh = 6_000_000; ResourceAvailability blocksAtBodiesBarrier = new(Disabled: false, OldestBlock: bodiesBarrierLow); ResourceAvailability receiptsAtReceiptsBarrier = new(Disabled: false, OldestBlock: receiptsBarrierHigh); yield return new CapabilitiesScenario( @@ -151,8 +151,8 @@ private static IEnumerable CapabilitiesScenarios() // Mid-sync: bodies/receipts caught up to block 12M from pivot 18M; blocks/receipts oldest // tracks the actual progress, not the eventual barrier. State sync is finished // (OldestStateBlock = pivot) but historical block sync continues. - const long midSyncBody = 12_000_000; - const long midSyncReceipt = 12_500_000; + const ulong midSyncBody = 12_000_000; + const ulong midSyncReceipt = 12_500_000; const ulong midSyncStateFloor = 18_000_000UL; ResourceAvailability midSyncBlocks = new(Disabled: false, OldestBlock: midSyncBody); ResourceAvailability midSyncReceipts = new(Disabled: false, OldestBlock: midSyncReceipt); @@ -213,8 +213,8 @@ private static IEnumerable CapabilitiesScenarios() ExpectedReceipts: Available, ExpectedBlocks: Available) { OldestStateBlock = fullPruneFloor, SyncConfig = fullSync }; - const long retention = 128; - const long memoryHead = 1000; + const ulong retention = 128; + const ulong memoryHead = 1000; ResourceAvailability memoryPruned = new( Disabled: false, OldestBlock: memoryHead - retention, @@ -251,7 +251,7 @@ private static IEnumerable CapabilitiesScenarios() ExpectedReceipts: Available, ExpectedBlocks: Available) { SyncConfig = new SyncConfig { DownloadReceiptsInFastSync = false } }; - const long rollingFloor = 1000; + const ulong rollingFloor = 1000; const uint retentionEpochs = 200; ResourceAvailability rollingPruned = new( Disabled: false, @@ -267,7 +267,7 @@ private static IEnumerable CapabilitiesScenarios() HistoryPruner = MockHistoryPruner(rollingFloor), }; - const long ancientFloor = 500; + const ulong ancientFloor = 500; ResourceAvailability ancientPruned = new(Disabled: false, OldestBlock: ancientFloor); yield return new CapabilitiesScenario( Name: "ancient_barriers_history_pruning_advances_floor", diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 4ce97486d644..a531d6274524 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -163,7 +163,7 @@ public static Transaction GetTransferTxData(ulong nonce, IEthereumEcdsa ethereum SenderAddress = from.Address, To = to, GasPrice = 20.GWei, - DecodedMaxFeePerGas = type >= TxType.EIP1559 ? (ulong)20.GWei : 0UL + DecodedMaxFeePerGas = type >= TxType.EIP1559 ? 20_000_000_000UL : 0UL }; ethereumEcdsa.Sign(from, tx); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilities.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilities.cs index 0e6cc8656c1f..e22c76bd1e06 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilities.cs @@ -40,7 +40,7 @@ public record EthCapabilities( /// Head block number and hash. /// Block number. /// Block hash. -public readonly record struct ChainHead(long Number, Hash256 Hash); +public readonly record struct ChainHead(ulong Number, Hash256 Hash); /// Availability descriptor for one historical data resource. /// true when the resource is completely unavailable on this node. @@ -48,7 +48,7 @@ public record EthCapabilities( /// Retention / deletion strategy. Present only when data is pruned with a rolling window. Omitted for archive nodes or disabled resources. public readonly record struct ResourceAvailability( bool Disabled, - [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] long? OldestBlock = null, + [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] ulong? OldestBlock = null, [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] DeleteStrategy? DeleteStrategy = null); /// Rolling-window deletion strategy for a resource. @@ -56,4 +56,4 @@ public readonly record struct ResourceAvailability( /// Number of recent blocks retained. Per spec this is a JSON integer (not a hex quantity). public readonly record struct DeleteStrategy( string Type, - [property: JsonConverter(typeof(LongRawJsonConverter))] long RetentionBlocks); + [property: JsonConverter(typeof(ULongRawJsonConverter))] ulong RetentionBlocks); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs index 6f496b7fe4ea..f954cc5c9085 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthCapabilitiesProvider.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.History; using Nethermind.State; using Nethermind.Synchronization; @@ -41,7 +42,7 @@ public EthCapabilities GetCapabilities() ulong historyFloor = historyPruner.OldestBlockHeader?.Number ?? 0ul; DeleteStrategy? historyWindow = BuildWindow( - historyConfig.Pruning == PruningModes.Rolling ? (long)historyPruner.GetRetentionBlocks(historyConfig.RetentionEpochs) : 0L); + historyConfig.Pruning == PruningModes.Rolling ? historyPruner.GetRetentionBlocks(historyConfig.RetentionEpochs) : 0UL); ulong lowestReceipt = Math.Max(syncPointers.LowestInsertedReceiptBlockNumber ?? 0ul, receiptsBarrier); ulong lowestBody = Math.Max(syncPointers.LowestInsertedBodyNumber ?? 0ul, bodiesBarrier); @@ -50,10 +51,10 @@ public EthCapabilities GetCapabilities() ResourceAvailability state = BuildState(head, fastSyncing); return new EthCapabilities( - Head: new ChainHead((long)head.Number, head.Hash!), + Head: new ChainHead(head.Number, head.Hash!), State: state, - Receipts: BuildResource(receiptsDownloaded, (long)Math.Max(lowestReceipt, historyFloor), historyWindow), - Blocks: BuildResource(blockTree.BestSuggestedHeader is not null && bodiesDownloaded, (long)Math.Max(lowestBlock, historyFloor), historyWindow), + Receipts: BuildResource(receiptsDownloaded, Math.Max(lowestReceipt, historyFloor), historyWindow), + Blocks: BuildResource(blockTree.BestSuggestedHeader is not null && bodiesDownloaded, Math.Max(lowestBlock, historyFloor), historyWindow), Stateproofs: state); } @@ -65,22 +66,22 @@ private ResourceAvailability BuildState(BlockHeader head, bool fastSyncing) ulong stateFloor = oldestStateBlock ?? 0UL; if (stateBoundary.RetentionWindowBlocks is not { } retention) - return new ResourceAvailability(Disabled: false, OldestBlock: (long)stateFloor, DeleteStrategy: null); + return new ResourceAvailability(Disabled: false, OldestBlock: stateFloor, DeleteStrategy: null); - ulong windowOldest = head.Number >= retention ? head.Number - retention : 0UL; + ulong windowOldest = head.Number.SaturatingSub(retention); ulong stateOldest = Math.Max(stateFloor, windowOldest); // Emit the window only when it's the binding constraint, and report the configured // retention so the value stays accurate before head reaches it. - DeleteStrategy? window = windowOldest >= stateFloor ? BuildWindow((long)retention) : null; - return new ResourceAvailability(Disabled: false, OldestBlock: (long)stateOldest, DeleteStrategy: window); + DeleteStrategy? window = windowOldest >= stateFloor ? BuildWindow(retention) : null; + return new ResourceAvailability(Disabled: false, OldestBlock: stateOldest, DeleteStrategy: window); } private static bool IsDescendingResourceDownloaded(bool fastSyncing, ulong pivot, bool downloadInFastSync, ulong? pointer) => !fastSyncing || (downloadInFastSync && (pivot == 0ul || pointer is not null)); - private static ResourceAvailability BuildResource(bool enabled, long oldestBlock, DeleteStrategy? deleteStrategy) => + private static ResourceAvailability BuildResource(bool enabled, ulong oldestBlock, DeleteStrategy? deleteStrategy) => enabled ? new ResourceAvailability(false, oldestBlock, deleteStrategy) : Disabled; - private static DeleteStrategy? BuildWindow(long retentionBlocks) => + private static DeleteStrategy? BuildWindow(ulong retentionBlocks) => retentionBlocks > 0 ? new DeleteStrategy("window", retentionBlocks) : null; } From 7fdffff5d1f8194c5ab4c9af6c915de5fcc33659 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 21:11:11 +0200 Subject: [PATCH 47/60] review: cleanup ulong test types and receipt-index check JsonRpcServiceTests: align Number/Size TestCase to ulong, drop (long) casts. TraceRpcModuleTests: ModExpGasUsed returns ulong. FeeHistoryOracleTests: maxDistFromHead ulong?, drop redundant cast. Eth70ProtocolHandler: replace opaque (ulong)/(uint) coercion with explicit negative + range check. --- .../JsonRpcServiceTests.cs | 8 ++++---- .../Modules/FeeHistoryOracleTests.cs | 4 ++-- .../Modules/TraceRpcModuleTests.cs | 16 ++++++++-------- .../Subprotocols/Eth/V70/Eth70ProtocolHandler.cs | 3 +-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index cdb76a477e73..665d05ca782f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -206,15 +206,15 @@ private JsonRpcResponse SendRequestWithPool(IRpcModulePool pool, JsonRpcRe return response; } - [TestCase(false, 2L, TestName = "Number")] - [TestCase(true, 513L, TestName = "Size")] - public void Eth_module_populates_block_data(bool assertSize, long expected) + [TestCase(false, 2UL, TestName = "Number")] + [TestCase(true, 513UL, TestName = "Size")] + public void Eth_module_populates_block_data(bool assertSize, ulong expected) { IEthRpcModule ethRpcModule = Substitute.For(); ISpecProvider specProvider = Substitute.For(); ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); BlockForRpc result = RpcTest.AssertSuccess(TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true")); - Assert.That(assertSize ? (long)result.Size : (long)result.Number!.Value, Is.EqualTo(expected)); + Assert.That(assertSize ? (ulong)result.Size : result.Number!.Value, Is.EqualTo(expected)); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs index 466cbeba7641..9abe5c458fb6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs @@ -502,7 +502,7 @@ private static FeeHistoryOracle GetSubstitutedFeeHistoryOracle( IBlockTree? blockTree = null, IReceiptStorage? receiptStorage = null, ISpecProvider? specProvider = null, - int? maxDistFromHead = null, + ulong? maxDistFromHead = null, IReleaseSpec? spec = null) { ISpecProvider provider; @@ -524,7 +524,7 @@ private static FeeHistoryOracle GetSubstitutedFeeHistoryOracle( blockTree ?? Substitute.For(), receiptStorage ?? Substitute.For(), provider, - (ulong?)maxDistFromHead); + maxDistFromHead); } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 631a24ef092d..edcf25bc34bc 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -1497,19 +1497,19 @@ private static byte[] BuildModExpInput() return (context, new BlockParameter(context.Blockchain.BlockTree.Head!.Number)); } - private static long ModExpGasUsed( + private static ulong ModExpGasUsed( Context context, BlockParameter block, string forkName) => - (long)context.TraceRpcModule + context.TraceRpcModule .trace_block(block, forkName) .Data.First(t => t.Type == "call").Result!.GasUsed; - [TestCase(nameof(Istanbul), 13056L, "pre-EIP-2565 formula: 32^2 * 255 / 20 = 13056")] - [TestCase(nameof(Berlin), 1360L, "EIP-2565 formula: ceil(32/8)^2 * 255 / 3 = 16 * 255 / 3 = 1360")] - public async Task trace_block_modexp_gas_cost_respects_fork_override(string forkName, long expectedGas, string reason) + [TestCase(nameof(Istanbul), 13056UL, "pre-EIP-2565 formula: 32^2 * 255 / 20 = 13056")] + [TestCase(nameof(Berlin), 1360UL, "EIP-2565 formula: ceil(32/8)^2 * 255 / 3 = 16 * 255 / 3 = 1360")] + public async Task trace_block_modexp_gas_cost_respects_fork_override(string forkName, ulong expectedGas, string reason) { (Context context, BlockParameter block) = await BuildModExpBlockAsync(); - long gasUsed = ModExpGasUsed(context, block, forkName); + ulong gasUsed = ModExpGasUsed(context, block, forkName); Assert.That(gasUsed, Is.EqualTo(expectedGas), reason); } @@ -1519,9 +1519,9 @@ public async Task trace_block_fork_override_does_not_persist_between_calls() { (Context context, BlockParameter block) = await BuildModExpBlockAsync(); - long firstIstanbulGas = ModExpGasUsed(context, block, nameof(Istanbul)); + ulong firstIstanbulGas = ModExpGasUsed(context, block, nameof(Istanbul)); ModExpGasUsed(context, block, nameof(Berlin)); - long secondIstanbulGas = ModExpGasUsed(context, block, nameof(Istanbul)); + ulong secondIstanbulGas = ModExpGasUsed(context, block, nameof(Istanbul)); Assert.That(secondIstanbulGas, Is.EqualTo(firstIstanbulGas), "the Berlin override from the intervening call must not leak into subsequent calls"); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs index 3ddbfae9d508..12f8b28f1d00 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V70/Eth70ProtocolHandler.cs @@ -112,8 +112,7 @@ private ReceiptsResponse FulfillReceiptsRequest(GetReceiptsMessage70 getReceipts } long requestedStartIndex = blockIndex == 0 ? getReceiptsMessage.FirstBlockReceiptIndex : 0; - // ulong (not uint) so an adversarial negative long isn't truncated. - if ((ulong)requestedStartIndex > (uint)receipts.Length) + if (requestedStartIndex < 0 || requestedStartIndex > receipts.Length) { throw new SubprotocolException($"Invalid firstBlockReceiptIndex {requestedStartIndex} for block receipts length {receipts.Length}"); } From 594bf809de79afc767da5df3ce2e891bf2a5045e Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 21:19:32 +0200 Subject: [PATCH 48/60] review: strip noise comments, add int WithNumber overloads, SaturatingSub in LogScanner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes CAST NOTE / "safe because" comments added in PR that re-explain the int↔ulong boundary already implied by the code. BlockBuilder and BlockHeaderBuilder gain int-arg WithNumber overloads so tests don't need (ulong)i casts. LogScanner switches to SaturatingSub for chunk math. --- .../Builders/BlockBuilder.cs | 2 ++ .../Builders/BlockHeaderBuilder.cs | 2 ++ .../Nethermind.Facade/Find/IndexedLogFinder.cs | 4 ---- .../Nethermind.Facade/Find/LogScanner.cs | 9 +++------ .../Modules/Eth/EthRpcModuleTests.FeeHistory.cs | 4 ++-- .../Nethermind.State.Flat/CompactionSchedule.cs | 17 +++-------------- .../Nethermind.State.Flat/SnapshotCompactor.cs | 7 ------- 7 files changed, 12 insertions(+), 33 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs index 8476e11acd4f..effd06223d71 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockBuilder.cs @@ -37,6 +37,8 @@ public BlockBuilder WithNumber(ulong number) return this; } + public BlockBuilder WithNumber(int number) => WithNumber((ulong)number); + public BlockBuilder WithBaseFeePerGas(UInt256 baseFeePerGas) { TestObjectInternal.Header.BaseFeePerGas = baseFeePerGas; diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs index feb3fc06279c..66fc3c5f13be 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/BlockHeaderBuilder.cs @@ -128,6 +128,8 @@ public BlockHeaderBuilder WithNumber(ulong blockNumber) return this; } + public BlockHeaderBuilder WithNumber(int blockNumber) => WithNumber((ulong)blockNumber); + public BlockHeaderBuilder WithTotalDifficulty(long totalDifficulty) { TestObjectInternal.TotalDifficulty = (ulong)totalDifficulty; diff --git a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs index 9382409ff1a5..d15fe92fce2b 100644 --- a/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs +++ b/src/Nethermind/Nethermind.Facade/Find/IndexedLogFinder.cs @@ -39,8 +39,6 @@ public override IEnumerable FindLogs(LogFilter filter, BlockHeader fr private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, (int from, int to) indexRange, CancellationToken cancellationToken) { - // CAST NOTE: indexRange uses int for log-index storage (kept as int for performance). - // Block numbers in the index fit in int (max ~2 billion blocks). if ((ulong)indexRange.from > fromBlock.Number && FindHeaderOrLogError((ulong)(indexRange.from - 1), cancellationToken) is { } beforeIndex) { foreach (FilterLog log in base.FindLogs(filter, fromBlock, beforeIndex, cancellationToken)) @@ -49,8 +47,6 @@ private IEnumerable FindIndexedLogs(LogFilter filter, BlockHeader fro cancellationToken.ThrowIfCancellationRequested(); - // EnumerateBlockNumbersFor returns IEnumerable (log-index contract kept as long for performance). - // Block numbers from the index are non-negative so the cast is safe. IEnumerable indexBlockNumbers = _logIndexStorage .EnumerateBlockNumbersFor(filter, (ulong)indexRange.from, (ulong)indexRange.to) .Select(static n => (ulong)n); diff --git a/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs b/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs index c28c642f4091..5b61c4954b7a 100644 --- a/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs +++ b/src/Nethermind/Nethermind.Facade/Find/LogScanner.cs @@ -7,6 +7,7 @@ using Nethermind.Facade.Filters.Topics; using Nethermind.Blockchain.Find; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Logging; namespace Nethermind.Facade.Find @@ -23,12 +24,8 @@ public IEnumerable ScanLogs(ulong headBlockNumber, Predicate shouldStopSca for (int i = 0; i < LogScanCutoffChunks; i++) { - bool atGenesis = false; - // headBlockNumber is ulong; chunk arithmetic is safe since we clamp to 0. - ulong startBlockNumber = end.BlockNumber!.Value > LogScanChunkSize - ? end.BlockNumber!.Value - LogScanChunkSize - : 0; - atGenesis = end.BlockNumber!.Value <= LogScanChunkSize; + ulong startBlockNumber = end.BlockNumber!.Value.SaturatingSub((ulong)LogScanChunkSize); + bool atGenesis = end.BlockNumber!.Value <= LogScanChunkSize; BlockParameter start = new(startBlockNumber); LogFilter logFilter = new(0, start, end, addressFilter, topicsFilter); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs index 3eda4436641b..951185eb751b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs @@ -41,7 +41,7 @@ public async Task Eth_feeHistory(long blockCount, string blockParameter, string Block[] blocks = Enumerable.Range(0, excessBlobGas.Length) .Select((i) => Build.A.Block.WithHeader( Build.A.BlockHeader - .WithNumber((ulong)i) + .WithNumber(i) .WithParentHash(new Hash256(Math.Max(0, i - 1).ToString("X").PadLeft(64, '0'))) .WithExcessBlobGas(excessBlobGas[i]) .WithBlobGasUsed(blobGasUsed[i]) @@ -50,7 +50,7 @@ public async Task Eth_feeHistory(long blockCount, string blockParameter, string IBlockTree blockFinder = Substitute.For(); - blockFinder.Head.Returns(Build.A.Block.WithNumber((ulong)(excessBlobGas.Length - 1)).TestObject); + blockFinder.Head.Returns(Build.A.Block.WithNumber(excessBlobGas.Length - 1).TestObject); blockFinder.FindBlock(Arg.Any(), Arg.Any()) .Returns(ci => blocks[(int)(((BlockParameter)ci[0]).BlockNumber ?? 0)]); blockFinder.FindBlock(Arg.Any(), Arg.Any(), Arg.Any()) diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index f3b52b307000..b3a97fc01e88 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -19,12 +19,10 @@ public CompactionSchedule( IFlatDbConfig config, ILogManager logManager) { - // Validate using the raw int value before storing. int cs = config.CompactSize; if (cs > 1 && (cs & (cs - 1)) != 0) throw new ArgumentException("Compact size must be a power of 2"); - // Safe: validated above — cs is 1 or a small positive power-of-2. _compactSize = (ulong)cs; ILogger logger = logManager.GetClassLogger(); @@ -39,11 +37,8 @@ public int GetCompactSize(ulong blockNumber) ulong shifted = blockNumber + _offset; // Isolate the lowest set bit via two's-complement identity: x & (~x + 1). - // No overflow risk: shifted == 0 is excluded by the guard above. ulong lowestBit = shifted & (~shifted + 1UL); - // _compactSize is a small power-of-2 (≤ int.MaxValue by construction), - // so Math.Min never returns a value that overflows int. return (int)Math.Min(lowestBit, _compactSize); } @@ -88,8 +83,7 @@ private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger return generated; } - // Boundary cast — on-disk RLP format uses long for backward-compatibility. - // Decode as long first so we can detect DB corruption (negative values). + // On-disk RLP format uses long for backward compatibility; decode as long to detect corrupt negatives. long decoded = stored.AsRlpValueContext().DecodeLong(); if (decoded < 0) { @@ -98,20 +92,15 @@ private ulong ResolveOffset(IDb metadataDb, IFlatDbConfig config, ILogger logger } if (logger.IsInfo) logger.Info($"Loaded FlatDb compaction offset {decoded}"); - // Boundary cast — safe: negativity excluded by the guard immediately above. return (ulong)decoded; } private ulong GenerateAndPersist(IDb metadataDb) { - // Generate in [0, int.MaxValue) so the value encodes cleanly as a - // non-negative long in the on-disk RLP format. + // Generate in [0, int.MaxValue) so the value encodes cleanly as a non-negative long + // in the on-disk RLP format (kept as long for database backward compatibility). long offset = Random.Shared.NextInt64(0, int.MaxValue); - - // Keep the on-disk encoding as long (RLP) for database compatibility. metadataDb.Set(MetadataDbKeys.FlatDbCompactionOffset, Rlp.Encode(offset).Bytes); - - // Boundary cast — safe: NextInt64(0, int.MaxValue) is always in [0, 2³¹ − 1]. return (ulong)offset; } } diff --git a/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs b/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs index 7c3aa942f271..b333dcb46229 100644 --- a/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs +++ b/src/Nethermind/Nethermind.State.Flat/SnapshotCompactor.cs @@ -68,9 +68,6 @@ public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) if (!isFullCompaction) { // Save memory by removing the compacted state from previous compaction. - // Cast _compactSize (int) to ulong: safe because config guarantees _compactSize > 0 - // and blockNumber >= (ulong)_compactSize in any valid sync state (we only compact - // already-downloaded blocks). No underflow is possible in practice. foreach (StateId id in _snapshotRepository.GetStatesAtBlockNumber(blockNumber - (ulong)_compactSize)) { if (_snapshotRepository.RemoveAndReleaseCompactedKnownState(id)) @@ -79,9 +76,6 @@ public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) } } - // Cast compactSize (int) to ulong: safe because compactSize > 1 is already verified - // above and blockNumber is always >= compactSize (compaction only runs once blocks - // are available). No underflow possible. ulong startingBlockNumber = blockNumber - (ulong)compactSize; SnapshotPooledList snapshots = _snapshotRepository.AssembleSnapshotsUntil(snapshot.To, startingBlockNumber, compactSize); @@ -94,7 +88,6 @@ public SnapshotPooledList GetSnapshotsToCompact(Snapshot snapshot) return SnapshotPooledList.Empty(); } - // Both sides are now ulong — no ambiguous operator. if (snapshots[0].From.BlockNumber != startingBlockNumber) { // Could happen especially at start where the block may not be aligned, but not a big problem. From c1772970d601b7040d2202711ce5ba6d8352b32d Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 21:24:57 +0200 Subject: [PATCH 49/60] review: more comment/style cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DebugBridge: drop redundant NOTE on CreateFailTrace; HistoryPruner: drop section-divider comment; Metrics.OldestStoredBlockAccessListBlockNumber: make nullable; MemoryHintMan: 1UL.GB → 1UL.GiB for the hint defaults, simplify the memoryHint nullable assignment. --- src/Nethermind/Nethermind.History/HistoryPruner.cs | 2 -- src/Nethermind/Nethermind.History/Metrics.cs | 2 +- src/Nethermind/Nethermind.Init/MemoryHintMan.cs | 6 +++--- .../Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs | 2 -- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.History/HistoryPruner.cs b/src/Nethermind/Nethermind.History/HistoryPruner.cs index 40d69e0d3fcf..f698ec8b3d3f 100644 --- a/src/Nethermind/Nethermind.History/HistoryPruner.cs +++ b/src/Nethermind/Nethermind.History/HistoryPruner.cs @@ -167,8 +167,6 @@ public BlockHeader? OldestBlockHeader } } - // ── Internal helpers ────────────────────────────────────────────────────── - private ulong? CalculateRollingCutoff(uint retentionEpochs) { ulong? head = _blockTree.Head?.Number; diff --git a/src/Nethermind/Nethermind.History/Metrics.cs b/src/Nethermind/Nethermind.History/Metrics.cs index 76d5ad008eae..7054b2db54c2 100644 --- a/src/Nethermind/Nethermind.History/Metrics.cs +++ b/src/Nethermind/Nethermind.History/Metrics.cs @@ -14,7 +14,7 @@ public static class Metrics [GaugeMetric] [Description("The number of the oldest block access list stored.")] - public static ulong OldestStoredBlockAccessListBlockNumber { get; set; } + public static ulong? OldestStoredBlockAccessListBlockNumber { get; set; } [CounterMetric] [Description("The number of the historical blocks that have been pruned (since restart).")] diff --git a/src/Nethermind/Nethermind.Init/MemoryHintMan.cs b/src/Nethermind/Nethermind.Init/MemoryHintMan.cs index 4c99189ee247..94d435b21b4c 100644 --- a/src/Nethermind/Nethermind.Init/MemoryHintMan.cs +++ b/src/Nethermind/Nethermind.Init/MemoryHintMan.cs @@ -34,8 +34,8 @@ public void SetMemoryAllowances( ITxPoolConfig txPoolConfig, uint cpuCount) { - ulong? memoryHint = initConfig.MemoryHint is { } h ? (ulong)h : null; - TotalMemory = memoryHint ?? 1UL.GB; + ulong? memoryHint = initConfig.MemoryHint; + TotalMemory = memoryHint ?? 1UL.GiB; ValidateCpuCount(cpuCount); checked @@ -44,7 +44,7 @@ public void SetMemoryAllowances( if (_logger.IsInfo) _logger.Info("Setting up memory allowances"); if (_logger.IsInfo) _logger.Info($" Memory hint: {TotalMemory / 1000 / 1000,5} MB"); - _remainingMemory = memoryHint ?? 1UL.GB; + _remainingMemory = memoryHint ?? 1UL.GiB; _remainingMemory -= GeneralMemory; if (_logger.IsInfo) _logger.Info($" General memory: {GeneralMemory / 1000 / 1000,5} MB"); AssignPeersMemory(networkConfig); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs index 5929d7a63414..58fdfcf3b00b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs @@ -255,8 +255,6 @@ private IEnumerable GetBundleTrace(TransactionBundle bundle, Bl } } - // NOTE: gasLimit is ulong? since Transaction.GasLimit and TransactionForRpc.Gas are ulong. - // GethLikeTxTrace.Gas is also ulong. No overflow risk here. static GethLikeTxTrace? CreateFailTrace(ulong? gasLimit) => new() { Failed = true, Gas = gasLimit ?? 0UL, ReturnValue = [] }; } } From 86078fef6efabbef1ac65a66ef850482f28c9814 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 21:30:34 +0200 Subject: [PATCH 50/60] review: explicit (int) array size, fold ulong-aware Math.Min into UnclesValidator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StatelessBlockTree.Prefetch: explicit `(int)length` for array creation so the ulong→int narrowing is on display. UnclesValidator.IsKin: collapse the header.Number ternary into Math.Min((ulong)relativeDepth, header.Number); the previous form needed a separate (int) cast on the ulong block number. --- .../Nethermind.Consensus/Stateless/StatelessBlockTree.cs | 2 +- .../Nethermind.Consensus/Validators/UnclesValidator.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs index 16c7d8554cd9..bebcf880cd45 100644 --- a/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs +++ b/src/Nethermind/Nethermind.Consensus/Stateless/StatelessBlockTree.cs @@ -234,7 +234,7 @@ public event EventHandler? OnForkChoiceUpd public Task Prefetch(BlockHeader blockHeader, CancellationToken cancellationToken) { const ulong length = BlockhashCache.MaxDepth + 1; - Hash256[] result = new Hash256[length]; + Hash256[] result = new Hash256[(int)length]; result[0] = blockHeader.Hash; for (ulong i = 1; i < length; i++) { diff --git a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs index b5c2c143765e..685bc9a81c67 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/UnclesValidator.cs @@ -104,14 +104,14 @@ public bool Validate(BlockHeader header, BlockHeader[] uncles) private static bool IsKin(BlockHeader header, BlockHeader uncle, int relationshipLevel, ReadOnlySpan ancestors, int ancestorsCount) { int relativeDepth = Math.Min(ancestorsCount, relationshipLevel); - int maxDepth = header.Number >= (ulong)relativeDepth ? relativeDepth : (int)header.Number; + ulong maxDepth = Math.Min((ulong)relativeDepth, header.Number); - if (uncle.Number + (ulong)maxDepth < header.Number) + if (uncle.Number + maxDepth < header.Number) { return false; } - for (int depth = 0; depth < maxDepth; depth++) + for (int depth = 0; depth < (int)maxDepth; depth++) { BlockHeader parent = ancestors[depth]; From 5bd99b13a877db11be4fc9d91461cd97c9588117 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 21:34:27 +0200 Subject: [PATCH 51/60] review(test): drop redundant (ulong) cast in Capabilities scenario builder retention is already const ulong; the cast was leftover from when the RetentionWindow init was long. --- .../Modules/Eth/EthRpcModuleTests.Capabilities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs index deb56f9822c9..65ed6ff729cc 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.Capabilities.cs @@ -223,7 +223,7 @@ private static IEnumerable CapabilitiesScenarios() Name: "memory_pruning_window_dominates_old_floor", ExpectedState: memoryPruned, ExpectedStateproofs: memoryPruned, ExpectedReceipts: Available, ExpectedBlocks: Available) - { RetentionWindow = (ulong)retention, HeadNumber = memoryHead, OldestStateBlock = 0, SyncConfig = fullSync }; + { RetentionWindow = retention, HeadNumber = memoryHead, OldestStateBlock = 0, SyncConfig = fullSync }; // Floor dominates window — DeleteStrategy is suppressed so oldestBlock and head-retentionBlocks stay consistent. const ulong recentPivot = 950UL; From 26af56c35a71f3dfab6ceb850b51a17b5633bd95 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 23:11:50 +0200 Subject: [PATCH 52/60] review(state.flat): strip stale comments; PersistenceManager depth/size fields ulong Drop the "Safe: ulong block numbers are well within long range" / "Flat persistence keys state by signed block number" / "Non-trivial: subtraction of two ulongs" narration that all restated the new ulong typing. PersistenceManager _minReorgDepth / _maxReorgDepth / _compactSize are now ulong, removing the per-use (ulong) casts. Also drop the leftover comments in CompactionSchedule.NextFullCompactionAfter. --- .../CompactionSchedule.cs | 6 ----- .../PersistenceManager.cs | 22 +++++-------------- .../ScopeProvider/FlatReadOnlyTrieStore.cs | 2 +- .../ScopeProvider/FlatWorldStateScope.cs | 1 - 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs index b3a97fc01e88..045e8d645d57 100644 --- a/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs +++ b/src/Nethermind/Nethermind.State.Flat/CompactionSchedule.cs @@ -45,16 +45,10 @@ public int GetCompactSize(ulong blockNumber) public ulong NextFullCompactionAfter(ulong from) { if (_compactSize <= 1) return ulong.MaxValue; - - // Sentinel: caller has no meaningful "from" block; no next compaction - // can be computed, so propagate the sentinel rather than wrapping into - // broken signed arithmetic. if (from == ulong.MaxValue) return ulong.MaxValue; ulong mod = (from + _offset) % _compactSize; ulong distance = mod == 0 ? _compactSize : _compactSize - mod; - // Practically unreachable at realistic chain heights, but explicit so a degenerate - // `from` near ulong.MaxValue doesn't wrap into a wildly-wrong "next" boundary. return from > ulong.MaxValue - distance ? ulong.MaxValue : from + distance; } diff --git a/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs b/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs index 8e45922ca99b..da29ee3075d5 100644 --- a/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs +++ b/src/Nethermind/Nethermind.State.Flat/PersistenceManager.cs @@ -28,9 +28,9 @@ public class PersistenceManager( ILogManager logManager) : IPersistenceManager { private readonly ILogger _logger = logManager.GetClassLogger(); - private readonly int _minReorgDepth = configuration.MinReorgDepth; - private readonly int _maxReorgDepth = configuration.MaxReorgDepth; - private readonly int _compactSize = configuration.CompactSize; + private readonly ulong _minReorgDepth = (ulong)configuration.MinReorgDepth; + private readonly ulong _maxReorgDepth = (ulong)configuration.MaxReorgDepth; + private readonly ulong _compactSize = (ulong)configuration.CompactSize; private readonly ICompactionSchedule _schedule = compactionSchedule; private readonly List<(Hash256, TreePath)> _trieNodesSortBuffer = []; // Presort make it faster private readonly Lock _persistenceLock = new(); @@ -116,30 +116,23 @@ public StateId GetCurrentPersistedStateId() StateId currentPersistedState = GetCurrentPersistedStateId(); ulong finalizedBlockNumber = finalizedStateProvider.FinalizedBlockNumber; - // Non-trivial: subtraction of two ulongs. Safe here because lastSnapshotNumber is the - // tip of the in-memory chain which is always >= currentPersistedState.BlockNumber by - // invariant. If the invariant is violated the result would wrap; the subsequent - // comparisons against _minReorgDepth / _maxReorgDepth (int) would then be nonsensical. - // A Debug.Assert guards this in debug builds. Debug.Assert(currentPersistedState == StateId.PreGenesis || lastSnapshotNumber >= currentPersistedState.BlockNumber, "Latest snapshot must be at or ahead of the last persisted block."); ulong inMemoryStateDepth = currentPersistedState == StateId.PreGenesis ? lastSnapshotNumber + 1 : lastSnapshotNumber - currentPersistedState.BlockNumber; - if (inMemoryStateDepth - (ulong)_compactSize < (ulong)_minReorgDepth) + if (inMemoryStateDepth - _compactSize < _minReorgDepth) { - // Keep some state in memory return null; } Snapshot? snapshotToPersist; - // NextFullCompactionAfter now returns ulong to match block number type. ulong nextCompactedBoundary = _schedule.NextFullCompactionAfter(currentPersistedState.BlockNumber); if (nextCompactedBoundary > finalizedBlockNumber) { - if (inMemoryStateDepth <= (ulong)_maxReorgDepth) + if (inMemoryStateDepth <= _maxReorgDepth) { // Unfinalized, and still under max reorg depth return null; @@ -255,13 +248,10 @@ public void ResetPersistedStateId() internal void PersistSnapshot(Snapshot snapshot) { - // Non-trivial: subtraction of two ulongs. Safe by invariant — snapshot.To always - // follows snapshot.From on the canonical chain. The ! null-forgiving operators from - // the old code are removed since BlockNumber is now a non-nullable ulong. ulong compactLength = snapshot.To.BlockNumber - snapshot.From.BlockNumber; // Usually at the start of the application - if (compactLength != (ulong)_compactSize && _logger.IsTrace) _logger.Trace($"Persisting non compacted state of length {compactLength}"); + if (compactLength != _compactSize && _logger.IsTrace) _logger.Trace($"Persisting non compacted state of length {compactLength}"); long sw = Stopwatch.GetTimestamp(); using (IPersistence.IWriteBatch batch = persistence.CreateWriteBatch(snapshot.From, snapshot.To)) diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs index 3bf43cb6a74d..c5983ccbbfb7 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatReadOnlyTrieStore.cs @@ -36,7 +36,7 @@ public TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256 public bool HasRoot(Hash256 stateRoot) => true; public bool HasRoot(Hash256 stateRoot, ulong blockNumber) => - flatDbManager.HasStateForBlock(new StateId(blockNumber, stateRoot)); // Safe: ulong block numbers are well within long range + flatDbManager.HasStateForBlock(new StateId(blockNumber, stateRoot)); public IDisposable BeginScope(BlockHeader? baseBlock) { diff --git a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs index eb7ee3efb449..e9aaf043e784 100644 --- a/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs +++ b/src/Nethermind/Nethermind.State.Flat/ScopeProvider/FlatWorldStateScope.cs @@ -372,7 +372,6 @@ public void Commit(ulong blockNumber) _storages.Clear(); - // Flat persistence keys state by signed block number; mainnet height fits in long. StateId newStateId = new(blockNumber, RootHash); bool shouldAddSnapshot = !_isReadOnly && _currentStateId != newStateId; (Snapshot? newSnapshot, TransientResource? cachedResource) = _snapshotBundle.CollectAndApplySnapshot(_currentStateId, newStateId, shouldAddSnapshot); From 7ddcf2b2f6e1696d7545b8c643957b58f84b63d6 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 23:16:47 +0200 Subject: [PATCH 53/60] review(specs): ulong types, drop noise comments and unused converter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AllocationJson.Nonce: UInt256 → ulong; ChainSpecLoader drops two (ulong) casts. - ChainSpecEthereumSealJson + GethGenesisJson Nonce: ULongRawJsonConverter → ULongConverter (the raw-write variant has no production caller and the default handles hex strings). - BlockRewardConverter: read the dictionary key as ulong directly via ULongConverter.FromString instead of UInt256 → (ulong) cast. - DifficultyBombDelaysConverter: unused, deleted. - ForkSchedule.timestampIndex: int → ulong (drops the per-add (ulong) cast). - GethGenesisLoader, ChainSpecLoader: drop the leftover "cast is safe" / "null when …" comments that re-explained the type system. --- .../ChainSpecStyle/ChainSpecLoader.cs | 5 +- .../ChainSpecStyle/GethGenesisLoader.cs | 2 - .../ChainSpecStyle/Json/AllocationJson.cs | 2 +- .../Json/BlockRewardConverter.cs | 4 +- .../Json/ChainSpecEthereumSealJson.cs | 2 +- .../Json/DifficultyBombDelaysConverter.cs | 64 ------------------- .../ChainSpecStyle/Json/GethGenesisJson.cs | 2 +- .../Nethermind.Specs/ForkSchedule.cs | 4 +- 8 files changed, 8 insertions(+), 77 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs index 179913a841b5..d8766e9fbdf5 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs @@ -275,7 +275,6 @@ private static void LoadTransitions(ChainSpecJson chainSpecJson, ChainSpec chain chainSpec.TangerineWhistleBlockNumber = chainSpec.Parameters.Eip150Transition; chainSpec.SpuriousDragonBlockNumber = chainSpec.Parameters.Eip160Transition; chainSpec.ByzantiumBlockNumber = chainSpec.Parameters.Eip140Transition; - // null when Eip1283DisableTransition is absent (chain never had a Constantinople/fix split). chainSpec.ConstantinopleBlockNumber = chainSpec.Parameters.Eip1283DisableTransition is null ? null @@ -469,7 +468,7 @@ private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chain if (chainSpecJson.CodeHashes is null || !chainSpecJson.CodeHashes.TryGetValue(codeHashString, out byte[] codeHash)) throw new ArgumentException($"CodeHash {account.Value.CodeHash} is not found"); chainSpec.Allocations[address] = new ChainSpecAllocation( account.Value.Balance ?? UInt256.Zero, - (ulong)account.Value.Nonce, + account.Value.Nonce, codeHash, account.Value.Constructor, account.Value.GetConvertedStorage()); @@ -478,7 +477,7 @@ private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chain { chainSpec.Allocations[address] = new ChainSpecAllocation( account.Value.Balance ?? UInt256.Zero, - (ulong)account.Value.Nonce, + account.Value.Nonce, account.Value.Code, account.Value.Constructor, account.Value.GetConvertedStorage()); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs index f4d6941bd36c..69f5e183d2cd 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/GethGenesisLoader.cs @@ -210,8 +210,6 @@ private static void LoadGenesis(GethGenesisJson gethGenesisJson, ChainSpec chain beneficiary, difficulty, 0, - // Pre-existing cast: UInt256 -> ulong. Safe for any valid genesis gas limit - // (would only overflow above ~1.8x10^19, which is physically impossible). gasLimit, timestamp, extraData) diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/AllocationJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/AllocationJson.cs index 8c4fa37ff0ba..85d19569d0d8 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/AllocationJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/AllocationJson.cs @@ -15,7 +15,7 @@ public class AllocationJson public UInt256? Balance { get; set; } - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public byte[]? Code { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs index 3a41759b7efd..f6f36b8bc8e3 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/BlockRewardConverter.cs @@ -39,9 +39,7 @@ public override SortedDictionary Read(ref Utf8JsonReader reader, throw new ArgumentException("Cannot deserialize dictionary."); } - UInt256 property = - UInt256Converter.ReadHex(reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan); - ulong key = (ulong)property; + ulong key = ULongConverter.FromString(reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan); reader.Read(); if (reader.TokenType != JsonTokenType.String) { diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs index cca83bbfb291..fc4dfb8a3ce6 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecEthereumSealJson.cs @@ -9,7 +9,7 @@ namespace Nethermind.Specs.ChainSpecStyle.Json { public class ChainSpecEthereumSealJson { - [JsonConverter(typeof(ULongRawJsonConverter))] + [JsonConverter(typeof(ULongConverter))] public ulong Nonce { get; set; } public Hash256 MixHash { get; set; } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs deleted file mode 100644 index d5f666794767..000000000000 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Text.Json; -using System.Text.Json.Serialization; -using Nethermind.Serialization.Json; - -namespace Nethermind.Specs.ChainSpecStyle.Json; - -public class DifficultyBombDelaysConverter : JsonConverter> -{ - public override void Write(Utf8JsonWriter writer, IDictionary value, - JsonSerializerOptions options) => throw new NotSupportedException(); - - public override IDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - Dictionary value = []; - if (reader.TokenType == JsonTokenType.StartObject) - { - reader.Read(); - while (reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new ArgumentException("Cannot deserialize dictionary."); - } - - ReadOnlySpan keySpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - ulong key = NumericConverterHelper.Parse(keySpan); - - reader.Read(); - - ulong delay; - if (reader.TokenType == JsonTokenType.String) - { - ReadOnlySpan valSpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; - delay = NumericConverterHelper.Parse(valSpan); - } - else if (reader.TokenType == JsonTokenType.Number) - { - delay = reader.GetUInt64(); - } - else - { - throw new ArgumentException("Cannot deserialize dictionary."); - } - - value.Add(key, delay); - - reader.Read(); - } - } - else - { - throw new ArgumentException("Cannot deserialize dictionary."); - } - - return value; - } -} diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs index 140743373dc0..e737569de2a1 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisJson.cs @@ -19,7 +19,7 @@ public class GethGenesisJson public Dictionary? Alloc { get; set; } - [JsonConverter(typeof(ULongRawJsonConverter))] + [JsonConverter(typeof(ULongConverter))] public ulong Nonce { get; set; } public ulong? Timestamp { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ForkSchedule.cs b/src/Nethermind/Nethermind.Specs/ForkSchedule.cs index 16043d3a2db8..847bf81229ac 100644 --- a/src/Nethermind/Nethermind.Specs/ForkSchedule.cs +++ b/src/Nethermind/Nethermind.Specs/ForkSchedule.cs @@ -104,7 +104,7 @@ public ForkActivation[] ToTransitionActivations( ForkActivation[] result = new ForkActivation[count]; prepend.CopyTo(result); int index = prepend.Length; - int timestampIndex = 0; + ulong timestampIndex = 0; for (int i = 1; i < _entries.Count; i++) { ForkSpec fork = _entries[i]; @@ -116,7 +116,7 @@ public ForkActivation[] ToTransitionActivations( else if (fork.Timestamp is { } timestamp) { ulong blockForTimestamp = incrementBlockPerTimestampFork - ? postMergeBlock + (ulong)timestampIndex + ? postMergeBlock + timestampIndex : postMergeBlock; result[index++] = (blockForTimestamp, timestamp); timestampIndex++; From b65b34ad03647a631838609f9d1e31226413cfc9 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 23:24:32 +0200 Subject: [PATCH 54/60] review(state): nonce + balance type fixes; restore DifficultyBombDelaysConverter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AccountProof.Nonce: UInt256 → ulong (protocol nonce is ulong); ProofJsonConverter pulls the ulong converter for the field. - BlockAccessListBasedWorldState.TryGetAccount: balance stays UInt256 instead of being truncated to ulong; AccountStruct ctor already takes UInt256. - WorldState.IsNonZeroAccount: simplify !(Nonce == 0) → Nonce != 0. - IWorldState.CommitTree gains int overload so callers writing for-loop counters don't need (ulong) casts (used by WorldStateManagerTests). - WorldStateManagerTests.lastBlock: int → ulong; loop counter ulong; drops the (ulong)i / (ulong)lastBlock casts. - BlockchainTestStreamingTracerTests: drop (ulong)(b + 1) cast (new int WithNumber). - DifficultyBombDelaysConverter: restored — still referenced from EthashChainSpecEngineParameters.cs. (Deletion in the previous commit was a false positive: grep missed the [JsonConverter(typeof(...))] attribute usage.) --- .../Nethermind.Evm/State/IWorldState.cs | 2 + .../Json/DifficultyBombDelaysConverter.cs | 64 +++++++++++++++++++ .../BlockchainTestStreamingTracerTests.cs | 2 +- .../Proofs/AccountProofCollectorTests.cs | 12 ++-- .../WorldStateManagerTests.cs | 14 ++-- .../BlockAccessListBasedWorldState.cs | 6 +- .../Nethermind.State/Proofs/AccountProof.cs | 5 +- src/Nethermind/Nethermind.State/WorldState.cs | 2 +- 8 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs diff --git a/src/Nethermind/Nethermind.Evm/State/IWorldState.cs b/src/Nethermind/Nethermind.Evm/State/IWorldState.cs index 10739f47144f..26f683535a0d 100644 --- a/src/Nethermind/Nethermind.Evm/State/IWorldState.cs +++ b/src/Nethermind/Nethermind.Evm/State/IWorldState.cs @@ -141,6 +141,8 @@ public interface IWorldState : IJournal, IReadOnlyStateProvider /// void CommitTree(ulong blockNumber); + void CommitTree(int blockNumber) => CommitTree((ulong)blockNumber); + ArrayPoolList? GetAccountChanges(); void ResetTransient(); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs new file mode 100644 index 000000000000..d5f666794767 --- /dev/null +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/DifficultyBombDelaysConverter.cs @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using Nethermind.Serialization.Json; + +namespace Nethermind.Specs.ChainSpecStyle.Json; + +public class DifficultyBombDelaysConverter : JsonConverter> +{ + public override void Write(Utf8JsonWriter writer, IDictionary value, + JsonSerializerOptions options) => throw new NotSupportedException(); + + public override IDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, + JsonSerializerOptions options) + { + Dictionary value = []; + if (reader.TokenType == JsonTokenType.StartObject) + { + reader.Read(); + while (reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + ReadOnlySpan keySpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + ulong key = NumericConverterHelper.Parse(keySpan); + + reader.Read(); + + ulong delay; + if (reader.TokenType == JsonTokenType.String) + { + ReadOnlySpan valSpan = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + delay = NumericConverterHelper.Parse(valSpan); + } + else if (reader.TokenType == JsonTokenType.Number) + { + delay = reader.GetUInt64(); + } + else + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + value.Add(key, delay); + + reader.Read(); + } + } + else + { + throw new ArgumentException("Cannot deserialize dictionary."); + } + + return value; + } +} diff --git a/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs b/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs index dedc4d11de7e..04077b9e94dc 100644 --- a/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs +++ b/src/Nethermind/Nethermind.State.Test.Runner.Test/BlockchainTestStreamingTracerTests.cs @@ -45,7 +45,7 @@ public void Tracer_handles_blocks_and_transactions(int blockCount, int txPerBloc for (int b = 0; b < blockCount; b++) { - tracer.StartNewBlockTrace(Build.A.Block.WithNumber((ulong)(b + 1)).TestObject); + tracer.StartNewBlockTrace(Build.A.Block.WithNumber(b + 1).TestObject); for (uint t = 0; t < txPerBlock; t++) { tracer.StartNewTxTrace(Build.A.Transaction.WithValue(t + 1).WithNonce(t).TestObject); diff --git a/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs b/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs index 5990adf0a86f..cf96e9019a85 100644 --- a/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs +++ b/src/Nethermind/Nethermind.State.Test/Proofs/AccountProofCollectorTests.cs @@ -227,10 +227,10 @@ public void Nonce_is_correct() StateTree tree = CreateTwoAccountTree(account1, account2); AccountProof proof = CollectProof(tree, TestItem.AddressA); - Assert.That(proof.Nonce, Is.EqualTo((UInt256)account1.Nonce)); + Assert.That(proof.Nonce, Is.EqualTo(account1.Nonce)); AccountProof proof2 = CollectProof(tree, TestItem.AddressB); - Assert.That(proof2.Nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(proof2.Nonce, Is.EqualTo(0UL)); } [Test] @@ -402,7 +402,7 @@ public void Shows_empty_values_when_account_is_missing() tree.Accept(accountProofCollector, tree.RootHash); AccountProof proof = accountProofCollector.BuildResult(); Assert.That(proof.Balance, Is.EqualTo((UInt256)0)); - Assert.That(proof.Nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(proof.Nonce, Is.EqualTo(0UL)); Assert.That(proof.CodeHash, Is.EqualTo(Hash256.Zero)); Assert.That(proof.StorageRoot, Is.EqualTo(Hash256.Zero)); } @@ -421,7 +421,7 @@ public void Existing_empty_account_keeps_canonical_empty_hashes() Assert.Multiple(() => { Assert.That(proof.Balance, Is.EqualTo(UInt256.Zero)); - Assert.That(proof.Nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(proof.Nonce, Is.EqualTo(0UL)); Assert.That(proof.CodeHash, Is.EqualTo(Keccak.OfAnEmptyString)); Assert.That(proof.StorageRoot, Is.EqualTo(Keccak.EmptyTreeHash)); }); @@ -587,7 +587,7 @@ public void _Test_storage_failed_case(string historicallyFailingCase) AccountProof accountProof = collector.BuildResult(); Assert.That(accountProof.Address, Is.EqualTo(address)); Assert.That(accountProof.Balance, Is.EqualTo((UInt256)accountIndex)); - Assert.That(accountProof.Nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(accountProof.Nonce, Is.EqualTo(0UL)); Assert.That(accountProof.CodeHash, Is.EqualTo(Keccak.OfAnEmptyString)); if (accountIndex != 0) Assert.That(accountProof.StorageRoot, Is.Not.EqualTo(Keccak.EmptyTreeHash)); Assert.That(accountProof.StorageProofs.Length, Is.EqualTo(accountIndex)); @@ -661,7 +661,7 @@ public void Chaotic_test() AccountProof accountProof = collector.BuildResult(); Assert.That(accountProof.Address, Is.EqualTo(addressesWithStorage[i].Address)); Assert.That(accountProof.Balance, Is.EqualTo((UInt256)i)); - Assert.That(accountProof.Nonce, Is.EqualTo(UInt256.Zero)); + Assert.That(accountProof.Nonce, Is.EqualTo(0UL)); Assert.That(accountProof.CodeHash, Is.EqualTo(Keccak.OfAnEmptyString)); if (i != 0) Assert.That(accountProof.StorageRoot, Is.Not.EqualTo(Keccak.EmptyTreeHash)); Assert.That(accountProof.StorageProofs.Length, Is.EqualTo(i)); diff --git a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs index 478f6354f7fb..32bf997bd379 100644 --- a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs @@ -76,7 +76,7 @@ public void ShouldNotSupportHashLookupOnHalfpath(INodeStorage.KeyScheme keySchem [Test] public void ShouldAnnounceReorgOnDispose() { - int lastBlock = 256; + ulong lastBlock = 256; IBlockTree blockTree = Substitute.For(); IConfigProvider configProvider = new ConfigProvider(); @@ -84,8 +84,8 @@ public void ShouldAnnounceReorgOnDispose() configProvider.GetConfig().Enabled = false; ulong reorgDepth = configProvider.GetConfig().SnapServingMaxDepth; IFinalizedStateProvider manualFinalizedStateProvider = Substitute.For(); - manualFinalizedStateProvider.FinalizedBlockNumber.Returns((ulong)lastBlock - reorgDepth); - manualFinalizedStateProvider.GetFinalizedStateRootAt((ulong)lastBlock - reorgDepth) + manualFinalizedStateProvider.FinalizedBlockNumber.Returns(lastBlock - reorgDepth); + manualFinalizedStateProvider.GetFinalizedStateRootAt(lastBlock - reorgDepth) .Returns(new Hash256("0xec6063a04d48f4b2258f36efaef76a23ba61875f5303fcf8ede2f5d160def35d")); { @@ -107,11 +107,11 @@ public void ShouldAnnounceReorgOnDispose() stateRoot = worldState.StateRoot; } - for (int i = 2; i <= lastBlock; i++) + for (ulong i = 2; i <= lastBlock; i++) { BlockHeader baseBlock = Build.A.BlockHeader .WithStateRoot(stateRoot) - .WithNumber((ulong)(i - 1)) + .WithNumber(i - 1) .TestObject; // Model production: the driver clears prewarmer caches between blocks; do the same here. @@ -120,13 +120,13 @@ public void ShouldAnnounceReorgOnDispose() { worldState.IncrementNonce(TestItem.AddressA, 1); worldState.Commit(Cancun.Instance); - worldState.CommitTree((ulong)i); + worldState.CommitTree(i); stateRoot = worldState.StateRoot; } } } - blockTree.Received().BestPersistedState = (ulong)lastBlock - reorgDepth; + blockTree.Received().BestPersistedState = lastBlock - reorgDepth; } [Test] diff --git a/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs b/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs index 596f561b3f15..05f5cec785f7 100644 --- a/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs +++ b/src/Nethermind/Nethermind.State/BlockAccessListBasedWorldState.cs @@ -185,7 +185,7 @@ public override bool TryGetAccount(Address address, out AccountStruct account) bool exists = parentReader.TryGetAccount(address, out account); ulong nonce = exists ? account.Nonce : 0; - ulong balance = exists ? (ulong)account.Balance : 0UL; + UInt256 balance = exists ? account.Balance : UInt256.Zero; ValueHash256 storageRoot = exists ? account.StorageRoot : Keccak.EmptyTreeHash.ValueHash256; ValueHash256 codeHash = exists ? account.CodeHash : Keccak.OfAnEmptyString.ValueHash256; @@ -198,9 +198,7 @@ public override bool TryGetAccount(Address address, out AccountStruct account) if (accountChanges.TryGetLastBalanceChangeBefore(_blockAccessIndex, out BalanceChange balanceChange)) { - // BalanceChange.Value is UInt256; Account.Balance is ulong. Cast is safe — - // total ETH supply is well below 2^64 Wei. - balance = (ulong)balanceChange.Value; + balance = balanceChange.Value; hasPriorChange = true; } diff --git a/src/Nethermind/Nethermind.State/Proofs/AccountProof.cs b/src/Nethermind/Nethermind.State/Proofs/AccountProof.cs index e1975c83aaa0..3489221ae47b 100644 --- a/src/Nethermind/Nethermind.State/Proofs/AccountProof.cs +++ b/src/Nethermind/Nethermind.State/Proofs/AccountProof.cs @@ -26,7 +26,7 @@ public class AccountProof public Hash256 CodeHash { get; set; } = Keccak.OfAnEmptyString; - public UInt256 Nonce { get; set; } + public ulong Nonce { get; set; } public Hash256 StorageRoot { get; set; } = Keccak.EmptyTreeHash; @@ -103,7 +103,8 @@ public override void Write( hashConverter.Write(writer, value.CodeHash, options); writer.WritePropertyName("nonce"u8); - uint256Converter.Write(writer, value.Nonce, options); + JsonConverter ulongConverter = (JsonConverter)options.GetConverter(typeof(ulong)); + ulongConverter.Write(writer, value.Nonce, options); writer.WritePropertyName("storageHash"u8); hashConverter.Write(writer, value.StorageRoot, options); diff --git a/src/Nethermind/Nethermind.State/WorldState.cs b/src/Nethermind/Nethermind.State/WorldState.cs index 1e7470622cc3..ee3e135a56da 100644 --- a/src/Nethermind/Nethermind.State/WorldState.cs +++ b/src/Nethermind/Nethermind.State/WorldState.cs @@ -317,7 +317,7 @@ public bool IsNonZeroAccount(Address address, out bool accountExists) DebugGuardInScope(); Account? account = _stateProvider.GetThroughCache(address); accountExists = account is not null; - return accountExists && (account!.IsContract || !(account.Nonce == 0) || !_persistentStorageProvider.IsStorageEmpty(address)); + return accountExists && (account!.IsContract || account.Nonce != 0 || !_persistentStorageProvider.IsStorageEmpty(address)); } public bool IsDeadAccount(Address address) From b44b5dd0fcabcce99eb7596c55cc63b2fd1175a4 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jun 2026 23:46:14 +0200 Subject: [PATCH 55/60] review(taiko/trie/state): ulong cascade for precompile contract; SaturatingSub; test overloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Taiko precompile chain (PrecompileExtras.RemainingGas, IContextAwarePrecompile.Run gasConsumed, IL1CallProvider.ExecuteTraceCall + L1CallResult.GasUsed, L1StaticCallPrecompile.GasCap, MockL1CallProvider) all cascade long → ulong; TaikoVirtualMachine drops the (long)/(ulong) casts at the call site. ZkGasTxTracer and SurgeGasPriceOracleTests: replace the explicit `a > b ? a - b : 0` pattern with the existing SaturatingSub extension. StateCompositionSnapshotDecoder.EncodeULong: call the native ulong RlpStream encoder instead of casting to long (which would mis-encode values >= 2^63). Decoder already uses DecodeULong so the wire format matches. TrieDiffWalkerTests.CreateEOA: keep `int` parameter and cast internally to UInt256 so call sites don't need (ulong)rng.Next(). Trie test overloads: BeginStateBlockCommit(int) + BeginBlockCommit(int) extensions and PruningScenariosTests.WithMaxDepth(ulong) — drops (ulong) casts at test call sites. TestPruningStrategy.pruneInterval int? → ulong?. TreeStoreTests startBlock ulong; reorgBoundaryCount ulong. WorldStateManagerTests / BlockchainTestStreamingTracerTests already migrated in the previous batch. StateTestRunner: drop redundant (ulong) cast on IntrinsicGasCalculator.Standard (already ulong). --- .../Diff/TrieDiffWalkerTests.cs | 10 +++---- .../StateCompositionSnapshotDecoder.cs | 6 +++- .../L1SloadPrecompileTests.cs | 4 +-- .../L1StaticCallPrecompileTests.cs | 30 +++++++++---------- .../SurgeGasPriceOracleTests.cs | 3 +- .../Precompiles/IContextAwarePrecompile.cs | 2 +- .../Precompiles/IL1CallProvider.cs | 6 ++-- .../Precompiles/JsonRpcL1CallProvider.cs | 4 +-- .../Precompiles/L1SloadPrecompile.cs | 14 ++++----- .../Precompiles/L1StaticCallPrecompile.cs | 20 ++++++------- .../Precompiles/PrecompileExtras.cs | 4 +-- .../Nethermind.Taiko/TaikoVirtualMachine.cs | 8 ++--- .../Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs | 5 ++-- .../Nethermind.Test.Runner/StateTestRunner.cs | 2 +- .../IFullTrieStoreExtensions.cs | 6 ++++ .../Pruning/TestPruningStrategy.cs | 4 +-- .../Pruning/TreeStoreTests.cs | 23 +++++++------- .../PruningScenariosTests.cs | 4 ++- 18 files changed, 84 insertions(+), 71 deletions(-) diff --git a/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs b/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs index b32ebbbd38b1..f18f5bad8c2f 100644 --- a/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs +++ b/src/Nethermind/Nethermind.StateComposition.Test/Diff/TrieDiffWalkerTests.cs @@ -24,7 +24,7 @@ namespace Nethermind.StateComposition.Test.Diff; [TestFixture] public class TrieDiffWalkerTests { - private static Account CreateEOA(ulong balance = 100UL) => new(0UL, balance); + private static Account CreateEOA(int balance = 100) => new(0UL, (UInt256)balance); private static Account CreateContract(Hash256 storageRoot, byte[]? code = null) { @@ -338,7 +338,7 @@ public void LargeTrie_IncrementalMatchesFullScan() addressBytes[0] = (byte)(i >> 8); addressBytes[1] = (byte)(i & 0xFF); Address addr = new(addressBytes); - tree.Set(addr, CreateEOA(i + 1)); + tree.Set(addr, CreateEOA((int)(i + 1))); } tree.Commit(); tree.UpdateRootHash(); @@ -354,7 +354,7 @@ public void LargeTrie_IncrementalMatchesFullScan() addressBytes[0] = (byte)(i >> 8); addressBytes[1] = (byte)(i & 0xFF); Address addr = new(addressBytes); - tree.Set(addr, CreateEOA(i + 1)); + tree.Set(addr, CreateEOA((int)(i + 1))); } tree.Commit(); tree.UpdateRootHash(); @@ -436,7 +436,7 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() for (int i = 0; i < newEOAsPerBlock; i++) { Address addr = AddressFromSeed(addressSeed++); - tree.Set(addr, CreateEOA((ulong)rng.Next(1, 10000))); + tree.Set(addr, CreateEOA(rng.Next(1, 10000))); eoaAddresses.Add(addr); } @@ -462,7 +462,7 @@ public void MultiBlock_ScanDiffScan_CumulativeMatchesFreshScan() for (int i = 0; i < modifiedEOAsPerBlock && pool > 0; i++) { int idx = rng.Next(0, pool); - tree.Set(eoaAddresses[idx], CreateEOA((ulong)rng.Next(1, 10000))); + tree.Set(eoaAddresses[idx], CreateEOA(rng.Next(1, 10000))); } } diff --git a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs index 00c10ae06550..ef27c2ff21d5 100644 --- a/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs +++ b/src/Nethermind/Nethermind.StateComposition/Snapshots/StateCompositionSnapshotDecoder.cs @@ -127,7 +127,11 @@ private static int EncodeLong(RlpStream? stream, long value) return Rlp.LengthOf(value); } - private static int EncodeULong(RlpStream? stream, ulong value) => EncodeLong(stream, (long)value); + private static int EncodeULong(RlpStream? stream, ulong value) + { + stream?.Encode(value); + return Rlp.LengthOf(value); + } private static int EncodeInt(RlpStream? stream, int value) { diff --git a/src/Nethermind/Nethermind.Taiko.Test/L1SloadPrecompileTests.cs b/src/Nethermind/Nethermind.Taiko.Test/L1SloadPrecompileTests.cs index 3a8633fb5ec4..48feb886fdb0 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/L1SloadPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/L1SloadPrecompileTests.cs @@ -139,7 +139,7 @@ public void Run_BlockRangeValidation(ulong l1Origin, ulong blockNumber, bool exp byte[] input = CreateValidInput(Address.FromNumber(1), storageKey: (UInt256)1, blockNumber: (UInt256)blockNumber); PrecompileExtras extras = new(l1Origin: (UInt256)l1Origin); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.EqualTo(expectedSuccess)); } @@ -150,7 +150,7 @@ public void Run_NullOrigin_AcceptsAnyBlock() L1SloadPrecompile.L1StorageProvider = MockL1StorageProvider.Returning((UInt256)42); byte[] input = CreateValidInput(Address.FromNumber(1), storageKey: (UInt256)1, blockNumber: (UInt256)12_345); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in PrecompileExtras.None); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in PrecompileExtras.None); Assert.That(result.IsSuccess, Is.True, "Permissive when no origin is available (eth_call / debug_traceCall / preconf)"); } diff --git a/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs b/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs index a61b5adfaeff..a86f95377322 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/L1StaticCallPrecompileTests.cs @@ -16,7 +16,7 @@ namespace Nethermind.Taiko.Test; public class L1StaticCallPrecompileTests { private const long MockGasUsed = 5000L; - private const long TestRemainingGas = 1_000_000L; + private const ulong TestRemainingGas = 1_000_000UL; private L1StaticCallPrecompile _precompile = null!; private IReleaseSpec _spec = null!; @@ -113,7 +113,7 @@ public void Run_With_Short_Input_Should_Fail() byte[] input = new byte[Address.Size]; // 20 bytes, below 52 PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.False); } @@ -128,7 +128,7 @@ public void Run_With_Valid_Input_Should_Succeed() byte[] input = CreateValidInput(Address.FromNumber(42), (UInt256)1000, calldata); PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.True); Assert.That(result.Data.returnValue, Is.EqualTo(expectedReturn)); @@ -142,7 +142,7 @@ public void Run_With_No_Provider_Should_Fail_With_Zero_Gas() byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)1); PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.False); Assert.That(result.Data.gasConsumed, Is.EqualTo(0)); @@ -151,12 +151,12 @@ public void Run_With_No_Provider_Should_Fail_With_Zero_Gas() [Test] public void Run_With_Provider_Failing_Should_Report_GasConsumed() { - long l1GasUsed = 12_000L; + ulong l1GasUsed = 12_000UL; L1StaticCallPrecompile.L1CallProvider = MockL1CallProvider.FailingWithGas(l1GasUsed); byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)1); PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.False); Assert.That(result.Data.gasConsumed, Is.EqualTo(l1GasUsed)); @@ -186,7 +186,7 @@ public void Run_With_Variable_Length_Return_Data(int returnSize, bool expectedSu byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)1); PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.EqualTo(expectedSuccess)); Assert.That(result.Data.gasConsumed, Is.EqualTo(MockGasUsed)); @@ -198,7 +198,7 @@ public void Run_With_Variable_Length_Return_Data(int returnSize, bool expectedSu public void DataGasCost_Then_Run_EndToEnd() { byte[] expectedReturn = [0xCA, 0xFE]; - long mockGas = 8000L; + ulong mockGas = 8000UL; L1StaticCallPrecompile.L1CallProvider = MockL1CallProvider.Returning(expectedReturn, mockGas); byte[] calldata = [0x5C, 0x97, 0x5A, 0xBB]; // paused() selector @@ -212,7 +212,7 @@ public void DataGasCost_Then_Run_EndToEnd() // Run returns result + actual L1 gas consumed PrecompileExtras extras = new(remainingGas: TestRemainingGas); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.True); Assert.That(result.Data.returnValue, Is.EqualTo(expectedReturn)); Assert.That(result.Data.gasConsumed, Is.EqualTo(mockGas)); @@ -265,7 +265,7 @@ public void Run_BlockRangeValidation(ulong l1Origin, ulong blockNumber, bool exp byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)blockNumber); PrecompileExtras extras = new(remainingGas: TestRemainingGas, l1Origin: (UInt256)l1Origin); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.EqualTo(expectedSuccess)); } @@ -277,7 +277,7 @@ public void Run_NullOrigin_AcceptsAnyBlock() byte[] input = CreateValidInput(Address.FromNumber(1), (UInt256)12_345); PrecompileExtras extras = new(remainingGas: TestRemainingGas, l1Origin: null); - Result<(byte[] returnValue, long gasConsumed)> result = _precompile.Run(input, _spec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = _precompile.Run(input, _spec, in extras); Assert.That(result.IsSuccess, Is.True, "Permissive when no origin is available (eth_call / debug_traceCall / preconf)"); } @@ -300,24 +300,24 @@ private sealed class MockL1CallProvider : IL1CallProvider private readonly L1CallResult _result; public int CallCount { get; private set; } - public long LastGasLimit { get; private set; } + public ulong LastGasLimit { get; private set; } private MockL1CallProvider(L1CallResult result) => _result = result; - public L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, long gasLimit) + public L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, ulong gasLimit) { CallCount++; LastGasLimit = gasLimit; return _result; } - public static MockL1CallProvider Returning(byte[] data, long gasUsed = 0) => + public static MockL1CallProvider Returning(byte[] data, ulong gasUsed = 0) => new(new L1CallResult(data, gasUsed, false)); public static MockL1CallProvider Failing() => new(L1CallResult.Failure()); - public static MockL1CallProvider FailingWithGas(long gasUsed) => + public static MockL1CallProvider FailingWithGas(ulong gasUsed) => new(new L1CallResult(null, gasUsed, true)); } } diff --git a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs index 9d716f97027a..1a697fa49d9a 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/SurgeGasPriceOracleTests.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.Find; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Int256; @@ -86,7 +87,7 @@ private void SetupBlockFinderWithBlocks(ulong headBlockNumber, ulong gasUsed = 1 _blockFinder.Head.Returns(headBlock); ulong windowSize = _surgeConfig.L2GasUsageWindowSize; - ulong lowestBlock = headBlockNumber + 1 > windowSize ? headBlockNumber - windowSize + 1 : 0UL; + ulong lowestBlock = (headBlockNumber + 1).SaturatingSub(windowSize); for (ulong i = lowestBlock; i <= headBlockNumber; i++) { _blockFinder.FindBlock(i, BlockTreeLookupOptions.RequireCanonical) diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/IContextAwarePrecompile.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/IContextAwarePrecompile.cs index aa61fbe4e51b..57a50677d8bb 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/IContextAwarePrecompile.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/IContextAwarePrecompile.cs @@ -22,6 +22,6 @@ namespace Nethermind.Taiko.Precompiles; /// public interface IContextAwarePrecompile : IPrecompile { - Result<(byte[] returnValue, long gasConsumed)> Run( + Result<(byte[] returnValue, ulong gasConsumed)> Run( ReadOnlyMemory inputData, IReleaseSpec releaseSpec, in PrecompileExtras extras); } diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/IL1CallProvider.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/IL1CallProvider.cs index 2c3315948126..f1ef88fe15d5 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/IL1CallProvider.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/IL1CallProvider.cs @@ -9,9 +9,9 @@ namespace Nethermind.Taiko.Precompiles; /// /// Result of an L1 call via debug_traceCall, carrying return data and actual gas consumed. /// -public readonly record struct L1CallResult(byte[]? ReturnData, long GasUsed, bool Failed) +public readonly record struct L1CallResult(byte[]? ReturnData, ulong GasUsed, bool Failed) { - public static L1CallResult Failure() => new(null, 0L, true); + public static L1CallResult Failure() => new(null, 0UL, true); } /// @@ -19,5 +19,5 @@ public readonly record struct L1CallResult(byte[]? ReturnData, long GasUsed, boo /// public interface IL1CallProvider { - L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, long gasLimit); + L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, ulong gasLimit); } diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/JsonRpcL1CallProvider.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/JsonRpcL1CallProvider.cs index e8dc9a8de058..ce744b845658 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/JsonRpcL1CallProvider.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/JsonRpcL1CallProvider.cs @@ -17,7 +17,7 @@ public class JsonRpcL1CallProvider(IJsonRpcClient rpcClient, ILogManager logMana { private readonly ILogger _logger = logManager.GetClassLogger(); - public L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, long gasLimit) + public L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumber, byte[] calldata, ulong gasLimit) { try { @@ -43,7 +43,7 @@ public L1CallResult ExecuteTraceCall(Address contractAddress, UInt256 blockNumbe } // Clamp to gasLimit — the L1 node must not cause us to charge more than we budgeted. - long gasUsed = Math.Min(response.Gas, gasLimit); + ulong gasUsed = Math.Min((ulong)response.Gas, gasLimit); if (response.Failed) { diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs index 802ed60a3579..19f13247fbf9 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/L1SloadPrecompile.cs @@ -51,13 +51,13 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe /// public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { - Result<(byte[] returnValue, long gasConsumed)> result = Run(inputData, releaseSpec, in PrecompileExtras.None); + Result<(byte[] returnValue, ulong gasConsumed)> result = Run(inputData, releaseSpec, in PrecompileExtras.None); // Implicit string→Result conversion fills Data with Array.Empty() on failure, // which the IPrecompile contract expects (callers deconstruct result and assert .IsEmpty). return result ? Result.Success(result.Data.returnValue) : result.Error!; } - public Result<(byte[] returnValue, long gasConsumed)> Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec, in PrecompileExtras extras) + public Result<(byte[] returnValue, ulong gasConsumed)> Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec, in PrecompileExtras extras) { L1PrecompileMetrics.L1SloadPrecompile++; if (Logger.IsDebug) Logger.Debug($"L1SLOAD: precompile called, input_len={inputData.Length}"); @@ -65,13 +65,13 @@ public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSp if (inputData.Length != L1PrecompileConstants.L1SloadExpectedInputLength) { if (Logger.IsWarn) Logger.Warn($"L1SLOAD: rejected invalid input length {inputData.Length}, expected {L1PrecompileConstants.L1SloadExpectedInputLength}"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(Errors.InvalidInputLength); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(Errors.InvalidInputLength); } if (L1StorageProvider is null) { if (Logger.IsWarn) Logger.Warn("L1SLOAD: no L1StorageProvider configured"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(L1StorageAccessFailed); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(L1StorageAccessFailed); } Address contractAddress = new(inputData.Span[..Address.Size]); @@ -83,7 +83,7 @@ public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSp if (extras.L1Origin is { } origin && !L1PrecompileConstants.IsBlockInRange(blockNumber, origin)) { if (Logger.IsWarn) Logger.Warn($"L1SLOAD: block {blockNumber} outside [{origin}-{L1PrecompileConstants.MaxBlockLookback}, {origin}]"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(BlockOutOfRange); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(BlockOutOfRange); } if (Logger.IsDebug) Logger.Debug($"L1SLOAD: request contract={contractAddress}, key={storageKey}, block={blockNumber}"); @@ -92,7 +92,7 @@ public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSp if (storageValue is null) { if (Logger.IsWarn) Logger.Warn($"L1SLOAD: storage access returned null for contract={contractAddress}, key={storageKey}, block={blockNumber}"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(L1StorageAccessFailed); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(L1StorageAccessFailed); } if (Logger.IsDebug) Logger.Debug($"L1SLOAD: success contract={contractAddress}, key={storageKey}, block={blockNumber}, value={storageValue.Value}"); @@ -100,7 +100,7 @@ public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSp byte[] output = new byte[32]; storageValue.Value.ToBigEndian().CopyTo(output.AsSpan()); - return (output, 0L); + return (output, 0UL); } private UInt256? GetL1StorageValue(Address contractAddress, UInt256 blockNumber, UInt256 storageKey) diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs index 1445374bec4a..601af8f0c229 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/L1StaticCallPrecompile.cs @@ -47,7 +47,7 @@ private L1StaticCallPrecompile() public bool SupportsCaching => false; public static IL1CallProvider? L1CallProvider { get; set; } public static ILogger Logger { get; set; } - public static long GasCap => L1PrecompileConstants.L1CallMaxGasCap; + public static ulong GasCap => (ulong)L1PrecompileConstants.L1CallMaxGasCap; public ulong BaseGasCost(IReleaseSpec releaseSpec) => L1PrecompileConstants.L1StaticCallFixedGasCost; @@ -70,7 +70,7 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe /// supplying remaining gas (used to clamp the L1 call gas limit) and the cached L1 origin /// (used for the 256-block lookback range check). /// - public Result<(byte[] returnValue, long gasConsumed)> Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec, in PrecompileExtras extras) + public Result<(byte[] returnValue, ulong gasConsumed)> Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec, in PrecompileExtras extras) { L1PrecompileMetrics.L1StaticCallPrecompile++; if (Logger.IsDebug) Logger.Debug($"L1STATICCALL: precompile called, input_len={inputData.Length}, remainingGas={extras.RemainingGas}"); @@ -78,13 +78,13 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe if (inputData.Length < L1PrecompileConstants.L1StaticCallMinInputLength) { if (Logger.IsWarn) Logger.Warn($"L1STATICCALL: rejected invalid input length {inputData.Length}, minimum {L1PrecompileConstants.L1StaticCallMinInputLength}"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(Errors.InvalidInputLength); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(Errors.InvalidInputLength); } if (L1CallProvider is null) { if (Logger.IsWarn) Logger.Warn("L1STATICCALL: no L1CallProvider configured"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(L1StaticCallFailed); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(L1StaticCallFailed); } Address contractAddress = new(inputData.Span[..Address.Size]); @@ -96,10 +96,10 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe if (extras.L1Origin is { } origin && !L1PrecompileConstants.IsBlockInRange(blockNumber, origin)) { if (Logger.IsWarn) Logger.Warn($"L1STATICCALL: block {blockNumber} outside [{origin}-{L1PrecompileConstants.MaxBlockLookback}, {origin}]"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(BlockOutOfRange); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(BlockOutOfRange); } - long gasLimit = Math.Min(Math.Max(0, extras.RemainingGas), GasCap); + ulong gasLimit = Math.Min(extras.RemainingGas, GasCap); if (Logger.IsDebug) Logger.Debug($"L1STATICCALL: request contract={contractAddress}, block={blockNumber}, calldata_len={calldata.Length}, gasLimit={gasLimit}"); L1CallResult result; @@ -110,7 +110,7 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe catch (Exception ex) { if (Logger.IsError) Logger.Error($"L1STATICCALL: exception in ExecuteTraceCall: {ex.Message}", ex); - return Result<(byte[] returnValue, long gasConsumed)>.Fail(L1StaticCallFailed); + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail(L1StaticCallFailed); } if (result.Failed || result.ReturnData is null) @@ -118,14 +118,14 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe if (Logger.IsWarn) Logger.Warn("L1STATICCALL: L1 call failed"); // Report gasUsed even on failure — the L1 node did the work and the user must pay. // On L1 OOG, gasUsed equals the full gas limit. - return Result<(byte[] returnValue, long gasConsumed)>.Fail( + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail( L1StaticCallFailed, (Array.Empty(), result.GasUsed)); } if (result.ReturnData.Length > L1PrecompileConstants.L1StaticCallMaxReturnDataSize) { if (Logger.IsWarn) Logger.Warn($"L1STATICCALL: return data too large ({result.ReturnData.Length} bytes, max {L1PrecompileConstants.L1StaticCallMaxReturnDataSize})"); - return Result<(byte[] returnValue, long gasConsumed)>.Fail( + return Result<(byte[] returnValue, ulong gasConsumed)>.Fail( L1StaticCallFailed, (Array.Empty(), result.GasUsed)); } @@ -142,7 +142,7 @@ public ulong DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpe public Result Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) { PrecompileExtras extras = new(remainingGas: GasCap); - Result<(byte[] returnValue, long gasConsumed)> result = Run(inputData, releaseSpec, in extras); + Result<(byte[] returnValue, ulong gasConsumed)> result = Run(inputData, releaseSpec, in extras); // Implicit string→Result conversion fills Data with Array.Empty() on failure, // which the IPrecompile contract expects (callers deconstruct result and assert .IsEmpty). return result ? Result.Success(result.Data.returnValue) : result.Error!; diff --git a/src/Nethermind/Nethermind.Taiko/Precompiles/PrecompileExtras.cs b/src/Nethermind/Nethermind.Taiko/Precompiles/PrecompileExtras.cs index e9e70fef599a..fab8af5148cc 100644 --- a/src/Nethermind/Nethermind.Taiko/Precompiles/PrecompileExtras.cs +++ b/src/Nethermind/Nethermind.Taiko/Precompiles/PrecompileExtras.cs @@ -19,10 +19,10 @@ namespace Nethermind.Taiko.Precompiles; /// before the chain has any origins). Precompiles must treat null as permissive — the /// proving layer enforces correctness in those contexts. /// -public readonly struct PrecompileExtras(long remainingGas = 0, UInt256? l1Origin = null) +public readonly struct PrecompileExtras(ulong remainingGas = 0, UInt256? l1Origin = null) { public static readonly PrecompileExtras None = default; - public readonly long RemainingGas = remainingGas; + public readonly ulong RemainingGas = remainingGas; public readonly UInt256? L1Origin = l1Origin; } diff --git a/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs b/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs index d9b45378cf19..ddcef5935ef5 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoVirtualMachine.cs @@ -54,10 +54,10 @@ protected override CallResult ExecutePrecompileCall( { TGasPolicy gas = state.Gas; PrecompileExtras extras = new( - remainingGas: (long)TGasPolicy.GetRemainingGas(in gas), + remainingGas: TGasPolicy.GetRemainingGas(in gas), l1Origin: _blockL1Origin); - Result<(byte[] returnValue, long gasConsumed)> output; + Result<(byte[] returnValue, ulong gasConsumed)> output; try { output = contextAwarePrecompile.Run(callData, spec, in extras); @@ -76,8 +76,8 @@ protected override CallResult ExecutePrecompileCall( // Deduct dynamic gas (e.g. actual L1 consumption) regardless of success/failure. // On L1 OOG the user loses the full gas limit — matching standard EVM sub-call semantics. - long gasConsumed = output.Data.gasConsumed; - if (gasConsumed > 0 && !TGasPolicy.UpdateGas(ref gas, (ulong)gasConsumed)) + ulong gasConsumed = output.Data.gasConsumed; + if (gasConsumed > 0 && !TGasPolicy.UpdateGas(ref gas, gasConsumed)) { return new(default, precompileSuccess: false, shouldRevert: true, EvmExceptionType.OutOfGas); } diff --git a/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs b/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs index 16b366b088bd..b539c03a0d8b 100644 --- a/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs +++ b/src/Nethermind/Nethermind.Taiko/ZkGas/ZkGasTxTracer.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Int256; @@ -79,7 +80,7 @@ public override void ReportOperationRemainingGas(ulong gas) _stepActive = false; - ulong rawGas = _currentGasStart > gas ? _currentGasStart - gas : 0UL; + ulong rawGas = _currentGasStart.SaturatingSub(gas); if (IsSpawnOpcode(_currentOpcode)) { @@ -258,7 +259,7 @@ private void ChargePrecompileIfPending(ulong gasRemaining) return; _pendingPrecompile = false; - ulong gasUsed = _precompileGasStart > gasRemaining ? _precompileGasStart - gasRemaining : 0UL; + ulong gasUsed = _precompileGasStart.SaturatingSub(gasRemaining); if (gasUsed > 0 && _precompileAddress is not null) { _meter.ChargePrecompile(_precompileAddress, gasUsed); diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs index 1341b1004640..85970dd7d2fb 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestRunner.cs @@ -97,7 +97,7 @@ public IEnumerable RunTests() txTrace.State.StateRoot = result.StateRoot; try { - txTrace.Result.GasUsed -= (ulong)IntrinsicGasCalculator.Calculate(test.Transaction, test.Fork).Standard; + txTrace.Result.GasUsed -= IntrinsicGasCalculator.Calculate(test.Transaction, test.Fork).Standard; } catch (InvalidDataException e) { diff --git a/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs b/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs index 82338c01b38a..a12bf616e9ec 100644 --- a/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs +++ b/src/Nethermind/Nethermind.Trie.Test/IFullTrieStoreExtensions.cs @@ -16,6 +16,12 @@ public static ICommitter BeginStateBlockCommit(this ITrieStore trieStore, ulong return new CommitterWithBlockCommitter(blockCommitter, stateTreeCommitter); } + public static ICommitter BeginStateBlockCommit(this ITrieStore trieStore, int blockNumber, TrieNode? root, WriteFlags writeFlags = WriteFlags.None) + => BeginStateBlockCommit(trieStore, (ulong)blockNumber, root, writeFlags); + + public static IBlockCommitter BeginBlockCommit(this ITrieStore trieStore, int blockNumber) + => trieStore.BeginBlockCommit((ulong)blockNumber); + public static void CommitPatriciaTrie(this ITrieStore trieStore, ulong blockNumber, PatriciaTree patriciaTree) { using (trieStore.BeginBlockCommit(blockNumber)) { patriciaTree.Commit(); } diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs index 70284c77d6d2..4a2a7ec0f6b1 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TestPruningStrategy.cs @@ -8,13 +8,13 @@ namespace Nethermind.Trie.Test.Pruning public class TestPruningStrategy( bool shouldPrune = false, bool deleteObsoleteKeys = false, - int? pruneInterval = null) + ulong? pruneInterval = null) : IPruningStrategy { public bool DeleteObsoleteKeys => deleteObsoleteKeys; public bool ShouldPruneDirtyNode(TrieStoreState state) { - if (pruneInterval is not null && state.LatestCommittedBlock % (ulong)pruneInterval.Value == 0) + if (pruneInterval is not null && state.LatestCommittedBlock % pruneInterval.Value == 0) { return true; } diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs index 473e7c3879c9..4cda97dc3225 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs @@ -108,7 +108,7 @@ public async Task Flush_ShouldBeCalledOnEachPersist() using (IDisposable _ = fullTrieStore.BeginScope(baseBlock)) { pt.Set(TestItem.KeccakA.BytesToArray(), TestItem.Keccaks[i].BytesToArray()); - using (fullTrieStore.BeginStateBlockCommit((ulong)(i + 1), trieNode)) + using (fullTrieStore.BeginStateBlockCommit(i + 1, trieNode)) { pt.Commit(); } @@ -149,14 +149,14 @@ public void Should_always_announce_zero_when_not_persisting() { TrieNode trieNode = new(NodeType.Leaf, Keccak.Zero); - long reorgBoundaryCount = 0L; + ulong reorgBoundaryCount = 0UL; using TrieStore fullTrieStore = CreateTrieStore(); - fullTrieStore.ReorgBoundaryReached += (_, e) => reorgBoundaryCount += (long)e.BlockNumber; + fullTrieStore.ReorgBoundaryReached += (_, e) => reorgBoundaryCount += e.BlockNumber; fullTrieStore.BeginStateBlockCommit(1, trieNode).Dispose(); fullTrieStore.BeginStateBlockCommit(2, trieNode).Dispose(); fullTrieStore.BeginStateBlockCommit(3, trieNode).Dispose(); fullTrieStore.BeginStateBlockCommit(4, trieNode).Dispose(); - Assert.That(reorgBoundaryCount, Is.EqualTo(0L)); + Assert.That(reorgBoundaryCount, Is.EqualTo(0UL)); } [Test] @@ -970,22 +970,21 @@ public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] StateTree stateTree = new(trieStore, LimboLogs.Instance); // Start from block 1 (not genesis) to avoid special-casing block 0 - int startBlock = 1; - int blockCount = (int)(pruningBoundary * 4); + ulong startBlock = 1; + ulong blockCount = pruningBoundary * 4; Hash256[] rootHashes = new Hash256[startBlock + blockCount]; - for (int i = startBlock; i < startBlock + blockCount; i++) + for (ulong i = startBlock; i < startBlock + blockCount; i++) { - ulong blockNumber = (ulong)i; - using (trieStore.BeginBlockCommit(blockNumber)) + using (trieStore.BeginBlockCommit(i)) { - stateTree.Set(TestItem.AddressA, new Account(blockNumber + 1)); + stateTree.Set(TestItem.AddressA, new Account(i + 1)); stateTree.Commit(); } rootHashes[i] = stateTree.RootHash; } trieStore.WaitForPruning(); - Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(pruningBoundary + (ulong)startBlock)); + Assert.That(trieStore.LastPersistedBlockNumber, Is.GreaterThan(pruningBoundary + startBlock)); ulong lastPersisted = trieStore.LastPersistedBlockNumber; @@ -993,7 +992,7 @@ public void HasRoot_with_block_number_allows_old_blocks_in_archive_mode([Values] Assert.That(trieStore.HasRoot(rootHashes[(int)lastPersisted], lastPersisted), Is.True); // Block 1 is well outside the pruning boundary but should still be accessible in archive mode - Assert.That(trieStore.HasRoot(rootHashes[startBlock], (ulong)startBlock), Is.True); + Assert.That(trieStore.HasRoot(rootHashes[startBlock], startBlock), Is.True); trieStore.Dispose(); } diff --git a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs index 0dc448e147bc..0ca479d60a96 100644 --- a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs @@ -315,7 +315,9 @@ public PruningContext SetManyAccountWithSameBalance(int startNum, int numOfAccou return this; } - public PruningContext WithMaxDepth(int maxDepth) => WithPruningConfig((cfg) => cfg.PruningBoundary = (ulong)maxDepth); + public PruningContext WithMaxDepth(int maxDepth) => WithMaxDepth((ulong)maxDepth); + + public PruningContext WithMaxDepth(ulong maxDepth) => WithPruningConfig((cfg) => cfg.PruningBoundary = maxDepth); public PruningContext WithPruningConfig(Action configurer) { From 210453141b6973920c78360eea110b9a84115311 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Sat, 20 Jun 2026 00:06:47 +0200 Subject: [PATCH 56/60] review(sync): SaturatingSub, ulong skipLastN/maxHeaders/fastSyncLag, strip noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PowForwardHeaderProvider: SaturatingSub for chunk arithmetic (headNum - 1, HeadNumber - skipLastN, currentNumber - ancestorJump, bestSuggestedNumber - MaxReorganizationLength, currentNumber - 1028). maxHeaders/skipLastN/ headersToRequest now ulong (cascades through IForwardHeaderProvider, IForwardSyncController, BlockDownloader.PrepareRequest, FastSyncFeed). PosForwardHeaderProvider: ulong signature at the entry then narrows once to int internally so the array/buffer arithmetic stays int-typed. SyncServer: SaturatingSub on the MaxReorgLength gate and the seal-validation hint window; drop the dead `number >= 0` guard (number is ulong); drop the "in the range of [Head - MaxReorganizationLength, Head]" stale comment. PeerInfo.ShouldNotifyNewRange: takes ulong instead of long; the two private last-notified fields cascade. SyncServer call site drops the (long) casts. ParallelSync: SyncProgressResolver FindBestProcessedBlock collapses `is { } n ? n : ulong.MaxValue` into `?? ulong.MaxValue`; SyncPivot getter collapses the trivial deconstruction. MultiSyncModeSelector: drop the long "Safe: …" comment that re-stated the ulong wrap behaviour. FullStateFinder: strip the "Block numbers are ulong…" and "startHeader.Number is ulong" comments; flatten the nested-if guard against underflow. SyncReport: SaturatingSub on the numHeadersToDownload subtraction. BetterPeerStrategyExtensions, ITotalDifficultyStrategy, TreeSync, SyncPeerPool: drop the leftover "cast is safe / Number is ulong" comments. Tests: BlockDownloaderTests / ForwardHeaderProviderTests / PosForwardHeaderProviderCacheTests / BlockDownloaderTests.BlockAccessLists follow the new ulong signatures. --- .../PosForwardHeaderProviderCacheTests.cs | 2 +- .../PosForwardHeaderProvider.cs | 7 ++++-- .../BlockDownloaderTests.BlockAccessLists.cs | 2 +- .../BlockDownloaderTests.cs | 8 +++---- .../ForwardHeaderProviderTests.Merge.cs | 2 +- .../ForwardHeaderProviderTests.cs | 2 +- .../BetterPeerStrategyExtensions.cs | 1 - .../Blocks/BlockDownloader.cs | 6 ++--- .../Blocks/FastSyncFeed.cs | 2 +- .../Blocks/IForwardHeaderProvider.cs | 2 +- .../Blocks/IForwardSyncController.cs | 2 +- .../Blocks/PowForwardHeaderProvider.cs | 22 +++++++++---------- .../FastSync/TreeSync.cs | 1 - .../ITotalDifficultyStrategy.cs | 1 - .../ParallelSync/FullStateFinder.cs | 15 +++---------- .../ParallelSync/MultiSyncModeSelector.cs | 4 ---- .../ParallelSync/SyncProgressResolver.cs | 11 ++-------- .../Peers/PeerInfo.cs | 6 ++--- .../Peers/SyncPeerPool.cs | 1 - .../Reporting/SyncReport.cs | 3 ++- .../Nethermind.Synchronization/SyncServer.cs | 11 ++++------ 21 files changed, 44 insertions(+), 67 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/PosForwardHeaderProviderCacheTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/PosForwardHeaderProviderCacheTests.cs index 963c618d63db..764c3d3c0106 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/PosForwardHeaderProviderCacheTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/Synchronization/PosForwardHeaderProviderCacheTests.cs @@ -66,7 +66,7 @@ public void SetUp() public void TearDown() => _provider.UnsubscribeForTest(); private Task?> Get(int skip = 0, int max = Requested) => - _provider.GetBlockHeaders(skip, max, CancellationToken.None); + _provider.GetBlockHeaders((ulong)skip, (ulong)max, CancellationToken.None); private void RaiseMainChainUpdate(params Block[] blocks) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PosForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PosForwardHeaderProvider.cs index 21c16fca75f8..3c66d56fb079 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PosForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PosForwardHeaderProvider.cs @@ -59,13 +59,16 @@ public PosForwardHeaderProvider( private bool ShouldUsePreMerge() => !_beaconPivot.BeaconPivotExists() && !_poSSwitcher.HasEverReachedTerminalBlock(); - public override Task?> GetBlockHeaders(int skipLastN, int maxHeader, CancellationToken cancellation) + public override Task?> GetBlockHeaders(ulong skipLastNUlong, ulong maxHeaderUlong, CancellationToken cancellation) { if (ShouldUsePreMerge()) { - return base.GetBlockHeaders(skipLastN, maxHeader, cancellation); + return base.GetBlockHeaders(skipLastNUlong, maxHeaderUlong, cancellation); } + int skipLastN = (int)skipLastNUlong; + int maxHeader = (int)maxHeaderUlong; + _syncReport.FullSyncBlocksDownloaded.TargetValue = Math.Max(_beaconPivot.PivotNumber, _beaconPivot.PivotDestinationNumber); ArrayPoolList? slice = TryServeFromCache(maxHeader, skipLastN); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.BlockAccessLists.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.BlockAccessLists.cs index 3916e3b2acdd..9267753bdcb0 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.BlockAccessLists.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.BlockAccessLists.cs @@ -179,7 +179,7 @@ private static void ConfigureBlockAccessListRequest(Context ctx, IForwardHeaderP .TestObject; forwardHeaderProvider - .GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) + .GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(_ => { IOwnedReadOnlyList headers = new ArrayPoolList(2) { parent, header }; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index 9afa7f41fe5f..4dcf56626661 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -184,7 +184,7 @@ public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion( PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); - mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any())! + mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any())! .Returns((c) => syncPeer.GetBlockHeaders(0, 200, 0, default)); Func act = async () => await ctx.FastSyncUntilNoRequest(peerInfo); @@ -195,7 +195,7 @@ public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion( public async Task Catch_exception_from_forwardHeaderProvider() { IForwardHeaderProvider mockForwardHeaderProvider = Substitute.For(); - mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) + mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) .Throws(new Exception("test exception")); await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() @@ -221,7 +221,7 @@ public async Task Return_Null_On_InConsistentHeaderSequence() headers.Add(Build.A.EmptyBlockHeader); IForwardHeaderProvider mockForwardHeaderProvider = Substitute.For(); - mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) + mockForwardHeaderProvider.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(Task.FromResult?>(headers)); await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() @@ -261,7 +261,7 @@ public async Task Skit_spawning_request_when_block_processing_queue_is_high() Assert.That(request, Is.Null); await mockForwardHeaderProvider.DidNotReceive() - .GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()); + .GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any()); } [Test] diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs index b12b004d88f8..f7f6222d57e1 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.Merge.cs @@ -119,7 +119,7 @@ public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int bloc IForwardHeaderProvider forwardHeader = ctx.ForwardHeaderProvider; ctx.ConfigureBestPeer(peerInfo); - using IOwnedReadOnlyList? headers = await forwardHeader.GetBlockHeaders(blocksToIgnore, 128, CancellationToken.None); + using IOwnedReadOnlyList? headers = await forwardHeader.GetBlockHeaders((ulong)blocksToIgnore, 128, CancellationToken.None); Assert.That(headers?[^1]?.Number, Is.EqualTo(expectedBestKnownNumber)); } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs index cc93da4d7539..e413b7017b25 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs @@ -68,7 +68,7 @@ public async Task Happy_path(long headNumber, int skipLastN, int maxHeader, long int maxNHeader = Math.Min(maxHeader, peerInfo!.MaxHeadersPerRequest()); - using IOwnedReadOnlyList? headers = await forwardHeader.GetBlockHeaders(skipLastN, maxNHeader, CancellationToken.None); + using IOwnedReadOnlyList? headers = await forwardHeader.GetBlockHeaders((ulong)skipLastN, (ulong)maxNHeader, CancellationToken.None); Assert.That(headers?[0]?.Number, Is.EqualTo(expectedStartNumber)); Assert.That(headers?[^1]?.Number, Is.EqualTo(expectedEndNumber)); } diff --git a/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs b/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs index 3c8a230e1031..1b5905ac9ea5 100644 --- a/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs +++ b/src/Nethermind/Nethermind.Synchronization/BetterPeerStrategyExtensions.cs @@ -23,7 +23,6 @@ public static int Compare(this IBetterPeerStrategy peerStrategy, BlockHeader? he public static int Compare(this IBetterPeerStrategy peerStrategy, (UInt256 TotalDifficulty, ulong Number) value, ISyncPeer? peerInfo) { UInt256? peerDifficulty = peerInfo?.TotalDifficulty; - // ISyncPeer.HeadNumber is ulong; cast to long is safe for realistic chain heights. ulong peerInfoHeadNumber = peerInfo?.HeadNumber ?? 0UL; return peerStrategy.Compare(value, (peerDifficulty, peerInfoHeadNumber)); } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs index af1728d3b37a..2e9f3df7a574 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs @@ -117,7 +117,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0UL); } - public async Task PrepareRequest(DownloaderOptions options, int fastSyncLag, CancellationToken cancellation) + public async Task PrepareRequest(DownloaderOptions options, ulong fastSyncLag, CancellationToken cancellation) { await _requestLock.WaitAsync(cancellation); try @@ -135,7 +135,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) } } - private async Task DoPrepareRequest(DownloaderOptions options, int fastSyncLag, CancellationToken cancellation) + private async Task DoPrepareRequest(DownloaderOptions options, ulong fastSyncLag, CancellationToken cancellation) { bool originalDownloadReceiptOpts = (options & DownloaderOptions.WithReceipts) == DownloaderOptions.WithReceipts; bool originalShouldProcess = (options & DownloaderOptions.Process) == DownloaderOptions.Process; @@ -152,7 +152,7 @@ private void BlockTreeOnNewHeadBlock(object? sender, BlockEventArgs e) return null; } - using IOwnedReadOnlyList? headers = await _forwardHeaderProvider.GetBlockHeaders(fastSyncLag, HeaderLookupSize + 1, cancellation); + using IOwnedReadOnlyList? headers = await _forwardHeaderProvider.GetBlockHeaders(fastSyncLag, (ulong)HeaderLookupSize + 1, cancellation); if (cancellation.IsCancellationRequested) return null; // check before every heavy operation bool shouldProcess; bool downloadReceipts; diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs index cf97a3a89b6f..789a38f74c56 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/FastSyncFeed.cs @@ -16,7 +16,7 @@ public class FastSyncFeed(IForwardSyncController forwardSyncController, ISyncCon private DownloaderOptions BuildOptions() => DownloaderOptions.Insert | DownloaderOptions.WithReceipts; - public override Task PrepareRequest(CancellationToken token = default) => forwardSyncController.PrepareRequest(BuildOptions(), (int)syncConfig.StateMinDistanceFromHead, token); + public override Task PrepareRequest(CancellationToken token = default) => forwardSyncController.PrepareRequest(BuildOptions(), syncConfig.StateMinDistanceFromHead, token); public override SyncResponseHandlingResult HandleResponse(BlocksRequest response, PeerInfo peer = null) => forwardSyncController.HandleResponse(response, peer); diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardHeaderProvider.cs index 08e9ffc5ca1e..ab26585af81e 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardHeaderProvider.cs @@ -11,6 +11,6 @@ namespace Nethermind.Synchronization.Blocks; public interface IForwardHeaderProvider { - Task?> GetBlockHeaders(int skipLastN, int maxHeaders, CancellationToken cancellation); + Task?> GetBlockHeaders(ulong skipLastN, ulong maxHeaders, CancellationToken cancellation); void OnSuggestBlock(BlockTreeSuggestOptions blockTreeSuggestOptions, Block currentBlock, AddBlockResult addResult); } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardSyncController.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardSyncController.cs index a29679dfd534..c7d2b8ee3843 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardSyncController.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/IForwardSyncController.cs @@ -13,7 +13,7 @@ namespace Nethermind.Synchronization.Blocks; /// public interface IForwardSyncController { - public Task PrepareRequest(DownloaderOptions buildOptions, int fastSyncLag, CancellationToken token = default); + public Task PrepareRequest(DownloaderOptions buildOptions, ulong fastSyncLag, CancellationToken token = default); public SyncResponseHandlingResult HandleResponse(BlocksRequest response, PeerInfo? peer); public int DownloadRequestBufferSize { get; } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs index 0564a9326793..ee05da6abe74 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/PowForwardHeaderProvider.cs @@ -55,7 +55,7 @@ private IOwnedReadOnlyList? LastResponseBatch } } - public virtual Task?> GetBlockHeaders(int skipLastN, int maxHeaders, CancellationToken cancellation) => syncPeerPool.AllocateAndRun(async (peerInfo) => + public virtual Task?> GetBlockHeaders(ulong skipLastN, ulong maxHeaders, CancellationToken cancellation) => syncPeerPool.AllocateAndRun(async (peerInfo) => { if (peerInfo != _currentBestPeer) { @@ -133,11 +133,11 @@ private void OnNewBestPeer(PeerInfo newBestPeer) _ancestorLookupLevel = 0; ulong bestKnown = blockTree.BestKnownNumber; ulong headNum = newBestPeer.HeadNumber; - _currentNumber = Math.Min(bestKnown, headNum > 0 ? headNum - 1 : 0); + _currentNumber = Math.Min(bestKnown, headNum.SaturatingSub(1)); _currentBestPeer = newBestPeer; } - private async Task?> GetBlockHeaders(PeerInfo bestPeer, int skipLastN, int maxHeaders, CancellationToken cancellation) + private async Task?> GetBlockHeaders(PeerInfo bestPeer, ulong skipLastN, ulong maxHeaders, CancellationToken cancellation) { while (true) { @@ -146,19 +146,19 @@ private void OnNewBestPeer(PeerInfo newBestPeer) if (_logger.IsDebug) _logger.Debug($"Continue full sync with {bestPeer} (our best {blockTree.BestKnownNumber})"); - ulong upperDownloadBoundary = bestPeer.HeadNumber > (ulong)skipLastN ? bestPeer.HeadNumber - (ulong)skipLastN : 0; + ulong upperDownloadBoundary = bestPeer.HeadNumber.SaturatingSub(skipLastN); if (_currentNumber > upperDownloadBoundary) { return null; } ulong blocksLeft = upperDownloadBoundary - _currentNumber; - int headersToRequest = (int)Math.Min(blocksLeft + 1, (ulong)maxHeaders); + ulong headersToRequest = Math.Min(blocksLeft + 1, maxHeaders); if (headersToRequest <= 1) { return null; } - headersToRequest = Math.Min(headersToRequest, bestPeer.MaxHeadersPerRequest()); + headersToRequest = Math.Min(headersToRequest, (ulong)bestPeer.MaxHeadersPerRequest()); if (_logger.IsTrace) _logger.Trace($"Full sync request {_currentNumber}+{headersToRequest} to peer {bestPeer} with {bestPeer.HeadNumber} blocks. Got {_currentNumber} and asking for {headersToRequest} more."); cancellation.ThrowIfCancellationRequested(); @@ -218,9 +218,9 @@ private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, r } int ancestorJump = _ancestorJumps[_ancestorLookupLevel] - _ancestorJumps[_ancestorLookupLevel - 1]; - currentNumber = currentNumber >= (ulong)ancestorJump ? (currentNumber - (ulong)ancestorJump) : 0UL; + currentNumber = currentNumber.SaturatingSub((ulong)ancestorJump); ulong bestSuggestedNumber = blockTree.BestSuggestedHeader?.Number ?? 0UL; - ulong minAllowed = bestSuggestedNumber > MaxReorganizationLength ? bestSuggestedNumber - MaxReorganizationLength : 0; + ulong minAllowed = bestSuggestedNumber.SaturatingSub((ulong)MaxReorganizationLength); currentNumber = Math.Max(minAllowed, currentNumber); return false; } @@ -228,12 +228,12 @@ private bool CheckAncestorJump(PeerInfo bestPeer, BlockHeader blockBeforeZero, r return true; } - private async Task> RequestHeaders(PeerInfo peer, CancellationToken cancellation, ulong currentNumber, int headersToRequest) + private async Task> RequestHeaders(PeerInfo peer, CancellationToken cancellation, ulong currentNumber, ulong headersToRequest) { - ulong start = currentNumber >= 1028 ? currentNumber - 1028 : 0UL; + ulong start = currentNumber.SaturatingSub(1028); sealValidator.HintValidationRange(_sealValidatorUserGuid, start, currentNumber + 30000); - IOwnedReadOnlyList headers = await peer.SyncPeer.GetBlockHeaders(currentNumber, headersToRequest, 0, cancellation); + IOwnedReadOnlyList headers = await peer.SyncPeer.GetBlockHeaders(currentNumber, (int)headersToRequest, 0, cancellation); cancellation.ThrowIfCancellationRequested(); headers = FilterPosHeader(headers); diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs index 4d0934bd02f7..7c9b5f4382e3 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs @@ -401,7 +401,6 @@ public bool IsSyncRoundFinished() } if (_logger.IsInfo) _logger.Info($"Starting the node data sync from the {headerForState.ToString(BlockHeader.Format.Short)} {headerForState.StateRoot} root"); - // headerForState.Number is ulong; ResetStateRoot takes long. Cast is safe for realistic chain heights. ResetStateRoot(headerForState.Number, headerForState.StateRoot!); return headerForState; } diff --git a/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs b/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs index dda799891eab..6236a126851c 100644 --- a/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs +++ b/src/Nethermind/Nethermind.Synchronization/ITotalDifficultyStrategy.cs @@ -27,7 +27,6 @@ public sealed class FixedTotalDifficultyStrategy( UInt256 toTotalDifficulty ) : ITotalDifficultyStrategy { - // header.Number is ulong; fixesBlockNumber is ulong — no cast needed. public UInt256 ParentTotalDifficulty(BlockHeader header) => header.Number > 0 && header.Number - 1 == fixesBlockNumber ? toTotalDifficulty : strategy.ParentTotalDifficulty(header); diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs index b252c4ac7133..ee1c38f93f41 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/FullStateFinder.cs @@ -21,8 +21,6 @@ public class FullStateFinder( private readonly IStateReader _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - // Block numbers are ulong throughout; 0 is the "not yet known" sentinel (genesis is never - // a valid "last known full state" to resume from). private ulong _lastKnownState; private bool IsFullySynced(BlockHeader block) => @@ -69,16 +67,10 @@ private ulong SearchForFullState(BlockHeader startHeader) { ulong bestFullState = 0; ulong maxLookupBack = MaxLookupBack; - if (_lastKnownState != 0) + if (_lastKnownState != 0 && startHeader.Number >= _lastKnownState) { - // Guard against underflow: only extend the window when the header is ahead of - // (or at) the last known state. If startHeader.Number < _lastKnownState the - // chain walked backwards during a reorg; keep the default MaxLookupBack window. - if (startHeader.Number >= _lastKnownState) - { - ulong lookback = startHeader.Number - _lastKnownState + 1; - if (lookback > maxLookupBack) maxLookupBack = lookback; - } + ulong lookback = startHeader.Number - _lastKnownState + 1; + if (lookback > maxLookupBack) maxLookupBack = lookback; } for (ulong i = 0; i < maxLookupBack; i++) @@ -90,7 +82,6 @@ private ulong SearchForFullState(BlockHeader startHeader) if (IsFullySynced(startHeader)) { - // startHeader.Number is ulong — direct assignment, no cast needed. bestFullState = startHeader.Number; break; } diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs index 9dcaf14ce94f..f54e3d99c977 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs @@ -573,10 +573,6 @@ private bool ShouldBeInStateSyncMode(Snapshot best) bool hasAnyPostPivotPeer = best.AnyPostPivotPeerKnown || (_syncConfig.StaticSnapPivot && best.Peer.Block >= best.PivotNumber); bool notInFastSync = !best.IsInFastSync; bool notNeedToWaitForHeaders = NotNeedToWaitForHeaders; - // Safe: _syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta are non-negative config - // ints whose sum fits comfortably in ulong. If TargetBlock < Header the subtraction wraps - // (ulong underflow) yielding a very large number, so stickyStateNodes is false — correct - // behaviour because we are already ahead of the target. bool stickyStateNodes = best.TargetBlock - best.Header < _syncConfig.StateMinDistanceFromHead + StickyStateNodesDelta; bool stateNotDownloadedYet = !best.StateDownloaded; diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs index c5c587e3dc41..a80598523e68 100644 --- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs +++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs @@ -32,7 +32,7 @@ public ulong FindBestFullBlock() => Math.Min( _blockTree.BestSuggestedHeader?.Number ?? 0UL, _blockTree.BestSuggestedBody?.Number ?? 0UL); // avoiding any potential concurrency issue public bool IsLoadingBlocksFromDb() => !_blockTree.CanAcceptNewBlocks; - public ulong FindBestProcessedBlock() => _blockTree.Head?.Number is { } n ? n : ulong.MaxValue; + public ulong FindBestProcessedBlock() => _blockTree.Head?.Number ?? ulong.MaxValue; public UInt256 ChainDifficulty => _blockTree.BestSuggestedBody?.TotalDifficulty ?? UInt256.Zero; public UInt256? GetTotalDifficulty(Hash256 blockHash) @@ -61,14 +61,7 @@ public ulong FindBestFullBlock() => Math.Min( public bool IsFastBlocksReceiptsFinished() => !IsFastBlocks() || !_syncConfig.DownloadReceiptsInFastSync || receiptsSyncFeed.IsFinished; public bool IsFastBlockAccessListsFinished() => !IsFastBlocks() || !_syncConfig.DownloadBlockAccessListsInFastSync || blockAccessListsSyncFeed.IsFinished; public void RecalculateProgressPointers() => _blockTree.RecalculateTreeLevels(); - public (ulong BlockNumber, Hash256 BlockHash) SyncPivot - { - get - { - (ulong blockNumber, Hash256 blockHash) = _blockTree.SyncPivot; - return (blockNumber, blockHash); - } - } + public (ulong BlockNumber, Hash256 BlockHash) SyncPivot => _blockTree.SyncPivot; private bool IsFastBlocks() => _syncConfig.FastSync && _blockTree.SyncPivot.BlockNumber != 0UL; // if pivot number is 0 then it is equivalent to fast blocks disabled } } diff --git a/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs b/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs index 1b2183aa5424..eb4fb645b6c8 100644 --- a/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs +++ b/src/Nethermind/Nethermind.Synchronization/Peers/PeerInfo.cs @@ -26,8 +26,8 @@ public class PeerInfo(ISyncPeer syncPeer, AllocationAllowances? allocationAllowa private uint _weaknesses; private uint _sleepingContexts; - private long _lastNotifiedEarliestNumber; - private long _lastNotifiedLatestNumber; + private ulong _lastNotifiedEarliestNumber; + private ulong _lastNotifiedLatestNumber; public NodeClientType PeerClientType => SyncPeer?.ClientType ?? NodeClientType.Unknown; @@ -139,7 +139,7 @@ public void EnsureInitialized() } [MethodImpl(MethodImplOptions.Synchronized)] - public bool ShouldNotifyNewRange(long earliestNumber, long latestNumber) + public bool ShouldNotifyNewRange(ulong earliestNumber, ulong latestNumber) { // Also notify if same header as could be reorg with different hash if (latestNumber < _lastNotifiedLatestNumber && earliestNumber < _lastNotifiedEarliestNumber) diff --git a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs index 91f4712f4f2c..886438e51875 100644 --- a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs +++ b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs @@ -650,7 +650,6 @@ public void UpdateSyncPeerHeadIfHeaderIsBetter(ISyncPeer syncPeer, BlockHeader h if (parent is not null && (parent.TotalDifficulty ?? 0) != 0) { UInt256 newTotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty; - // header.Number is ulong; Compare expects long Number. Cast is safe for realistic chain heights. bool newValueIsNotWorseThanPeer = _betterPeerStrategy.Compare((newTotalDifficulty, header.Number), syncPeer) >= 0; if (_logger.IsTrace) _logger.Trace($"REFRESH Updating header of {syncPeer} from {syncPeer.HeadNumber} to {header.Number} based on totalDifficulty, newValueIsNotWorseThanPeer {newValueIsNotWorseThanPeer}, newTotalDifficulty: {newTotalDifficulty}, header.Difficulty: {header.Difficulty}, Parent total difficulty: {parent.TotalDifficulty}"); if (newValueIsNotWorseThanPeer) diff --git a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs index 5fbaa4550eff..97533e501745 100644 --- a/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs +++ b/src/Nethermind/Nethermind.Synchronization/Reporting/SyncReport.cs @@ -5,6 +5,7 @@ using System.Text; using Nethermind.Blockchain.Synchronization; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Core.Timers; using Nethermind.Logging; using Nethermind.Stats; @@ -49,7 +50,7 @@ public SyncReport(ISyncPeerPool syncPeerPool, INodeStatsManager nodeStatsManager BeaconHeaders.SetFormat((progress) => { - ulong numHeadersToDownload = _pivot.PivotNumber - _pivot.PivotDestinationNumber + 1; + ulong numHeadersToDownload = _pivot.PivotNumber.SaturatingSub(_pivot.PivotDestinationNumber) + 1; string skipSectionStr = progress.SkippedPerSecond != -1 ? $"skipped {progress.SkippedPerSecond,ProgressLogger.SpeedPaddingLength:N0} Blk/s | " : ""; diff --git a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs index c7c0f1e6b831..7541e4065286 100644 --- a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs @@ -174,9 +174,7 @@ public void AddNewBlock(Block block, ISyncPeer nodeWhoSentTheBlock) bool isBlockBeforeTheSyncPivot = block.Number < _pivotNumber; ulong headNumber = _blockTree.Head?.Number ?? 0UL; - // Guard against underflow - bool isBlockOlderThanMaxReorgAllows = headNumber > Sync.MaxReorgLength && - block.Number < headNumber - Sync.MaxReorgLength; + bool isBlockOlderThanMaxReorgAllows = block.Number < headNumber.SaturatingSub(Sync.MaxReorgLength); // We skip blocks that are old if (isBlockBeforeTheSyncPivot || isBlockOlderThanMaxReorgAllows) @@ -255,7 +253,7 @@ private bool ValidateSeal(Block block, ISyncPeer syncPeer) // It is important that we only do that here, after we ensured that the block is // in the range of [Head - MaxReorganizationLength, Head]. // Otherwise we could hint incorrect ranges and cause expensive cache recalculations. - ulong start = block.Number >= 128 ? block.Number - 128 : 0UL; + ulong start = block.Number.SaturatingSub(128); _sealValidator.HintValidationRange(_sealValidatorUserGuid, start, block.Number + 1024); return _sealValidator.ValidateSeal(block.Header, true); } @@ -365,8 +363,7 @@ public void HintBlock(Hash256 hash, ulong number, ISyncPeer syncPeer) { if (!_gossipPolicy.CanGossipBlocks) return; - // number is from the peer protocol (long); HeadNumber is ulong. Guard against negative values. - if (number >= 0 && number > syncPeer.HeadNumber) + if (number > syncPeer.HeadNumber) { if (_logger.IsTrace) _logger.Trace($"HINT Updating header of {syncPeer} from {syncPeer.HeadNumber} {syncPeer.TotalDifficulty} to {number}"); syncPeer.HeadNumber = number; @@ -540,7 +537,7 @@ private void RangeBroadcast(BlockHeader earliest, BlockHeader latest, Cancellati return; } PeerInfo peerInfo = allPeers[i]; - if (peerInfo.ShouldNotifyNewRange((long)earliest.Number, (long)latest.Number)) + if (peerInfo.ShouldNotifyNewRange(earliest.Number, latest.Number)) { NotifyOfNewRange(peerInfo, earliest, latest); Interlocked.Increment(ref counter); From 491701a27bbc9daa1b438021802e0e00c4dae307 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Sat, 20 Jun 2026 00:15:55 +0200 Subject: [PATCH 57/60] review(sync.merge): ulong cascade in WithBlockTrees/test scenarios, use ulong.Min/Max MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HeadersSyncFeed: SaturatingSub in BuildRightFiller (drops the EndNumber/rightFillerSize underflow comment); strip the "Use ulong.MaxValue / 0 as 'not set' sentinel" comments in InsertHeaders — the sentinels are obvious from the initial values. BlockTreeTests.WithBlockTrees gains a ulong overload that narrows once at the entry, so callers don't need (int) casts on ulong test parameters. BlockDownloaderTests.Merge: drop the local ULongMin/ULongMax helpers in favour of the BCL `ulong.Min` / `ulong.Max`; cascade fastSyncLag / headNumber / blocksToIgnore to ulong; drop the "BOUNDARY CAST" / "fastSyncLag is non-negative" / "ULongMin avoids …" narration that re-stated the type contract. SaturatingSub replaces the `Math.Max(0, Math.Min(headNumber, headNumber - fastSyncLag))` clamp. --- .../BlockTreeTests.cs | 12 ++++ .../BlockDownloaderTests.Merge.cs | 64 ++++++++----------- .../FastBlocks/HeadersSyncFeed.cs | 7 +- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs index 6de0d8662b9b..a4143cc28ffb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/BlockTreeTests.cs @@ -279,6 +279,18 @@ public class ScenarioBuilder private IChainLevelHelper? _chainLevelHelper; private IBeaconPivot? _beaconPivot; + public ScenarioBuilder WithBlockTrees( + ulong notSyncedTreeSize, + ulong? syncedTreeSize = null, + bool moveBlocksToMainChain = true, + UInt256? ttd = null, + int splitVariant = 0, + int splitFrom = 0, + int syncedSplitVariant = 0, + int syncedSplitFrom = 0, + IReceiptStorage? receiptStorage = null + ) => WithBlockTrees(checked((int)notSyncedTreeSize), syncedTreeSize is { } s ? checked((int)s) : -1, moveBlocksToMainChain, ttd, splitVariant, splitFrom, syncedSplitVariant, syncedSplitFrom, receiptStorage); + public ScenarioBuilder WithBlockTrees( int notSyncedTreeSize, int syncedTreeSize = -1, diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs index a0645a5365f1..99a71b93f122 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.Merge.cs @@ -14,6 +14,7 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Core.Test.Modules; using Nethermind.Db; @@ -30,18 +31,13 @@ namespace Nethermind.Synchronization.Test; public partial class BlockDownloaderTests { - // BCL Math.Min/Math.Max have no ulong overloads; use these helpers to avoid - // boundary casts and the unsafe negative-then-cast-to-ulong pattern. - private static ulong ULongMin(ulong a, ulong b) => a < b ? a : b; - private static ulong ULongMax(ulong a, ulong b) => a > b ? a : b; - - [TestCase(16UL, 32UL, false, 32, 32UL)] - [TestCase(16UL, 32UL, false, 32, 29UL)] - [TestCase(16UL, 32UL, true, 0, 32UL)] - [TestCase(16UL, SyncBatchSizeMax * 8, true, 32, 32UL)] - [TestCase(16UL, SyncBatchSizeMax * 8, false, 32, 32UL)] - [TestCase(16UL, SyncBatchSizeMax * 8, false, 32, SyncBatchSizeMax * 8 - 16UL)] - public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool enableFastSync, int fastSyncLag, ulong insertedBeaconBlocks) + [TestCase(16UL, 32UL, false, 32UL, 32UL)] + [TestCase(16UL, 32UL, false, 32UL, 29UL)] + [TestCase(16UL, 32UL, true, 0UL, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, true, 32UL, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, false, 32UL, 32UL)] + [TestCase(16UL, SyncBatchSizeMax * 8, false, 32UL, SyncBatchSizeMax * 8 - 16UL)] + public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool enableFastSync, ulong fastSyncLag, ulong insertedBeaconBlocks) { bool withReceipts = enableFastSync; ulong notSyncedTreeStartingBlockNumber = 3; @@ -49,7 +45,7 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena InMemoryReceiptStorage? receiptStorage = withReceipts ? new InMemoryReceiptStorage() : null; BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() - .WithBlockTrees((int)notSyncedTreeStartingBlockNumber + 1, (int)headNumber + 1, receiptStorage: receiptStorage) + .WithBlockTrees(notSyncedTreeStartingBlockNumber + 1, headNumber + 1, receiptStorage: receiptStorage) .InsertBeaconPivot(beaconPivot) .InsertBeaconHeaders(notSyncedTreeStartingBlockNumber + 1, beaconPivot - 1) .InsertBeaconBlocks(beaconPivot + 1, insertedBeaconBlocks, BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder.TotalDifficultyMode.Null); @@ -59,7 +55,7 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena new SyncConfig() { FastSync = enableFastSync, - StateMinDistanceFromHead = (ulong)fastSyncLag + StateMinDistanceFromHead = fastSyncLag }, new MergeConfig() { @@ -67,7 +63,6 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena }); PostMergeContext ctx = container.Resolve(); - // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(beaconPivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(beaconPivot, BlockTreeLookupOptions.None); @@ -84,12 +79,10 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena { await ctx.FastSyncUntilNoRequest(peerInfo); ulong expectedDownloadStart = notSyncedTreeStartingBlockNumber; - // fastSyncLag is a non-negative int test parameter; cast to ulong is safe. - // ULongMin avoids the old pattern of (long) subtraction → negative → cast-to-ulong wrap-around. - ulong expectedDownloadEnd = ULongMin(headNumber, insertedBeaconBlocks - (ulong)fastSyncLag); + ulong expectedDownloadEnd = ulong.Min(headNumber, insertedBeaconBlocks - fastSyncLag); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(ULongMax(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); - Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(ULongMax(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(ulong.Max(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); + Assert.That(ctx.BlockTree.BestKnownNumber, Is.EqualTo(ulong.Max(notSyncedTreeStartingBlockNumber, expectedDownloadEnd))); ulong receiptCount = 0; for (ulong i = expectedDownloadStart; i < expectedDownloadEnd; i++) @@ -101,7 +94,7 @@ public async Task Merge_Happy_path(ulong beaconPivot, ulong headNumber, bool ena } Assert.That(ctx.ReceiptStorage.Count, Is.EqualTo(withReceipts ? (int)receiptCount : 0)); - Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(ULongMax(insertedBeaconBlocks - (ulong)fastSyncLag, beaconPivot))); + Assert.That(ctx.BeaconPivot.ProcessDestination?.Number, Is.EqualTo(ulong.Max(insertedBeaconBlocks - fastSyncLag, beaconPivot))); } await ctx.FullSyncUntilNoRequest(peerInfo); @@ -128,8 +121,7 @@ public async Task Can_reach_terminal_block(long headNumber, int options, int thr PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - // BOUNDARY CAST: FindHeader overload takes `long`; safe while block numbers < long.MaxValue - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16L, BlockTreeLookupOptions.None)); + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -164,8 +156,7 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(ulong headNumber, int ttdBlock, PostMergeContext ctx = container.Resolve(); if (withBeaconPivot) - // BOUNDARY CAST: FindHeader overload takes `long`; safe while block numbers < long.MaxValue - ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16L, BlockTreeLookupOptions.None)); + ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(16UL, BlockTreeLookupOptions.None)); SyncPeerMock syncPeer = new(syncedTree, false, Response.AllCorrect, 16000000); PeerInfo peerInfo = new(syncPeer); @@ -174,13 +165,13 @@ public async Task IfNoBeaconPivot_thenStopAtPoS(ulong headNumber, int ttdBlock, Assert.That(notSyncedTree.BestKnownNumber, Is.EqualTo(expectedBestKnownNumber)); } - [TestCase(32UL, 32UL, 0, 32)] - [TestCase(32UL, 32UL, 10, 22)] - public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int blocksToIgnore, long expectedBestKnownNumber) + [TestCase(32UL, 32UL, 0UL, 32)] + [TestCase(32UL, 32UL, 10UL, 22)] + public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, ulong blocksToIgnore, long expectedBestKnownNumber) { BlockTreeTests.BlockTreeTestScenario.ScenarioBuilder blockTrees = BlockTreeTests.BlockTreeTestScenario .GoesLikeThis() - .WithBlockTrees(4, (int)headNumber + 1) + .WithBlockTrees(4, headNumber + 1) .InsertBeaconPivot(pivot) .InsertBeaconHeaders(4, pivot - 1); @@ -188,11 +179,10 @@ public async Task WillSkipBlocksToIgnore(ulong pivot, ulong headNumber, int bloc await using IContainer container = CreateMergeNode(blockTrees, new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = (ulong)blocksToIgnore + StateMinDistanceFromHead = blocksToIgnore }); PostMergeContext ctx = container.Resolve(); - // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None); @@ -267,23 +257,23 @@ public async Task Recalculate_header_total_difficulty() [Test] public async Task BlockDownloader_works_correctly_with_withdrawals() { - int fastSyncLag = 2; + ulong fastSyncLag = 2; await using IContainer container = CreateMergeNode((_) => { }, new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = (ulong)fastSyncLag, + StateMinDistanceFromHead = fastSyncLag, }); PostMergeContext ctx = container.Resolve(); Response responseOptions = Response.AllCorrect | Response.WithTransactions; - int headNumber = 5; + ulong headNumber = 5; // normally chain length should be head number + 1 so here we setup a slightly shorter chain which // will only be fixed slightly later - ulong chainLength = (ulong)headNumber + 1; + ulong chainLength = headNumber + 1; SyncPeerMock syncPeerInternal = new(chainLength, true, responseOptions, true); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -303,8 +293,7 @@ public async Task BlockDownloader_works_correctly_with_withdrawals() PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); await ctx.FastSyncUntilNoRequest(peerInfo); - // fastSyncLag is non-negative; subtraction is safe as headNumber > fastSyncLag in this test - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)Math.Max(0, Math.Min(headNumber, headNumber - fastSyncLag)))); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(ulong.Min(headNumber, headNumber.SaturatingSub(fastSyncLag)))); syncPeerInternal.ExtendTree(chainLength * 2); await ctx.FullSyncUntilNoRequest(peerInfo); @@ -330,7 +319,6 @@ public void BlockDownloader_does_not_stop_processing_when_main_chain_is_unknown( }); PostMergeContext ctx = container.Resolve(); - // BOUNDARY CAST: FindHeader overload takes `ulong`; no cast needed. ctx.BeaconPivot.EnsurePivot(blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None)); ctx.BeaconPivot.ProcessDestination = blockTrees.SyncedTree.FindHeader(pivot, BlockTreeLookupOptions.None); diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs index 083022cbe6c4..d9f37edac5d1 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/HeadersSyncFeed.cs @@ -522,10 +522,7 @@ public override SyncResponseHandlingResult HandleResponse(HeadersSyncBatch? batc private static HeadersSyncBatch BuildRightFiller(HeadersSyncBatch batch, int rightFillerSize) { HeadersSyncBatch rightFiller = new(); - // EndNumber is ulong; rightFillerSize is int. Guard against underflow (should never happen in practice). - rightFiller.StartNumber = batch.EndNumber >= (ulong)(rightFillerSize - 1) - ? batch.EndNumber - (ulong)(rightFillerSize - 1) - : 0UL; + rightFiller.StartNumber = batch.EndNumber.SaturatingSub((ulong)(rightFillerSize - 1)); rightFiller.RequestSize = rightFillerSize; return rightFiller; } @@ -623,8 +620,6 @@ protected virtual int InsertHeaders(HeadersSyncBatch batch) using ArrayPoolList headersToAdd = new(response.Length); (Hash256 nextHeaderHash, UInt256? nextHeaderTotalDifficulty) = _expectedNextHeader; - // Use ulong.MaxValue as "not set" sentinel for addedEarliest (any real block number will be lower). - // Use 0 as "not set" sentinel for addedLast (any real block number ≥ 1 will be higher). // These are adjusted during iteration; arithmetic is safe for realistic block heights. ulong addedLast = batch.StartNumber == 0 ? 0UL : batch.StartNumber - 1UL; ulong addedEarliest = batch.EndNumber + 1UL; From 5e5e35b3cce4aad8f04bcf2fee6c4be61936c5be Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Sat, 20 Jun 2026 00:22:47 +0200 Subject: [PATCH 58/60] review(sync.test): fastSynclag/effectiveHead/headNumber ulong, strip noise BlockDownloaderTests: - Happy_path / Invoke_TryUpdateMainChain_Once / ForwardHeaderProvider_*: fastSynclag & headNumber ulong; effectiveHead lifted out of the fast-sync branch and computed via SaturatingSub. expectedNewHeadSequence drops the (ulong)fastSyncLag cast. - Drop the "Dictionary key changed from long to ulong" / "Cast loop variable i (int) to ulong" comments that re-stated the type of the surrounding code. --- .../BlockDownloaderTests.cs | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index 4dcf56626661..88280d28f1f4 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -57,30 +57,30 @@ public partial class BlockDownloaderTests private const int FullBatch = 24; private const ulong SyncBatchSizeMax = 128; - [TestCase(1UL, false, 0)] - [TestCase(32UL, false, 0)] - [TestCase(32UL, true, 0)] - [TestCase(1UL, true, 0)] - [TestCase(2UL, true, 0)] - [TestCase(3UL, true, 0)] - [TestCase(32UL, true, 0)] - [TestCase(SyncBatchSizeMax * 8, true, 0)] - [TestCase(SyncBatchSizeMax * 8, false, 0)] - [TestCase(1UL, false, 32)] - [TestCase(32UL, false, 32)] - [TestCase(32UL, true, 32)] - [TestCase(1UL, true, 32)] - [TestCase(2UL, true, 32)] - [TestCase(3UL, true, 32)] - [TestCase(32UL, true, 32)] - [TestCase(SyncBatchSizeMax * 8, true, 32)] - [TestCase(SyncBatchSizeMax * 8, false, 32)] - public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSynclag) + [TestCase(1UL, false, 0UL)] + [TestCase(32UL, false, 0UL)] + [TestCase(32UL, true, 0UL)] + [TestCase(1UL, true, 0UL)] + [TestCase(2UL, true, 0UL)] + [TestCase(3UL, true, 0UL)] + [TestCase(32UL, true, 0UL)] + [TestCase(SyncBatchSizeMax * 8, true, 0UL)] + [TestCase(SyncBatchSizeMax * 8, false, 0UL)] + [TestCase(1UL, false, 32UL)] + [TestCase(32UL, false, 32UL)] + [TestCase(32UL, true, 32UL)] + [TestCase(1UL, true, 32UL)] + [TestCase(2UL, true, 32UL)] + [TestCase(3UL, true, 32UL)] + [TestCase(32UL, true, 32UL)] + [TestCase(SyncBatchSizeMax * 8, true, 32UL)] + [TestCase(SyncBatchSizeMax * 8, false, 32UL)] + public async Task Happy_path(ulong headNumber, bool enableFastSync, ulong fastSynclag) { await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = enableFastSync, - StateMinDistanceFromHead = (ulong)fastSynclag + StateMinDistanceFromHead = fastSynclag })); Context ctx = node.Resolve(); bool withReceipts = enableFastSync; @@ -98,12 +98,11 @@ public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSync PeerInfo peerInfo = new(syncPeer); ctx.ConfigureBestPeer(peerInfo); + ulong effectiveHead = headNumber.SaturatingSub(fastSynclag); if (enableFastSync) { await ctx.FastSyncUntilNoRequest(peerInfo); - // Use long arithmetic to safely handle the fastSynclag subtraction (which could underflow if ulong). - long effectiveHead = Math.Max(0L, (long)headNumber - fastSynclag); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)effectiveHead)); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(effectiveHead)); } syncPeer.ExtendTree(chainLength * 2); @@ -116,8 +115,7 @@ public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSync if (enableFastSync) { int receiptCount = 0; - long effectiveHead2 = Math.Max(0L, (long)headNumber - fastSynclag); - for (int i = 0; i < (int)effectiveHead2; i++) + for (ulong i = 0; i < effectiveHead; i++) { if (i % 3 == 0) { @@ -133,14 +131,14 @@ public async Task Happy_path(ulong headNumber, bool enableFastSync, int fastSync public async Task Invoke_TryUpdateMainChain_Once() { ulong headNumber = 100; - int fastSyncLag = 10; + ulong fastSyncLag = 10; bool withReceipts = true; ulong chainLength = headNumber + 1; await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = (ulong)fastSyncLag, + StateMinDistanceFromHead = fastSyncLag, })); Context ctx = node.Resolve(); @@ -152,11 +150,11 @@ public async Task Invoke_TryUpdateMainChain_Once() ctx.BlockTree.BlockAddedToMain += (_, b) => newHeadSequence.Add(b.Block.Number); await ctx.FastSyncUntilNoRequest(peerInfo); - long effectiveHead = Math.Max(0L, (long)headNumber - fastSyncLag); - Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo((ulong)effectiveHead)); + ulong effectiveHead = headNumber.SaturatingSub(fastSyncLag); + Assert.That(ctx.BlockTree.BestSuggestedHeader!.Number, Is.EqualTo(effectiveHead)); List expectedNewHeadSequence = Enumerable - .Range(1, (int)(chainLength - (ulong)fastSyncLag - 1)) + .Range(1, (int)(chainLength - fastSyncLag - 1)) .Select(i => (ulong)i) .ToList(); Assert.That(newHeadSequence, Is.EqualTo(expectedNewHeadSequence)); @@ -166,7 +164,7 @@ public async Task Invoke_TryUpdateMainChain_Once() public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion() { ulong headNumber = 200; - int fastSyncLag = 10; + ulong fastSyncLag = 10; bool withReceipts = true; ulong chainLength = headNumber + 1; @@ -175,7 +173,7 @@ public async Task ForwardHeaderProvider_ReturnedSameHeaders_EvenAfterSuggestion( await using IContainer node = CreateNode(configProvider: new ConfigProvider(new SyncConfig() { FastSync = true, - StateMinDistanceFromHead = (ulong)fastSyncLag, + StateMinDistanceFromHead = fastSyncLag, }), configurer: (builder) => builder.AddSingleton(mockForwardHeaderProvider)); @@ -738,11 +736,11 @@ public async Task On_null_receipt_will_retry() Response responseOptions = Response.AllCorrect | Response.WithTransactions; - int headNumber = 5; + ulong headNumber = 5; // normally chain length should be head number + 1 so here we setup a slightly shorter chain which // will only be fixed slightly later - ulong chainLength = (ulong)(headNumber + 1); + ulong chainLength = headNumber + 1; SyncPeerMock syncPeerInternal = new(chainLength, true, responseOptions); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -869,7 +867,6 @@ private IContainer CreateNode(Action? configurer = null, IConf return tree; }) - // Dictionary key changed from long to ulong to match BlockHeader.Number .AddSingleton, IBlockTree>((blockTree) => new Dictionary() { { @@ -1116,7 +1113,6 @@ public async Task GetBlockBodies(IReadOnlyList blockH BlockHeader[] headers = new BlockHeader[maxBlocks]; for (int i = 0; i < (justFirst ? 1 : maxBlocks); i++) { - // Cast loop variable i (int) to ulong to avoid ambiguous operator with ulong number headers[i] = BlockTree.FindHeader(number + (ulong)i, BlockTreeLookupOptions.None)!; } @@ -1220,7 +1216,6 @@ private class ResponseBuilder(IBlockTree blockTree, Dictionary t _blockTree.SuggestHeader(header); } - // Cast loop variable i (int) to ulong to avoid ambiguous operator with ulong startNumber _testHeaderMapping[startNumber + (ulong)i] = headers[i].Hash!; } } From 68073b3ab5e505d81366e8f54b2e6228c1ee752c Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Sat, 20 Jun 2026 00:30:46 +0200 Subject: [PATCH 59/60] review(sync.test): ulong types and cast-free arg lookups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ForwardHeaderProviderTests: _testHeaderMapping rekeyed long → ulong; BuildHeaderResponse signature ulong; drop the `(long)ci.ArgAt(0)` casts at six call sites; DI registration updated to Dictionary. - StateSyncPivotTest: replace `(ulong)ci[0]` (object boxing) with ci.ArgAt(0) — clearer intent, no cast. - StateSyncDispatcherTests.ChainLength: int → ulong const; drop the (ulong) casts on `peer.HeadNumber.Returns(ChainLength - 1)`. - StateSyncFeedHealingTests.blockJumps: int → ulong; cascade loop counters; drop the (ulong)blockJumps cast. - HealingTreeTests line 223: `(ulong)100` → `100ul`. --- .../StateSyncDispatcherTests.cs | 6 ++--- .../FastSync/StateSyncFeedHealingTests.cs | 8 +++---- .../ForwardHeaderProviderTests.cs | 24 +++++++++---------- .../SnapSync/StateSyncPivotTest.cs | 2 +- .../Trie/HealingTreeTests.cs | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs index bce0112ccf0d..ed03601c3e04 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/SnapProtocolTests/StateSyncDispatcherTests.cs @@ -36,7 +36,7 @@ public class StateSyncDispatcherTests private readonly PublicKey _publicKey = new("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"); - private const int ChainLength = 100; + private const ulong ChainLength = 100; private static IBlockTree BlockTree => LazyInitializer.EnsureInitialized(ref _blockTree, static () => Build.A.BlockTree().OfChainLength(ChainLength).TestObject); [SetUp] @@ -68,7 +68,7 @@ public async Task Eth66Peer_RunGetNodeData() peer.ProtocolVersion.Returns((byte)66); peer.IsInitialized.Returns(true); peer.TotalDifficulty.Returns(new Int256.UInt256(1_000_000_000)); - peer.HeadNumber.Returns((ulong)(ChainLength - 1)); + peer.HeadNumber.Returns(ChainLength - 1); _pool.AddPeer(peer); using StateSyncBatch batch = new( @@ -89,7 +89,7 @@ public async Task GroupMultipleStorageSlotsByAccount() peer.ProtocolVersion.Returns((byte)67); peer.IsInitialized.Returns(true); peer.TotalDifficulty.Returns(new Int256.UInt256(1_000_000_000)); - peer.HeadNumber.Returns((ulong)(ChainLength - 1)); + peer.HeadNumber.Returns(ChainLength - 1); ISnapSyncPeer snapPeer = Substitute.For(); peer.TryGetSatelliteProtocol("snap", out Arg.Any()).Returns( x => diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs index 40c297cc5b78..624245d10229 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedHealingTests.cs @@ -67,7 +67,7 @@ public async Task HealBigSqueezedRandomTree() pathPool[i] = keccak; } - int blockJumps = 5; + ulong blockJumps = 5; // Store accounts snapshot at each block number SortedDictionary[] accountsAtBlock = new SortedDictionary[blockJumps + 1]; @@ -89,7 +89,7 @@ public async Task HealBigSqueezedRandomTree() remote.StateTree.Commit(); // Pre-build all blocks and store state at each block - for (int blockNumber = 1; blockNumber <= blockJumps; blockNumber++) + for (ulong blockNumber = 1; blockNumber <= blockJumps; blockNumber++) { // Store snapshot of accounts and root hash at this block accountsAtBlock[blockNumber] = new SortedDictionary(accounts); @@ -135,7 +135,7 @@ public async Task HealBigSqueezedRandomTree() int endHashIndex; // Now process account ranges using stored snapshots - for (uint blockNumber = 1; blockNumber <= blockJumps; blockNumber++) + for (ulong blockNumber = 1; blockNumber <= blockJumps; blockNumber++) { // Set remote tree to the state at this block number remote.StateTree.RootHash = rootHashAtBlock[blockNumber]; @@ -164,7 +164,7 @@ public async Task HealBigSqueezedRandomTree() endHashIndex = pathPool.Length - 1; } - ProcessAccountRange(remote.StateTree, snapTrieFactory, (ulong)blockJumps, finalRootHash, + ProcessAccountRange(remote.StateTree, snapTrieFactory, blockJumps, finalRootHash, accounts.Where(a => a.Key >= pathPool[startingHashIndex] && a.Key <= pathPool[endHashIndex]).Select(a => new PathWithAccount(a.Key, a.Value)).ToArray()); startingHashIndex += 1000; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs index e413b7017b25..7b032b353a5e 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/ForwardHeaderProviderTests.cs @@ -176,7 +176,7 @@ public async Task Throws_on_inconsistent_batch() Context ctx = node.Resolve(); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect ^ Response.Consistent)); PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -197,7 +197,7 @@ public async Task Throws_on_invalid_seal() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1000UL); @@ -217,7 +217,7 @@ public async Task Cache_block_headers_unless_peer_changed() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1000UL); @@ -234,7 +234,7 @@ public async Task Cache_block_headers_unless_peer_changed() newSyncPeer.HeadNumber.Returns(1000UL); newSyncPeer.TotalDifficulty.Returns(UInt256.MaxValue); newSyncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); ctx.ConfigureBestPeer(new PeerInfo(newSyncPeer)); Assert.That((await forwardHeader.GetBlockHeaders(0, 128, CancellationToken.None)), Is.Not.Null); @@ -251,7 +251,7 @@ public async Task Cache_block_headers_with_disposal() ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1000UL); @@ -290,7 +290,7 @@ public async Task Can_cancel_seal_validation() ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse((long)ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); + .Returns(ci => ctx.ResponseBuilder.BuildHeaderResponse(ci.ArgAt(0), ci.ArgAt(1), Response.AllCorrect)); syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect)); @@ -471,7 +471,7 @@ private IContainer CreateNode(Action? configurer = null, IConf return tree; }) - .AddSingleton, IBlockTree>((blockTree) => new Dictionary() + .AddSingleton, IBlockTree>((blockTree) => new Dictionary() { { 0, blockTree.Genesis!.Hash! @@ -643,12 +643,12 @@ public bool TryGetSatelliteProtocol(string protocol, out T protocolHandler) w throw new NotImplementedException(); } - private class ResponseBuilder(IBlockTree blockTree, Dictionary testHeaderMapping) + private class ResponseBuilder(IBlockTree blockTree, Dictionary testHeaderMapping) { private readonly IBlockTree _blockTree = blockTree; - private readonly Dictionary _testHeaderMapping = testHeaderMapping; + private readonly Dictionary _testHeaderMapping = testHeaderMapping; - public async Task?> BuildHeaderResponse(long startNumber, int number, Response flags) + public async Task?> BuildHeaderResponse(ulong startNumber, int number, Response flags) { bool consistent = flags.HasFlag(Response.Consistent); bool justFirst = flags.HasFlag(Response.JustFirst); @@ -687,7 +687,7 @@ private class ResponseBuilder(IBlockTree blockTree, Dictionary te _blockTree.SuggestHeader(headers[i]); } - _testHeaderMapping[startNumber + i] = headers[i].Hash!; + _testHeaderMapping[startNumber + (ulong)i] = headers[i].Hash!; } } @@ -752,7 +752,7 @@ Block BuildBlockForHeader(BlockHeader header, int txSeed) ? _headers[blockHashes[i]] : Build.A.BlockHeader.WithNumber(blockHeaders[i - 1].Number + 1).WithHash(blockHashes[i]).TestObject; - _testHeaderMapping[(long)(startHeader.Number + (ulong)i)] = blockHeaders[i].Hash!; + _testHeaderMapping[startHeader.Number + (ulong)i] = blockHeaders[i].Hash!; BlockHeader header = consistent ? blockHeaders[i] diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs index 6ab32a30fed5..44b27744127b 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/StateSyncPivotTest.cs @@ -28,7 +28,7 @@ ulong syncPivot { IBlockTree blockTree = Substitute.For(); blockTree.FindHeader(Arg.Any()) - .Returns(static (ci) => Build.A.BlockHeader.WithNumber((ulong)ci[0]).TestObject); + .Returns(static (ci) => Build.A.BlockHeader.WithNumber(ci.ArgAt(0)).TestObject); Synchronization.FastSync.StateSyncPivot stateSyncPivot = new(blockTree, new TestSyncConfig() diff --git a/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs index ce56d38bc4d0..56e97fa5f3b3 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/Trie/HealingTreeTests.cs @@ -220,7 +220,7 @@ void AssertStorage(IContainer client) Address storageAddress = new(Keccak.Compute("storage")); Assert.That(mainWorldState.GetBalance(storageAddress), Is.EqualTo((UInt256)100)); - Assert.That(mainWorldState.GetNonce(storageAddress), Is.EqualTo((ulong)100)); + Assert.That(mainWorldState.GetNonce(storageAddress), Is.EqualTo(100ul)); for (int i = 1; i < 100; i++) { Assert.That(mainWorldState.Get(new StorageCell(storageAddress, (UInt256)i)).ToArray(), Is.EqualTo(i.ToBigEndianByteArray())); From 722a2992afcd8d4e8b593ee64a3efe094c76b8ec Mon Sep 17 00:00:00 2001 From: Dyslex7c Date: Mon, 22 Jun 2026 02:52:20 +0530 Subject: [PATCH 60/60] refactor: unify blockchain metrics, limits, and validation types to ulong --- .../TxPoolSourceTests.cs | 6 ++-- .../Nethermind.Blockchain/Metrics.cs | 4 +-- .../EthashSealValidator.cs | 4 +-- .../ProcessingStatsTests.cs | 4 +-- .../BlockAccessListManager.Validation.cs | 29 ++++++++++++------- .../Processing/BlockAccessListManager.cs | 12 ++++---- .../Processing/ProcessingStats.cs | 5 ++-- .../Producers/TxPoolTxSource.cs | 20 ++++++------- .../Nethermind.Core/Eip7928Constants.cs | 2 +- .../Nethermind.Evm/ReleaseSpecExtensions.cs | 6 ++-- 10 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs index f8faa7443336..47159e37f9bb 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs @@ -79,7 +79,7 @@ public static IEnumerable BlobTransactionsWithBlobGasLimitPerBlock } [TestCaseSource(nameof(MaxProductionBlobCountTests))] - public int MaxProductionBlobCount_calculation(IReleaseSpec spec, int? customBlobLimit) => spec.MaxProductionBlobCount(customBlobLimit); + public ulong MaxProductionBlobCount_calculation(IReleaseSpec spec, int? customBlobLimit) => spec.MaxProductionBlobCount(customBlobLimit); public static IEnumerable MaxProductionBlobCountTests() { @@ -89,8 +89,8 @@ public static IEnumerable MaxProductionBlobCountTests() yield return new TestCaseData(BPO2.Instance, null).Returns(BPO2.Instance.MaxBlobCount); yield return new TestCaseData(Prague.Instance, -1).Returns(Prague.Instance.MaxBlobCount); - yield return new TestCaseData(Prague.Instance, 0).Returns(0); - yield return new TestCaseData(BPO1.Instance, 5).Returns(5); + yield return new TestCaseData(Prague.Instance, 0).Returns(0ul); + yield return new TestCaseData(BPO1.Instance, 5).Returns(5ul); yield return new TestCaseData(BPO2.Instance, 500_000).Returns(BPO2.Instance.MaxBlobCount); } diff --git a/src/Nethermind/Nethermind.Blockchain/Metrics.cs b/src/Nethermind/Nethermind.Blockchain/Metrics.cs index 0c13b2085e5a..2de05a3abba6 100644 --- a/src/Nethermind/Nethermind.Blockchain/Metrics.cs +++ b/src/Nethermind/Nethermind.Blockchain/Metrics.cs @@ -27,7 +27,7 @@ public static class Metrics [GaugeMetric] [Description("Total number of blocks processed")] - public static long Blocks { get; set; } + public static ulong Blocks { get; set; } [CounterMetric] [Description("Total number of chain reorganizations")] @@ -77,7 +77,7 @@ public static class Metrics [GaugeMetric] [Description("The current height of the canonical chain.")] [DataMember(Name = "ethereum_blockchain_height")] - public static long BlockchainHeight { get; set; } + public static ulong BlockchainHeight { get; set; } //EIP-2159: Common Prometheus Metrics Names for Clients [GaugeMetric] diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs index 5d4851bc2408..84a8d95f0ee8 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashSealValidator.cs @@ -24,7 +24,7 @@ public class EthashSealValidator : ISealValidator private readonly ILogger _logger; private readonly LruCache _sealCache = new(2048, 2048, "ethash seals"); - private const int SealValidationIntervalConstantComponent = 1024; + private const uint SealValidationIntervalConstantComponent = 1024; private const long AllowedFutureBlockTimeSeconds = 15; private uint _sealValidationInterval = SealValidationIntervalConstantComponent; @@ -42,7 +42,7 @@ public EthashSealValidator(ILogManager logManager, IDifficultyCalculator difficu private void ResetValidationInterval() => // more or less at the constant component // prevents attack on all Nethermind nodes at once - _sealValidationInterval = (uint)(SealValidationIntervalConstantComponent - 8 + _cryptoRandom.NextInt(16)); + _sealValidationInterval = SealValidationIntervalConstantComponent - 8 + (uint)_cryptoRandom.NextInt(16); public bool ValidateSeal(BlockHeader header, bool force) { diff --git a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs index 8dfa691b524d..e57bb8505b2f 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/ProcessingStatsTests.cs @@ -114,8 +114,8 @@ private static async Task WithRestoredBlockchainMetrics(Func test) double originalMgas = BlockchainMetrics.Mgas; double originalMgasPerSec = BlockchainMetrics.MgasPerSec; long originalTransactions = BlockchainMetrics.Transactions; - long originalBlocks = BlockchainMetrics.Blocks; - long originalBlockchainHeight = BlockchainMetrics.BlockchainHeight; + ulong originalBlocks = BlockchainMetrics.Blocks; + ulong originalBlockchainHeight = BlockchainMetrics.BlockchainHeight; UInt256 originalTotalDifficulty = BlockchainMetrics.TotalDifficulty; UInt256 originalLastDifficulty = BlockchainMetrics.LastDifficulty; ulong originalGasUsed = BlockchainMetrics.GasUsed; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs index 8db7ddc0935c..de0355d4186a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.Validation.cs @@ -165,7 +165,10 @@ _generatedValidationIndex is null || return false; } - ThrowIfStorageReadBudgetExceeded(block, _suggestedChargeableStorageReads - _generatedChargeableStorageReads, validateStorageReads); + ulong surplusReads = _suggestedChargeableStorageReads > _generatedChargeableStorageReads + ? _suggestedChargeableStorageReads - _generatedChargeableStorageReads + : 0ul; + ThrowIfStorageReadBudgetExceeded(block, surplusReads, validateStorageReads); return true; } @@ -179,15 +182,15 @@ private void SlowPathFromGeneratedBlockAccessList(Block block, uint index, bool GeneratedBlockAccessList generated = GeneratedBlockAccessList; ReadOnlyBlockAccessList suggested = block.BlockAccessList!; - int generatedReads = 0; - int suggestedReads = 0; + ulong generatedReads = 0; + ulong suggestedReads = 0; // Pass 1: every account generated touched must match suggested at this index (O(1) // dictionary lookup) or be a tolerated generated-only entry. foreach (GeneratedAccountChanges gen in generated.AccountChanges) { int genReads = IsSystemContract(gen.Address) ? 0 : gen.StorageReads.Count; - generatedReads += genReads; + generatedReads += (ulong)genReads; ReadOnlyAccountChanges? sug = suggested.GetAccountChanges(gen.Address); if (sug is not null) @@ -208,14 +211,17 @@ private void SlowPathFromGeneratedBlockAccessList(Block block, uint index, bool // Tally suggested reads here for the storage-read gas-budget check below. foreach (ReadOnlyAccountChanges sug in suggested.AccountChanges) { - suggestedReads += IsSystemContract(sug.Address) ? 0 : sug.StorageReads.Length; + suggestedReads += IsSystemContract(sug.Address) ? 0ul : (ulong)sug.StorageReads.Length; if (generated.HasAccount(sug.Address)) continue; if (!sug.HasNoChangesAtIndex(index)) ThrowSurplusChanges(block, sug.Address, index); } - ThrowIfStorageReadBudgetExceeded(block, suggestedReads - generatedReads, validateStorageReads); + ulong surplusReads = suggestedReads > generatedReads + ? suggestedReads - generatedReads + : 0ul; + ThrowIfStorageReadBudgetExceeded(block, surplusReads, validateStorageReads); } /// @@ -261,7 +267,10 @@ private void SlowPathFromColumnIndex(Block block, uint index, bool validateStora } // Storage-read gas budget — counts already tracked block-cumulative on both sides. - ThrowIfStorageReadBudgetExceeded(block, _suggestedChargeableStorageReads - _generatedChargeableStorageReads, validateStorageReads); + ulong surplusReads = _suggestedChargeableStorageReads > _generatedChargeableStorageReads + ? _suggestedChargeableStorageReads - _generatedChargeableStorageReads + : 0ul; + ThrowIfStorageReadBudgetExceeded(block, surplusReads, validateStorageReads); } /// @@ -287,7 +296,7 @@ private void RegisterGeneratedSlice(BlockAccessListAtIndex slice) { if (!IsSystemContract(ac.Address)) { - _generatedChargeableStorageReads += ac.StorageReads.Count; + _generatedChargeableStorageReads += (ulong)ac.StorageReads.Count; } } @@ -334,9 +343,9 @@ private static bool IsToleratedGeneratedOnlyAccount(Address address, uint index, => hasNoChangesAtIndex && ((index == 0 && address == Address.SystemUser && !hasChargeableReads) || hasChargeableReads); - private void ThrowIfStorageReadBudgetExceeded(Block block, int surplusReads, bool validateStorageReads) + private void ThrowIfStorageReadBudgetExceeded(Block block, ulong surplusReads, bool validateStorageReads) { - if (validateStorageReads && surplusReads > 0 && _gasRemaining < (ulong)(surplusReads * Eip7928Constants.ItemCost)) + if (validateStorageReads && surplusReads > 0ul && _gasRemaining < surplusReads * Eip7928Constants.ItemCost) { throw new InvalidBlockLevelAccessListException(block.Header, "Suggested block-level access list contained invalid storage reads."); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs index 431097e48eca..8db916d8fbde 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.cs @@ -78,8 +78,8 @@ public partial class BlockAccessListManager( // generated is incremented as each per-tx slice merges in. ValidateBlockAccessList's // fast path checks (suggestedReads - generatedReads) * Eip7928Constants.ItemCost against // _gasRemaining instead of re-walking the whole BAL. - private int _suggestedChargeableStorageReads; - private int _generatedChargeableStorageReads; + private ulong _suggestedChargeableStorageReads; + private ulong _generatedChargeableStorageReads; private bool _hasGeneratedValidationIndexUpdates; // for tests internal bool HasGeneratedValidationIndexUpdates => _hasGeneratedValidationIndexUpdates; @@ -147,10 +147,10 @@ public void PrepareForProcessing(Block suggestedBlock, IReleaseSpec spec, Proces ReadOnlyBlockAccessList suggested = suggestedBlock.BlockAccessList; _suggestedValidationIndex = BlockAccessListValidationIndex.Build(suggested, suggestedBlock.Transactions.Length, addressIndex); _generatedValidationIndex = new(suggestedBlock.Transactions.Length, addressIndex, _suggestedValidationIndex, suggested.TotalStorageReads, suggested.TotalStorageChangeEvents); - int suggestedReads = 0; + ulong suggestedReads = 0; foreach (ReadOnlyAccountChanges ac in suggested.AccountChanges) { - if (!IsSystemContract(ac.Address)) suggestedReads += ac.StorageReads.Length; + if (!IsSystemContract(ac.Address)) suggestedReads += (ulong)ac.StorageReads.Length; } _suggestedChargeableStorageReads = suggestedReads; } @@ -300,8 +300,8 @@ private void Reset() GeneratedBlockAccessList.Reset(); DisposableExtensions.DisposeAndNull(ref _suggestedValidationIndex); DisposableExtensions.DisposeAndNull(ref _generatedValidationIndex); - _suggestedChargeableStorageReads = 0; - _generatedChargeableStorageReads = 0; + _suggestedChargeableStorageReads = 0ul; + _generatedChargeableStorageReads = 0ul; _hasGeneratedValidationIndexUpdates = false; _hasGeneratedRequiredReadAccountMismatch = false; _currentGeneratedBlockAccessList = null; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 54599568020e..8fa317181071 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -371,9 +371,8 @@ protected virtual void GenerateReport(BlockData data) long chunkBlocks = (_chunkBlocks += data.BlockCount); - // Safe cast: block numbers fit well within long range for any realistic chain - Metrics.Blocks = (long)blockNumber; - Metrics.BlockchainHeight = (long)blockNumber; + Metrics.Blocks = blockNumber; + Metrics.BlockchainHeight = blockNumber; Metrics.Transactions += data.TransactionCount; Metrics.TotalDifficulty = block.TotalDifficulty ?? UInt256.Zero; diff --git a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs index 1495e464b06d..007d81f447ed 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs @@ -54,7 +54,7 @@ public IEnumerable GetTransactions(BlockHeader parent, ulong gasLim Func filter = tx => _txFilterPipeline.Execute(tx, parent, spec); - int maxBlobCount = spec.MaxProductionBlobCount(blocksConfig.BlockProductionBlobLimit); + ulong maxBlobCount = spec.MaxProductionBlobCount(blocksConfig.BlockProductionBlobLimit); IEnumerable transactions = GetOrderedTransactions(pendingTransactions, comparer, filter, gasLimit); IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions = GetOrderedBlobTransactions(pendingBlobTransactionsEquivalences, comparer, filter, maxBlobCount); if (_logger.IsDebug) _logger.Debug($"Collecting pending transactions at block gas limit {gasLimit}."); @@ -62,7 +62,7 @@ public IEnumerable GetTransactions(BlockHeader parent, ulong gasLim int checkedTransactions = 0; int selectedTransactions = 0; - using ArrayPoolList selectedBlobTxs = new(maxBlobCount); + using ArrayPoolList selectedBlobTxs = new((int)maxBlobCount); SelectBlobTransactions(blobTransactions, parent, spec, baseFee, selectedBlobTxs, maxBlobCount); @@ -151,9 +151,9 @@ private static IEnumerable PickBlobTxsBetterThanCurrentTx(ArrayPool } } - private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions, BlockHeader parent, IReleaseSpec spec, in UInt256 baseFee, ArrayPoolList selectedBlobTxs, int maxBlobs) + private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain)> blobTransactions, BlockHeader parent, IReleaseSpec spec, in UInt256 baseFee, ArrayPoolList selectedBlobTxs, ulong maxBlobs) { - int maxBlobsToConsider = maxBlobs * 5; + ulong maxBlobsToConsider = maxBlobs * 5ul; ulong countOfRemainingBlobs = 0UL; if (!TryUpdateFeePerBlobGas(parent, spec, out UInt256 feePerBlobGas)) @@ -166,7 +166,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain foreach ((Transaction blobTx, ulong blobChain) in blobTransactions) { ulong txBlobCount = (ulong)blobTx.GetBlobCount(); - if (txBlobCount > (ulong)maxBlobs) + if (txBlobCount > maxBlobs) { if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space."); continue; @@ -181,7 +181,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain if (txBlobCount == 1UL && candidates is null) { selectedBlobTxs.Add(blobTx); - if (selectedBlobTxs.Count == maxBlobs) + if ((ulong)selectedBlobTxs.Count == maxBlobs) { // Early exit, have complete set of 1 blob txs with maximal priority fees // No need to consider other tx. @@ -196,7 +196,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain countOfRemainingBlobs += txBlobCount; } - if (countOfRemainingBlobs > (ulong)maxBlobsToConsider) + if (countOfRemainingBlobs > maxBlobsToConsider) { // Reached max blobs to consider, should have enough to fill the block. break; @@ -209,7 +209,7 @@ private void SelectBlobTransactions(IEnumerable<(Transaction tx, ulong blobChain using (candidates) { // We have leftover candidates. Check how many blob slots remain. - int leftoverCapacity = maxBlobs - selectedBlobTxs.Count; + int leftoverCapacity = (int)(maxBlobs - (ulong)selectedBlobTxs.Count); if (countOfRemainingBlobs <= (ulong)leftoverCapacity) { foreach ((Transaction tx, ulong blobChain) tx in candidates.AsSpan()) @@ -381,8 +381,8 @@ private bool TryUpdateFeePerBlobGas(BlockHeader parent, IReleaseSpec spec, out U protected virtual IEnumerable GetOrderedTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, ulong gasLimit) => Order(pendingTransactions, comparer, filter, gasLimit); - private static IEnumerable<(Transaction tx, ulong blobChain)> GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, int maxBlobs = 0) => - OrderCore(pendingTransactions, comparer, static tx => (ulong)tx.GetBlobCount(), filter, (ulong)maxBlobs); + private static IEnumerable<(Transaction tx, ulong blobChain)> GetOrderedBlobTransactions(IDictionary pendingTransactions, IComparer comparer, Func filter, ulong maxBlobs = 0ul) => + OrderCore(pendingTransactions, comparer, static tx => (ulong)tx.GetBlobCount(), filter, maxBlobs); protected virtual IComparer GetComparer(BlockHeader parent, BlockPreparationContext blockPreparationContext) => _transactionComparerProvider.GetDefaultProducerComparer(blockPreparationContext); diff --git a/src/Nethermind/Nethermind.Core/Eip7928Constants.cs b/src/Nethermind/Nethermind.Core/Eip7928Constants.cs index 340e8762f079..ba05f974e1c2 100644 --- a/src/Nethermind/Nethermind.Core/Eip7928Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip7928Constants.cs @@ -22,5 +22,5 @@ public static class Eip7928Constants /// /// Gas cost per BAL item for size limit. bal_items <= block_gas_limit / ItemCost. /// - public const int ItemCost = 2000; + public const ulong ItemCost = 2000; } diff --git a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs index 5cc8e538ceef..a0697d5896f4 100644 --- a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs @@ -12,10 +12,10 @@ public static class ReleaseSpecExtensions { extension(IReleaseSpec spec) { - public int MaxProductionBlobCount(int? blockProductionBlobLimit) => + public ulong MaxProductionBlobCount(int? blockProductionBlobLimit) => blockProductionBlobLimit >= 0 - ? Math.Min(blockProductionBlobLimit.Value, (int)spec.MaxBlobCount) - : (int)spec.MaxBlobCount; + ? Math.Min((ulong)blockProductionBlobLimit.Value, spec.MaxBlobCount) + : spec.MaxBlobCount; public ulong GetBaseDataCost(Transaction tx) => tx.IsContractCreation && spec.IsEip3860Enabled