diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs index 0b1b763d32d..6ee719ac6fc 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs @@ -135,7 +135,7 @@ public async Task Produces_block() (await StartStop(new Context())).ShouldProduceBlocks(Quantity.AtLeastOne()); } - [Test, Retry(3)] + [Test, Retry(6)] public async Task Can_produce_first_block_when_private_chains_allowed() { Context context = new(); diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs index 7a48e064867..3d243d92bb5 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/Ethash.cs @@ -151,11 +151,11 @@ private static ulong GetRandomNonce() return BitConverter.ToUInt64(buffer, 0); } - private bool IsLessThanTarget(byte[] result, UInt256 difficulty) + private bool IsLessOrEqualThanTarget(byte[] result, UInt256 difficulty) { UInt256 resultAsInteger = new(result, true); - BigInteger threshold = BigInteger.Divide(_2To256, (BigInteger)difficulty); - return (BigInteger)resultAsInteger < threshold; + BigInteger target = BigInteger.Divide(_2To256, (BigInteger)difficulty); + return (BigInteger)resultAsInteger <= target; } public (Keccak MixHash, ulong Nonce) Mine(BlockHeader header, ulong? startNonce = null) @@ -178,7 +178,7 @@ private bool IsLessThanTarget(byte[] result, UInt256 difficulty) { byte[] result; (mixHash, result, _) = Hashimoto(fullSize, dataSet, headerHashed, null, nonce); - if (IsLessThanTarget(result, header.Difficulty)) + if (IsLessOrEqualThanTarget(result, header.Difficulty)) { break; } @@ -243,7 +243,7 @@ public bool Validate(BlockHeader header) return false; } - return IsLessThanTarget(result, header.Difficulty); + return IsLessOrEqualThanTarget(result, header.Difficulty); } private readonly Stopwatch _cacheStopwatch = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs index 16f4ec1043b..6ff5a9295dc 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/GasPriceOracleTests.cs @@ -62,8 +62,8 @@ public void GasPriceEstimate_IfPreviousGasPriceDoesNotExist_FallbackGasPriceSetT GasPriceOracle testGasPriceOracle = new(blockFinder, specProvider, gasPrice); testGasPriceOracle.GetGasPriceEstimate(); - - testGasPriceOracle.FallbackGasPrice.Should().BeEquivalentTo(gasPrice ?? 1.GWei()); + UInt256 expectedGasPrice = 110 * (gasPrice ?? 1.GWei()) / 100; + testGasPriceOracle.FallbackGasPrice.Should().BeEquivalentTo(expectedGasPrice); } [TestCase(3)] diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs index 1452f42ab2b..37c260ea74d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/GasPrice/GasPriceOracle.cs @@ -38,6 +38,7 @@ public class GasPriceOracle : IGasPriceOracle public UInt256 IgnoreUnder { get; set; } = EthGasPriceConstants.DefaultIgnoreUnder; public int BlockLimit { get; set; } = EthGasPriceConstants.DefaultBlocksLimit; private int SoftTxThreshold => BlockLimit * 2; + private readonly UInt256 _defaultMinGasPriceMultiplier = 110; public GasPriceOracle( IBlockFinder blockFinder, @@ -45,7 +46,7 @@ public GasPriceOracle( UInt256? minGasPrice = null) { _blockFinder = blockFinder; - _minGasPrice = minGasPrice ?? new MiningConfig().MinGasPrice; + _minGasPrice = _defaultMinGasPriceMultiplier * (minGasPrice ?? new MiningConfig().MinGasPrice) / 100; SpecProvider = specProvider; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutePayloadResult.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutePayloadResult.cs new file mode 100644 index 00000000000..9f8c87d6715 --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutePayloadResult.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +using Nethermind.Core.Crypto; + +namespace Nethermind.Merge.Plugin.Data +{ + public class ExecutePayloadResult + { + public Keccak BlockHash { get; set; } + + public VerificationStatus Status { get; set; } + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/SyncStatus.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/SyncStatus.cs new file mode 100644 index 00000000000..9fc956b6686 --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/SyncStatus.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +namespace Nethermind.Merge.Plugin.Data +{ + public enum SyncStatus + { + Snap, + Block, + Finished, + Error + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/VerificationStatus.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/VerificationStatus.cs new file mode 100644 index 00000000000..7162e716597 --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/VerificationStatus.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +namespace Nethermind.Merge.Plugin.Data +{ + public enum VerificationStatus + { + Valid, + Invalid, + Known + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs index 95aead7ebda..d303463a96f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs @@ -18,12 +18,15 @@ using System; using System.Threading; using System.Threading.Tasks; +using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.Handlers; using Org.BouncyCastle.Asn1.Cms; +using Result = Nethermind.Merge.Plugin.Data.Result; namespace Nethermind.Merge.Plugin { @@ -98,5 +101,68 @@ public async Task> engine_setHead(Keccak blockHash) public Task> engine_finaliseBlock(Keccak blockHash) => Task.FromResult(_finaliseBlockHandler.Handle(blockHash)); + + public Task engine_preparePayload(Keccak parentHash, UInt256 timestamp, Keccak random, Address coinbase) + { + throw new NotImplementedException(); + } + + public Task> engine_getPayload(Keccak parentHash, UInt256 timeStamp, + Keccak random, Address coinbase) + { + throw new NotImplementedException(); + } + + public Task> engine_executePayload(BlockRequestResult executionPayload) + { + throw new NotImplementedException(); + } + + public Task engine_consensusValidated(Keccak parentHash, VerificationStatus status) + { + throw new NotImplementedException(); + } + + public Task engine_forkchoiceUpdated(Keccak headBlockHash, Keccak finalizedBlockHash, Keccak confirmedBlockHash) + { + throw new NotImplementedException(); + } + + public Task engine_terminalTotalDifficultyOverride(UInt256 terminalTotalDifficulty) + { + throw new NotImplementedException(); + } + + public Task engine_terminalPoWBlockOverride(Keccak blockHash) + { + throw new NotImplementedException(); + } + + public Task> engine_getPowBlock(Keccak blockHash) + { + throw new NotImplementedException(); + } + + public Task engine_syncCheckpointSet(BlockRequestResult executionPayloadHeader) + { + throw new NotImplementedException(); + } + + public Task engine_syncStatus(SyncStatus sync, Keccak blockHash, UInt256 blockNumber) + { + throw new NotImplementedException(); + } + + public Task engine_consensusStatus(UInt256 transitionTotalDifficulty, Keccak terminalPowBlockHash, + Keccak finalizedBlockHash, + Keccak confirmedBlockHash, Keccak headBlockHash) + { + throw new NotImplementedException(); + } + + public Task engine_executionStatus(Keccak finalizedBlockHash, Keccak confirmedBlockHash, Keccak headBlockHash) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs index 60297d9dead..49e3e3654f0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs @@ -16,11 +16,14 @@ // using System.Threading.Tasks; +using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Merge.Plugin.Data; +using Result = Nethermind.Merge.Plugin.Data.Result; namespace Nethermind.Merge.Plugin { @@ -53,5 +56,87 @@ Task> engine_setHead( IsImplemented = true)] Task> engine_finaliseBlock( Keccak blockHash); + + [JsonRpcMethod( + Description = + "Builds an execution payload on top of a given parent with transactions selected from the mempool.", + IsSharable = true, + IsImplemented = false)] + Task engine_preparePayload(Keccak parentHash, UInt256 timestamp, Keccak random, Address coinbase); + + [JsonRpcMethod( + Description = + "Returns the most recent version of an execution payload with respect to the transaction set contained by the mempool.", + IsSharable = true, + IsImplemented = false)] + Task> engine_getPayload(Keccak parentHash, UInt256 timeStamp, Keccak random, + Address coinbase); + + [JsonRpcMethod( + Description = + "Verifies the payload according to the execution environment rule set and returns the status of the verification.", + IsSharable = true, + IsImplemented = false)] + Task> engine_executePayload(BlockRequestResult executionPayload); + + [JsonRpcMethod( + Description = + "Communicates that full consensus validation of an execution payload is complete along with its corresponding status.", + IsSharable = true, + IsImplemented = false)] + Task engine_consensusValidated(Keccak parentHash, VerificationStatus status); + + [JsonRpcMethod( + Description = "Propagates the change in the fork choice to the execution client.", + IsSharable = true, + IsImplemented = false)] + Task engine_forkchoiceUpdated(Keccak headBlockHash, Keccak finalizedBlockHash, Keccak confirmedBlockHash); + + [JsonRpcMethod( + Description = "Propagates an override of the TERMINAL_TOTAL_DIFFICULTY to the execution client.", + IsSharable = true, + IsImplemented = false)] + Task engine_terminalTotalDifficultyOverride(UInt256 terminalTotalDifficulty); + + [JsonRpcMethod( + Description = "Propagates the hash of the terminal PoW block.", + IsSharable = true, + IsImplemented = false)] + Task engine_terminalPoWBlockOverride(Keccak blockHash); + + [JsonRpcMethod( + Description = "Given the hash returns the information of the PoW block.", + IsSharable = true, + IsImplemented = false)] + Task> engine_getPowBlock(Keccak blockHash); + + [JsonRpcMethod( + Description = + "Propagates the header of the payload obtained from the state at the weak subjectivity checkpoint.", + IsSharable = true, + IsImplemented = false)] + Task engine_syncCheckpointSet(BlockRequestResult executionPayloadHeader); + + [JsonRpcMethod( + Description = + "An execution client responds with this status to any request of the consensus layer while sync is being in progress.", + IsSharable = true, + IsImplemented = false)] + Task engine_syncStatus(SyncStatus sync, Keccak blockHash, UInt256 blockNumber); + + [JsonRpcMethod( + Description = + "Sends information on the state of the client to the execution side.", + IsSharable = true, + IsImplemented = false)] + Task engine_consensusStatus(UInt256 transitionTotalDifficulty, Keccak terminalPowBlockHash, + Keccak finalizedBlockHash, Keccak confirmedBlockHash, Keccak headBlockHash); + + [JsonRpcMethod( + Description = + "Responds with information on the state of the execution client to either engine_consensusStatus or any other call if consistency failure has occurred.", + IsSharable = true, + IsImplemented = false)] + Task engine_executionStatus(Keccak finalizedBlockHash, Keccak confirmedBlockHash, Keccak headBlockHash); } } diff --git a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg index 9ce3ef16d79..fbe25ccd6b1 100644 --- a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg @@ -27,9 +27,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13790000, - "PivotHash": "0x08d798a74438f37748d52fc5e37b0bc22ac69d5902c29c219547af807d08f635", - "PivotTotalDifficulty": "4692493839839741411159935836484083635638296744", + "PivotNumber": 13810000, + "PivotHash": "0x9881bce585ff1d73098d05c8a18cfd0bea658d02690bbefe8f5b14b1e1949e82", + "PivotTotalDifficulty": "4699299487178160180429203328632718999867375783", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/energyweb_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/energyweb_pruned.cfg index 3a8920cd04b..d98eafd4caa 100644 --- a/src/Nethermind/Nethermind.Runner/configs/energyweb_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/energyweb_pruned.cfg @@ -32,9 +32,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13790000, - "PivotHash": "0x08d798a74438f37748d52fc5e37b0bc22ac69d5902c29c219547af807d08f635", - "PivotTotalDifficulty": "4692493839839741411159935836484083635638296744", + "PivotNumber": 13810000, + "PivotHash": "0x9881bce585ff1d73098d05c8a18cfd0bea658d02690bbefe8f5b14b1e1949e82", + "PivotTotalDifficulty": "4699299487178160180429203328632718999867375783", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg index 424dcaa637d..3184118dcc8 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg @@ -29,9 +29,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet_beam.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet_beam.cfg index 31a65f0da2d..12d5f62a3dc 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet_beam.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet_beam.cfg @@ -30,9 +30,9 @@ "Sync": { "FastSync": true, "BeamSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadHeadersInFastSync": false, "DownloadBodiesInFastSync": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet_mev.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet_mev.cfg index ae776f9d0b8..764ecaf0695 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet_mev.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet_mev.cfg @@ -29,9 +29,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned.cfg index 819f5975684..4337303733c 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned.cfg @@ -34,9 +34,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned_mev.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned_mev.cfg index 497b02ef035..f2591dbf34f 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned_mev.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet_pruned_mev.cfg @@ -34,9 +34,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_mainnet.cfg index da15b069bd5..b093ce13600 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_mainnet.cfg @@ -42,9 +42,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13212000, - "PivotHash": "0x373ef865825dfc5001258adedafb4a57004de1c0b946bdf3cf98b45792229906", - "PivotTotalDifficulty": "30511108919641849170143", + "PivotNumber": 13218000, + "PivotHash": "0x1765bccda14394a27f3865f604e118a8be7d84ce6ad6e024852e850fcc680e34", + "PivotTotalDifficulty": "30564941907494799221708", "FastBlocks": true, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_ropsten.cfg b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_ropsten.cfg index cef9a259ff7..6b29c886dbc 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_ropsten.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_ropsten.cfg @@ -44,11 +44,11 @@ "FastBlocks": true, "BeamSync": false, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 11010000, + "PivotNumber": 11020000, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, - "PivotHash": "0x5902eba0956e66b8258eef4d960e366b7ef6eeaf46af329e38124e2b2669cd35", - "PivotTotalDifficulty": "34730590699233830" + "PivotHash": "0xd52784fde94c889694b50693dcdfa9175a6ccd961f350bed1577b44a979a529b", + "PivotTotalDifficulty": "34746807075941524" }, "EthStats": { "Enabled": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_xdai.cfg b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_xdai.cfg index 1e68107f331..650c5957eca 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_xdai.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ndm_consumer_xdai.cfg @@ -48,9 +48,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 18050000, - "PivotHash": "0xa870ef9cab39b4da1d03a6c7fd35064f5daeb8928d7f92a8935a6ebc106c04ab", - "PivotTotalDifficulty": "6142096722922939265513911664143416216436595753", + "PivotNumber": 18070000, + "PivotHash": "0xaa0bafbf4a9aabbceda9a2782d26cb868eddbc92d005ff652d69512ca44bf711", + "PivotTotalDifficulty": "6148902370261358034783179156292051580665675043", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/poacore.cfg b/src/Nethermind/Nethermind.Runner/configs/poacore.cfg index 8a0e0422d98..5aa7f4214e7 100644 --- a/src/Nethermind/Nethermind.Runner/configs/poacore.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/poacore.cfg @@ -28,9 +28,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 23230000, - "PivotHash": "0x9c2a3f2916de1990e2d2684ce116f65d92a033b9a109b180faa40574d982617e", - "PivotTotalDifficulty": "7904759383573400506254192130639975551773493820", + "PivotNumber": 23250000, + "PivotHash": "0x86a134d47492fab9ceae1e186d09f7c189f1201ba160121dd35336a9bb5574ea", + "PivotTotalDifficulty": "7911565030911819275523459622788610916002573770", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/poacore_beam.cfg b/src/Nethermind/Nethermind.Runner/configs/poacore_beam.cfg index 20088d25df8..bcd8c9f291d 100644 --- a/src/Nethermind/Nethermind.Runner/configs/poacore_beam.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/poacore_beam.cfg @@ -29,9 +29,9 @@ "Sync": { "FastSync": true, "BeamSync": true, - "PivotNumber": 23230000, - "PivotHash": "0x9c2a3f2916de1990e2d2684ce116f65d92a033b9a109b180faa40574d982617e", - "PivotTotalDifficulty": "7904759383573400506254192130639975551773493820", + "PivotNumber": 23250000, + "PivotHash": "0x86a134d47492fab9ceae1e186d09f7c189f1201ba160121dd35336a9bb5574ea", + "PivotTotalDifficulty": "7911565030911819275523459622788610916002573770", "FastBlocks": true, "DownloadHeadersInFastSync": false, "DownloadBodiesInFastSync": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/poacore_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/poacore_pruned.cfg index 64243002528..9b688464004 100644 --- a/src/Nethermind/Nethermind.Runner/configs/poacore_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/poacore_pruned.cfg @@ -33,9 +33,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 23230000, - "PivotHash": "0x9c2a3f2916de1990e2d2684ce116f65d92a033b9a109b180faa40574d982617e", - "PivotTotalDifficulty": "7904759383573400506254192130639975551773493820", + "PivotNumber": 23250000, + "PivotHash": "0x86a134d47492fab9ceae1e186d09f7c189f1201ba160121dd35336a9bb5574ea", + "PivotTotalDifficulty": "7911565030911819275523459622788610916002573770", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/ropsten.cfg b/src/Nethermind/Nethermind.Runner/configs/ropsten.cfg index a13c4cee0a8..51d36c40053 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ropsten.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ropsten.cfg @@ -30,11 +30,11 @@ "FastBlocks": true, "BeamSync": false, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 11010000, + "PivotNumber": 11020000, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, - "PivotHash": "0x5902eba0956e66b8258eef4d960e366b7ef6eeaf46af329e38124e2b2669cd35", - "PivotTotalDifficulty": "34730590699233830" + "PivotHash": "0xd52784fde94c889694b50693dcdfa9175a6ccd961f350bed1577b44a979a529b", + "PivotTotalDifficulty": "34746807075941524" }, "EthStats": { "Enabled": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/ropsten_beam.cfg b/src/Nethermind/Nethermind.Runner/configs/ropsten_beam.cfg index 7fcb13296f8..d52f76f6f7d 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ropsten_beam.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ropsten_beam.cfg @@ -30,12 +30,12 @@ "FastBlocks": true, "BeamSync": true, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 11010000, + "PivotNumber": 11020000, "DownloadHeadersInFastSync": false, "DownloadBodiesInFastSync": false, "DownloadReceiptsInFastSync": false, - "PivotHash": "0x5902eba0956e66b8258eef4d960e366b7ef6eeaf46af329e38124e2b2669cd35", - "PivotTotalDifficulty": "34730590699233830" + "PivotHash": "0xd52784fde94c889694b50693dcdfa9175a6ccd961f350bed1577b44a979a529b", + "PivotTotalDifficulty": "34746807075941524" }, "EthStats": { "Enabled": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/ropsten_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/ropsten_pruned.cfg index 526fa9ae65d..4bb32262eb3 100644 --- a/src/Nethermind/Nethermind.Runner/configs/ropsten_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/ropsten_pruned.cfg @@ -35,11 +35,11 @@ "FastBlocks": true, "BeamSync": false, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 11010000, + "PivotNumber": 11020000, "DownloadBodiesInFastSync": true, "DownloadReceiptsInFastSync": true, - "PivotHash": "0x5902eba0956e66b8258eef4d960e366b7ef6eeaf46af329e38124e2b2669cd35", - "PivotTotalDifficulty": "34730590699233830" + "PivotHash": "0xd52784fde94c889694b50693dcdfa9175a6ccd961f350bed1577b44a979a529b", + "PivotTotalDifficulty": "34746807075941524" }, "EthStats": { "Enabled": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/sokol.cfg b/src/Nethermind/Nethermind.Runner/configs/sokol.cfg index 9f4fcfed4de..391a618ec4d 100644 --- a/src/Nethermind/Nethermind.Runner/configs/sokol.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/sokol.cfg @@ -28,9 +28,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 22700000, - "PivotHash": "0x676f06465ebcf405e60061e80576c7fe5bef52991fb9925062d8c0e814d98221", - "PivotTotalDifficulty": "7724409729105303120618603588701138399702355594", + "PivotNumber": 22720000, + "PivotHash": "0x31651d66f73adf258ab6e2346ffd5ac557bcaf4ba1149806f0ca3479c6fdcc4d", + "PivotTotalDifficulty": "7731215376443721889887871080849773763931430251", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/sokol_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/sokol_pruned.cfg index a077784503d..97cc9295cc8 100644 --- a/src/Nethermind/Nethermind.Runner/configs/sokol_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/sokol_pruned.cfg @@ -33,9 +33,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 22700000, - "PivotHash": "0x676f06465ebcf405e60061e80576c7fe5bef52991fb9925062d8c0e814d98221", - "PivotTotalDifficulty": "7724409729105303120618603588701138399702355594", + "PivotNumber": 22720000, + "PivotHash": "0x31651d66f73adf258ab6e2346ffd5ac557bcaf4ba1149806f0ca3479c6fdcc4d", + "PivotTotalDifficulty": "7731215376443721889887871080849773763931430251", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/volta.cfg b/src/Nethermind/Nethermind.Runner/configs/volta.cfg index a6f71ae7456..c3cae373777 100644 --- a/src/Nethermind/Nethermind.Runner/configs/volta.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/volta.cfg @@ -28,9 +28,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13530000, - "PivotHash": "0x63289298a5f12d764610da77e233bb19e08fd42df4fb074e8f3c6c7afa457310", - "PivotTotalDifficulty": "4604020424440297410659458438551823900659998911", + "PivotNumber": 13550000, + "PivotHash": "0x481e0264445b50eb7bc6c94b10e412c84f79d51eb8c6b30e10fd97eb1c01772f", + "PivotTotalDifficulty": "4610826071778716179928725930700459264889076534", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/volta_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/volta_pruned.cfg index 1d8bd0d8cc5..a36a0de1b9a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/volta_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/volta_pruned.cfg @@ -33,9 +33,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 13530000, - "PivotHash": "0x63289298a5f12d764610da77e233bb19e08fd42df4fb074e8f3c6c7afa457310", - "PivotTotalDifficulty": "4604020424440297410659458438551823900659998911", + "PivotNumber": 13550000, + "PivotHash": "0x481e0264445b50eb7bc6c94b10e412c84f79d51eb8c6b30e10fd97eb1c01772f", + "PivotTotalDifficulty": "4610826071778716179928725930700459264889076534", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/xdai.cfg b/src/Nethermind/Nethermind.Runner/configs/xdai.cfg index 47c9fb940bd..ce5fc5ad4e0 100644 --- a/src/Nethermind/Nethermind.Runner/configs/xdai.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/xdai.cfg @@ -28,9 +28,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 18050000, - "PivotHash": "0xa870ef9cab39b4da1d03a6c7fd35064f5daeb8928d7f92a8935a6ebc106c04ab", - "PivotTotalDifficulty": "6142096722922939265513911664143416216436595753", + "PivotNumber": 18070000, + "PivotHash": "0xaa0bafbf4a9aabbceda9a2782d26cb868eddbc92d005ff652d69512ca44bf711", + "PivotTotalDifficulty": "6148902370261358034783179156292051580665675043", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/xdai_mev.cfg b/src/Nethermind/Nethermind.Runner/configs/xdai_mev.cfg index e84a22f77f4..338dc540e6a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/xdai_mev.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/xdai_mev.cfg @@ -28,9 +28,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 18050000, - "PivotHash": "0xa870ef9cab39b4da1d03a6c7fd35064f5daeb8928d7f92a8935a6ebc106c04ab", - "PivotTotalDifficulty": "6142096722922939265513911664143416216436595753", + "PivotNumber": 18070000, + "PivotHash": "0xaa0bafbf4a9aabbceda9a2782d26cb868eddbc92d005ff652d69512ca44bf711", + "PivotTotalDifficulty": "6148902370261358034783179156292051580665675043", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/xdai_pruned.cfg b/src/Nethermind/Nethermind.Runner/configs/xdai_pruned.cfg index 78aaef75020..55464d28886 100644 --- a/src/Nethermind/Nethermind.Runner/configs/xdai_pruned.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/xdai_pruned.cfg @@ -33,9 +33,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 18050000, - "PivotHash": "0xa870ef9cab39b4da1d03a6c7fd35064f5daeb8928d7f92a8935a6ebc106c04ab", - "PivotTotalDifficulty": "6142096722922939265513911664143416216436595753", + "PivotNumber": 18070000, + "PivotHash": "0xaa0bafbf4a9aabbceda9a2782d26cb868eddbc92d005ff652d69512ca44bf711", + "PivotTotalDifficulty": "6148902370261358034783179156292051580665675043", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/xdai_pruned_mev.cfg b/src/Nethermind/Nethermind.Runner/configs/xdai_pruned_mev.cfg index af450355070..d8f957cf699 100644 --- a/src/Nethermind/Nethermind.Runner/configs/xdai_pruned_mev.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/xdai_pruned_mev.cfg @@ -33,9 +33,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 18050000, - "PivotHash": "0xa870ef9cab39b4da1d03a6c7fd35064f5daeb8928d7f92a8935a6ebc106c04ab", - "PivotTotalDifficulty": "6142096722922939265513911664143416216436595753", + "PivotNumber": 18070000, + "PivotHash": "0xaa0bafbf4a9aabbceda9a2782d26cb868eddbc92d005ff652d69512ca44bf711", + "PivotTotalDifficulty": "6148902370261358034783179156292051580665675043", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index 722f85da909..0626491c027 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -24,6 +24,7 @@ using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Validators; +using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -48,6 +49,7 @@ using Nethermind.Trie.Pruning; using Nethermind.TxPool; using NSubstitute; +using NSubstitute.Exceptions; using NUnit.Framework; using BlockTree = Nethermind.Blockchain.BlockTree; @@ -76,11 +78,11 @@ public class BlockDownloaderTests [TestCase(SyncBatchSize.Max * 8, DownloaderOptions.Process, 32)] public async Task Happy_path(long headNumber, int options, int threshold) { - Context ctx = new Context(); + Context ctx = new(); DownloaderOptions downloaderOptions = (DownloaderOptions) options; bool withReceipts = downloaderOptions == DownloaderOptions.WithReceipts; - InMemoryReceiptStorage receiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, receiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + InMemoryReceiptStorage receiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, receiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response responseOptions = Response.AllCorrect; if (withReceipts) @@ -91,9 +93,9 @@ public async Task Happy_path(long headNumber, int options, int threshold) // 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; - SyncPeerMock syncPeer = new SyncPeerMock(chainLength, withReceipts, responseOptions); + SyncPeerMock syncPeer = new(chainLength, withReceipts, responseOptions); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.None, threshold), CancellationToken.None); ctx.BlockTree.BestSuggestedHeader.Number.Should().Be(Math.Max(0, Math.Min(headNumber, headNumber - threshold))); @@ -118,21 +120,21 @@ public async Task Happy_path(long headNumber, int options, int threshold) [Test] public async Task Ancestor_lookup_simple() { - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); - Context ctx = new Context(); + Context ctx = new(); ctx.BlockTree = Build.A.BlockTree().OfChainLength(1024).TestObject; ISyncPeerPool syncPeerPool = Substitute.For(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, syncPeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + BlockDownloader downloader = new(ctx.Feed, syncPeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response blockResponseOptions = Response.AllCorrect; - SyncPeerMock syncPeer = new SyncPeerMock(2048 + 1, false, blockResponseOptions); + SyncPeerMock syncPeer = new(2048 + 1, false, blockResponseOptions); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); - var block1024 = Build.A.Block.WithParent(ctx.BlockTree.Head).WithDifficulty(ctx.BlockTree.Head.Difficulty + 1).TestObject; - var block1025 = Build.A.Block.WithParent(block1024).WithDifficulty(block1024.Difficulty + 1).TestObject; - var block1026 = Build.A.Block.WithParent(block1025).WithDifficulty(block1025.Difficulty + 1).TestObject; + Block block1024 = Build.A.Block.WithParent(ctx.BlockTree.Head).WithDifficulty(ctx.BlockTree.Head.Difficulty + 1).TestObject; + Block block1025 = Build.A.Block.WithParent(block1024).WithDifficulty(block1024.Difficulty + 1).TestObject; + Block block1026 = Build.A.Block.WithParent(block1025).WithDifficulty(block1025.Difficulty + 1).TestObject; ctx.BlockTree.SuggestBlock(block1024); ctx.BlockTree.SuggestBlock(block1025); ctx.BlockTree.SuggestBlock(block1026); @@ -150,19 +152,19 @@ public async Task Ancestor_lookup_simple() [Test] public async Task Ancestor_lookup_headers() { - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); - Context ctx = new Context(); + Context ctx = new(); ctx.BlockTree = Build.A.BlockTree().OfChainLength(1024).TestObject; - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response responseOptions = Response.AllCorrect; - SyncPeerMock syncPeer = new SyncPeerMock(2048 + 1, false, responseOptions); - PeerInfo peerInfo = new PeerInfo(syncPeer); + SyncPeerMock syncPeer = new(2048 + 1, false, responseOptions); + PeerInfo peerInfo = new(syncPeer); - var block1024 = Build.A.Block.WithParent(ctx.BlockTree.Head).WithDifficulty(ctx.BlockTree.Head.Difficulty + 1).TestObject; - var block1025 = Build.A.Block.WithParent(block1024).WithDifficulty(block1024.Difficulty + 1).TestObject; - var block1026 = Build.A.Block.WithParent(block1025).WithDifficulty(block1025.Difficulty + 1).TestObject; + Block block1024 = Build.A.Block.WithParent(ctx.BlockTree.Head).WithDifficulty(ctx.BlockTree.Head.Difficulty + 1).TestObject; + Block block1025 = Build.A.Block.WithParent(block1024).WithDifficulty(block1024.Difficulty + 1).TestObject; + Block block1026 = Build.A.Block.WithParent(block1025).WithDifficulty(block1025.Difficulty + 1).TestObject; ctx.BlockTree.SuggestBlock(block1024); ctx.BlockTree.SuggestBlock(block1025); ctx.BlockTree.SuggestBlock(block1026); @@ -179,16 +181,16 @@ public async Task Ancestor_lookup_headers() [Test] public void Ancestor_failure() { - InMemoryReceiptStorage memReceiptStorage = new InMemoryReceiptStorage(); + InMemoryReceiptStorage memReceiptStorage = new(); - Context ctx = new Context(); + Context ctx = new(); ctx.BlockTree = Build.A.BlockTree().OfChainLength(2048 + 1).TestObject; - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, memReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, memReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response blockResponseOptions = Response.AllCorrect; - SyncPeerMock syncPeer = new SyncPeerMock(2072 + 1, true, blockResponseOptions); + SyncPeerMock syncPeer = new(2072 + 1, true, blockResponseOptions); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); Assert.ThrowsAsync(() => downloader.DownloadHeaders(peerInfo, new BlocksRequest(), CancellationToken.None)); ctx.BlockTree.BestSuggestedHeader.Number.Should().Be(2048); @@ -197,16 +199,16 @@ public void Ancestor_failure() [Test] public void Ancestor_failure_blocks() { - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); - Context ctx = new Context(); + Context ctx = new(); ctx.BlockTree = Build.A.BlockTree().OfChainLength(2048 + 1).TestObject; - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response responseOptions = Response.AllCorrect; - SyncPeerMock syncPeer = new SyncPeerMock(2072 + 1, true, responseOptions); + SyncPeerMock syncPeer = new(2072 + 1, true, responseOptions); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); Assert.ThrowsAsync(() => downloader.DownloadBlocks(peerInfo, new BlocksRequest(), CancellationToken.None)); ctx.BlockTree.BestSuggestedHeader.Number.Should().Be(2048); @@ -217,8 +219,8 @@ public void Ancestor_failure_blocks() [TestCase(0)] public async Task Can_sync_with_peer_when_it_times_out_on_full_batch(int threshold) { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -230,7 +232,7 @@ public async Task Can_sync_with_peer_when_it_times_out_on_full_batch(int thresho syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.HeadNumber.Returns(SyncBatchSize.Max * 2 + threshold); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, threshold), CancellationToken.None).ContinueWith(t => { }); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, threshold), CancellationToken.None); @@ -246,8 +248,8 @@ public async Task Can_sync_with_peer_when_it_times_out_on_full_batch(int thresho [Test] public async Task Headers_already_known() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -256,7 +258,7 @@ public async Task Headers_already_known() syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.AllKnown)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(64); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None) @@ -271,8 +273,8 @@ public async Task Headers_already_known() [TestCase(65L)] public async Task Peer_sends_just_one_item_when_advertising_more_blocks(long headNumber) { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -281,7 +283,7 @@ public async Task Peer_sends_just_one_item_when_advertising_more_blocks(long hea syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.JustFirst)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.HeadNumber.Returns(headNumber); @@ -295,8 +297,8 @@ public async Task Peer_sends_just_one_item_when_advertising_more_blocks(long hea [TestCase(65L)] public async Task Peer_sends_just_one_item_when_advertising_more_blocks_but_no_bodies(long headNumber) { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -305,7 +307,7 @@ public async Task Peer_sends_just_one_item_when_advertising_more_blocks_but_no_b syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect | Response.JustFirst)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(headNumber); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -318,8 +320,8 @@ public async Task Peer_sends_just_one_item_when_advertising_more_blocks_but_no_b [Test] public async Task Throws_on_null_best_peer() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); Task task1 = downloader.DownloadHeaders(null, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); await task1.ContinueWith(t => Assert.True(t.IsFaulted)); @@ -330,16 +332,16 @@ public async Task Throws_on_null_best_peer() [Test] public async Task Throws_on_inconsistent_batch() { - Context ctx = new Context(); + Context ctx = new(); 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)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.HeadNumber.Returns(1024); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); await task.ContinueWith(t => Assert.True(t.IsFaulted)); } @@ -347,15 +349,15 @@ public async Task Throws_on_inconsistent_batch() [Test] public async Task Throws_on_invalid_seal() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Invalid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Invalid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); 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)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1000); Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); @@ -365,15 +367,15 @@ public async Task Throws_on_invalid_seal() [Test] public async Task Throws_on_invalid_header() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Invalid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Invalid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); 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)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1000); Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); @@ -432,8 +434,8 @@ public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, B [Ignore("Fails OneLoggerLogManager Travis only")] public async Task Can_cancel_seal_validation() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, new SlowSealValidator(), NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, new SlowSealValidator(), NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -442,11 +444,11 @@ public async Task Can_cancel_seal_validation() syncPeer.GetBlockBodies(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildBlocksResponse(ci.ArgAt>(0), Response.AllCorrect)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.HeadNumber.Returns(1000); - CancellationTokenSource cancellation = new CancellationTokenSource(); + CancellationTokenSource cancellation = new(); cancellation.CancelAfter(1000); Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), cancellation.Token); await task.ContinueWith(t => Assert.True(t.IsCanceled, $"headers {t.Status}")); @@ -462,8 +464,8 @@ public async Task Can_cancel_seal_validation() [Test, MaxTime(7000)] public async Task Can_cancel_adding_headers() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, new SlowHeaderValidator(), Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, new SlowHeaderValidator(), Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) @@ -475,9 +477,9 @@ public async Task Can_cancel_adding_headers() syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); syncPeer.HeadNumber.Returns(1000); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); - CancellationTokenSource cancellation = new CancellationTokenSource(); + CancellationTokenSource cancellation = new(); cancellation.CancelAfter(1000); Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), cancellation.Token); await task.ContinueWith(t => Assert.True(t.IsCanceled, "headers")); @@ -489,6 +491,31 @@ public async Task Can_cancel_adding_headers() task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), cancellation.Token); await task.ContinueWith(t => Assert.True(t.IsCanceled, "blocks")); } + + [Test] + public async Task Validate_always_the_last_seal_and_random_seal_in_the_package() + { + ISealValidator sealValidator = Substitute.For(); + sealValidator.ValidateSeal(Arg.Any(), Arg.Any()).Returns(true); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, sealValidator, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + + BlockHeader[] blockHeaders = await ctx.ResponseBuilder.BuildHeaderResponse(0, 512, Response.AllCorrect); + ISyncPeer syncPeer = Substitute.For(); + syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); + syncPeer.GetBlockHeaders(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(blockHeaders); + + PeerInfo peerInfo = new(syncPeer); + syncPeer.HeadNumber.Returns(511); + + Task task = downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); + await task; + + sealValidator.Received(2).ValidateSeal(Arg.Any(), true); + sealValidator.Received(510).ValidateSeal(Arg.Any(), false); + sealValidator.Received().ValidateSeal(blockHeaders[^1], true); + } private class ThrowingPeer : ISyncPeer { @@ -567,11 +594,11 @@ public bool TryGetSatelliteProtocol(string protocol, out T protocolHandler) w [Test] public async Task Faults_on_get_headers_faulting() { - Context ctx = new Context(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, new InMemoryReceiptStorage(), RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = new ThrowingPeer(1000, UInt256.MaxValue); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None) .ContinueWith(t => Assert.True(t.IsFaulted)); @@ -580,9 +607,9 @@ public async Task Faults_on_get_headers_faulting() [Test] public async Task Throws_on_block_task_exception() { - Context ctx = new Context(); - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -596,7 +623,7 @@ public async Task Throws_on_block_task_exception() syncPeer.GetReceipts(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions)); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); @@ -611,10 +638,10 @@ public async Task Throws_on_block_task_exception() [TestCase(DownloaderOptions.Process, false)] public async Task Throws_on_receipt_task_exception_when_downloading_receipts(int options, bool shouldThrow) { - Context ctx = new Context(); + Context ctx = new(); DownloaderOptions downloaderOptions = (DownloaderOptions) options; - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -630,7 +657,7 @@ public async Task Throws_on_receipt_task_exception_when_downloading_receipts(int syncPeer.GetReceipts(Arg.Any>(), Arg.Any()) .Returns(Task.FromException(new TimeoutException())); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, 0), CancellationToken.None); @@ -653,11 +680,11 @@ public async Task Throws_on_receipt_task_exception_when_downloading_receipts(int [TestCase(DownloaderOptions.Process, false)] public async Task Throws_on_null_receipt_downloaded(int options, bool shouldThrow) { - Context ctx = new Context(); + Context ctx = new(); DownloaderOptions downloaderOptions = (DownloaderOptions)options; bool withReceipts = downloaderOptions == DownloaderOptions.WithReceipts; - InMemoryReceiptStorage receiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, receiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + InMemoryReceiptStorage receiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, receiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); Response responseOptions = Response.AllCorrect; if (withReceipts) @@ -670,7 +697,7 @@ public async Task Throws_on_null_receipt_downloaded(int options, bool shouldThro // 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; - SyncPeerMock syncPeerInternal = new SyncPeerMock(chainLength, withReceipts, responseOptions); + SyncPeerMock syncPeerInternal = new(chainLength, withReceipts, 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))); @@ -690,7 +717,7 @@ public async Task Throws_on_null_receipt_downloaded(int options, bool shouldThro syncPeer.HeadHash.Returns(ci => syncPeerInternal.HeadHash); syncPeer.HeadNumber.Returns(ci => syncPeerInternal.HeadNumber); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); int threshold = 2; await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.None, threshold), CancellationToken.None); @@ -713,9 +740,9 @@ public async Task Throws_on_null_receipt_downloaded(int options, bool shouldThro [TestCase(0)] public async Task Throws_on_block_bodies_count_higher_than_receipts_list_count(int threshold) { - Context ctx = new Context(); - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -731,7 +758,7 @@ public async Task Throws_on_block_bodies_count_higher_than_receipts_list_count(i syncPeer.GetReceipts(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions).Result.Skip(1).ToArray()); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, threshold), CancellationToken.None); @@ -745,9 +772,9 @@ public async Task Throws_on_block_bodies_count_higher_than_receipts_list_count(i [TestCase(1)] public async Task Does_throw_on_transaction_count_different_than_receipts_count_in_block(int threshold) { - Context ctx = new Context(); - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -763,7 +790,7 @@ public async Task Does_throw_on_transaction_count_different_than_receipts_count_ .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions) .Result.Select(r => r == null || r.Length == 0 ? r : r.Skip(1).ToArray()).ToArray()); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.None, threshold), CancellationToken.None); @@ -777,9 +804,9 @@ public async Task Does_throw_on_transaction_count_different_than_receipts_count_ [TestCase(1)] public async Task Throws_on_incorrect_receipts_root(int threshold) { - Context ctx = new Context(); - InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); - BlockDownloader downloader = new BlockDownloader(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); + Context ctx = new(); + InMemoryReceiptStorage inMemoryReceiptStorage = new(); + BlockDownloader downloader = new(ctx.Feed, ctx.PeerPool, ctx.BlockTree, Always.Valid, Always.Valid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For(); syncPeer.TotalDifficulty.Returns(UInt256.MaxValue); @@ -795,7 +822,7 @@ public async Task Throws_on_incorrect_receipts_root(int threshold) syncPeer.GetReceipts(Arg.Any>(), Arg.Any()) .Returns(ci => ctx.ResponseBuilder.BuildReceiptsResponse(ci.ArgAt>(0), Response.AllCorrect | Response.WithTransactions).Result); - PeerInfo peerInfo = new PeerInfo(syncPeer); + PeerInfo peerInfo = new(syncPeer); syncPeer.HeadNumber.Returns(1); await downloader.DownloadHeaders(peerInfo, new BlocksRequest(DownloaderOptions.WithBodies, threshold), CancellationToken.None); @@ -830,7 +857,7 @@ private class Context public Context() { Block genesis = Build.A.Block.Genesis.TestObject; - MemDb blockInfoDb = new MemDb(); + MemDb blockInfoDb = new(); BlockTree = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), MainnetSpecProvider.Instance, NullBloomStorage.Instance, LimboLogs.Instance); BlockTree.SuggestBlock(genesis); @@ -840,10 +867,10 @@ public Context() PeerPool = Substitute.For(); Feed = Substitute.For>(); - var stateDb = new MemDb(); + MemDb stateDb = new MemDb(); - SyncConfig syncConfig = new SyncConfig(); - SyncProgressResolver syncProgressResolver = new SyncProgressResolver( + SyncConfig syncConfig = new(); + SyncProgressResolver syncProgressResolver = new( BlockTree, NullReceiptStorage.Instance, stateDb, @@ -861,9 +888,9 @@ public Context() private class SyncPeerMock : ISyncPeer { private readonly bool _withReceipts; - private readonly BlockHeadersMessageSerializer _headersSerializer = new BlockHeadersMessageSerializer(); - private readonly BlockBodiesMessageSerializer _bodiesSerializer = new BlockBodiesMessageSerializer(); - private readonly ReceiptsMessageSerializer _receiptsSerializer = new ReceiptsMessageSerializer(RopstenSpecProvider.Instance); + private readonly BlockHeadersMessageSerializer _headersSerializer = new(); + private readonly BlockBodiesMessageSerializer _bodiesSerializer = new(); + private readonly ReceiptsMessageSerializer _receiptsSerializer = new(RopstenSpecProvider.Instance); private IDb _blockInfoDb = new MemDb(); public BlockTree BlockTree { get; private set; } @@ -881,7 +908,7 @@ public SyncPeerMock(long chainLength, bool withReceipts, Response flags) private void BuildTree(long chainLength, bool withReceipts) { _receiptStorage = new InMemoryReceiptStorage(); - var builder = Build.A.BlockTree(); + BlockTreeBuilder builder = Build.A.BlockTree(); if (withReceipts) { builder = builder.WithTransactions(_receiptStorage, MainnetSpecProvider.Instance); @@ -926,7 +953,7 @@ public async Task GetBlockBodies(IList blockHashes, Cancell headers[i++] = BlockTree.FindBlock(blockHash, BlockTreeLookupOptions.None).Body; } - BlockBodiesMessage message = new BlockBodiesMessage(headers); + BlockBodiesMessage message = new(headers); byte[] messageSerialized = _bodiesSerializer.Serialize(message); return await Task.FromResult(_bodiesSerializer.Deserialize(messageSerialized).Bodies); } @@ -955,7 +982,7 @@ public async Task GetBlockHeaders(long number, int maxBlocks, int headers[i] = BlockTree.FindHeader(number + i, BlockTreeLookupOptions.None); } - BlockHeadersMessage message = new BlockHeadersMessage(headers); + BlockHeadersMessage message = new(headers); byte[] messageSerialized = _headersSerializer.Serialize(message); return await Task.FromResult(_headersSerializer.Deserialize(messageSerialized).BlockHeaders); } @@ -988,7 +1015,7 @@ public async Task GetReceipts(IList blockHash, Cancellati receipts[i++] = blockReceipts; } - ReceiptsMessage message = new ReceiptsMessage(receipts); + ReceiptsMessage message = new(receipts); byte[] messageSerialized = _receiptsSerializer.Serialize(message); return await Task.FromResult(_receiptsSerializer.Deserialize(messageSerialized).TxReceipts); } @@ -1059,17 +1086,17 @@ public async Task BuildHeaderResponse(long startNumber, int numbe _headers[header.Hash] = header; } - BlockHeadersMessage message = new BlockHeadersMessage(headers); + BlockHeadersMessage message = new(headers); byte[] messageSerialized = _headersSerializer.Serialize(message); return await Task.FromResult(_headersSerializer.Deserialize(messageSerialized).BlockHeaders); } - private readonly BlockHeadersMessageSerializer _headersSerializer = new BlockHeadersMessageSerializer(); - private readonly BlockBodiesMessageSerializer _bodiesSerializer = new BlockBodiesMessageSerializer(); - private readonly ReceiptsMessageSerializer _receiptsSerializer = new ReceiptsMessageSerializer(RopstenSpecProvider.Instance); + private readonly BlockHeadersMessageSerializer _headersSerializer = new(); + private readonly BlockBodiesMessageSerializer _bodiesSerializer = new(); + private readonly ReceiptsMessageSerializer _receiptsSerializer = new(RopstenSpecProvider.Instance); - private Dictionary _headers = new Dictionary(); - private Dictionary _bodies = new Dictionary(); + private Dictionary _headers = new(); + private Dictionary _bodies = new(); public async Task BuildBlocksResponse(IList blockHashes, Response flags) { @@ -1127,7 +1154,7 @@ public async Task BuildBlocksResponse(IList blockHashes, Re } } - BlockBodiesMessage message = new BlockBodiesMessage(blockBodies); + BlockBodiesMessage message = new(blockBodies); byte[] messageSerialized = _bodiesSerializer.Serialize(message); return await Task.FromResult(_bodiesSerializer.Deserialize(messageSerialized).Bodies); } @@ -1152,7 +1179,7 @@ public async Task BuildReceiptsResponse(IList blockHashes : new ReceiptTrie(MainnetSpecProvider.Instance.GetSpec(_headers[blockHashes[i]].Number), receipts[i]).RootHash; } - ReceiptsMessage message = new ReceiptsMessage(receipts); + ReceiptsMessage message = new(receipts); byte[] messageSerialized = _receiptsSerializer.Serialize(message); return await Task.FromResult(_receiptsSerializer.Deserialize(messageSerialized).TxReceipts); } diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs index 631b44bc85e..67332005567 100644 --- a/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs +++ b/src/Nethermind/Nethermind.Synchronization/Blocks/BlockDownloader.cs @@ -48,6 +48,7 @@ internal class BlockDownloader : SyncDispatcher private readonly IReceiptsRecovery _receiptsRecovery; private readonly ISpecProvider _specProvider; private readonly ILogger _logger; + private readonly Random _rnd = new(); private bool _cancelDueToBetterPeer; private AllocationWithCancellation _allocationWithCancellation; @@ -494,6 +495,7 @@ private void ValidateSeals(BlockHeader?[] headers, CancellationToken cancellatio { if (_logger.IsTrace) _logger.Trace("Starting seal validation"); ConcurrentQueue exceptions = new(); + int randomNumberForValidation = _rnd.Next(Math.Max(0, headers.Length - 2)); Parallel.For(0, headers.Length, (i, state) => { if (cancellation.IsCancellationRequested) @@ -511,7 +513,8 @@ private void ValidateSeals(BlockHeader?[] headers, CancellationToken cancellatio try { - if (!_sealValidator.ValidateSeal(header, false)) + bool forceValidation = i == headers.Length - 1 || i == randomNumberForValidation; + if (!_sealValidator.ValidateSeal(header, forceValidation)) { if (_logger.IsTrace) _logger.Trace("One of the seals is invalid"); throw new EthSyncException("Peer sent a block with an invalid seal");