Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,41 +189,44 @@ private static IEnumerable<TestCaseData> BadSuggestedBlocks()
BlockHeader parent = Build.A.BlockHeader.TestObject;

yield return new TestCaseData(
Build.A.Block.WithHeader(Build.A.BlockHeader.WithParent(parent).WithUnclesHash(Keccak.Zero).TestObject).TestObject,
parent,
Substitute.For<ISpecProvider>(),
"InvalidUnclesHash");
Build.A.Block.WithHeader(Build.A.BlockHeader.WithParent(parent).WithUnclesHash(Keccak.Zero).TestObject)
.TestObject,
parent,
Substitute.For<ISpecProvider>(),
"InvalidUnclesHash");

yield return new TestCaseData(
Build.A.Block.WithHeader(Build.A.BlockHeader.WithParent(parent).WithTransactionsRoot(Keccak.Zero).TestObject).TestObject,
parent,
Substitute.For<ISpecProvider>(),
"InvalidTxRoot");
Build.A.Block
.WithHeader(Build.A.BlockHeader.WithParent(parent).WithTransactionsRoot(Keccak.Zero).TestObject)
.TestObject,
parent,
Substitute.For<ISpecProvider>(),
"InvalidTxRoot");

yield return new TestCaseData(
Build.A.Block.WithBlobGasUsed(131072)
.WithParent(parent)
.WithExcessBlobGas(1)
.WithTransactions(
Build.A.Transaction.WithShardBlobTxTypeAndFields(1)
.WithMaxFeePerBlobGas(0)
.WithMaxFeePerGas(1000000)
.Signed()
.TestObject)
.TestObject,
parent,
new CustomSpecProvider(((ForkActivation)0, Cancun.Instance)),
"InsufficientMaxFeePerBlobGas");
Build.A.Block.WithBlobGasUsed(131072)
.WithParent(parent)
.WithExcessBlobGas(1)
.WithTransactions(
Build.A.Transaction.WithShardBlobTxTypeAndFields(1)
.WithMaxFeePerBlobGas(0)
.WithMaxFeePerGas(1000000)
.Signed()
.TestObject)
.TestObject,
parent,
new CustomSpecProvider(((ForkActivation)0, Cancun.Instance)),
"InsufficientMaxFeePerBlobGas");

yield return new TestCaseData(
Build.A.Block.WithParent(parent).WithEncodedSize(Eip7934Constants.DefaultMaxRlpBlockSize + 1).TestObject,
parent,
new CustomSpecProvider(((ForkActivation)0, Osaka.Instance)),
"ExceededBlockSizeLimit");
Build.A.Block.WithParent(parent).WithEncodedSize(Eip7934Constants.DefaultMaxRlpBlockSize + 1).TestObject,
parent,
new CustomSpecProvider(((ForkActivation)0, Osaka.Instance)),
"ExceededBlockSizeLimit");
}

[TestCaseSource(nameof(BadSuggestedBlocks))]
public void ValidateSuggestedBlock_SuggestedBlockIsInvalid_CorrectErrorIsSet(Block suggestedBlock, BlockHeader? parent, ISpecProvider specProvider, string expectedError)
public void ValidateSuggestedBlock_SuggestedBlockIsInvalid_CorrectErrorIsSet(Block suggestedBlock, BlockHeader parent, ISpecProvider specProvider, string expectedError)
{
TxValidator txValidator = new(TestBlockchainIds.ChainId);
BlockValidator sut = new(txValidator, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ public static bool Blob_gas_fields_should_be_set(IReleaseSpec spec, ulong? blobG
HeaderValidator headerValidator = new(Substitute.For<IBlockTree>(), Always.Valid, specProvider, TestLogManager.Instance);
BlockValidator blockValidator = new(Always.Valid, headerValidator, Always.Valid, specProvider, TestLogManager.Instance);
BlockHeader parent = Build.A.BlockHeader.TestObject;
return blockValidator.ValidateSuggestedBlock(Build.A.Block
.WithBlobGasUsed(blobGasUsed)
.WithExcessBlobGas(excessBlobGas)
.WithWithdrawalsRoot(TestItem.KeccakA)
.WithWithdrawals(TestItem.WithdrawalA_1Eth)
.WithParent(parent)
.TestObject,
return blockValidator.ValidateSuggestedBlock(
Build.A.Block
.WithBlobGasUsed(blobGasUsed)
.WithExcessBlobGas(excessBlobGas)
.WithWithdrawalsRoot(TestItem.KeccakA)
.WithWithdrawals(TestItem.WithdrawalA_1Eth)
.WithParent(parent)
.TestObject,
parent,
out _);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,70 +1,30 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Nethermind.Consensus.Validators;
using Nethermind.Core;

namespace Nethermind.Blockchain.Test.Validators;

public class TestBlockValidator : IBlockValidator
public class TestBlockValidator(bool suggestedValidationResult = true) : IBlockValidator
{
public static TestBlockValidator AlwaysValid = new();
public static TestBlockValidator NeverValid = new(false, false);
private readonly Queue<bool> _processedValidationResults = null!;
private readonly Queue<bool> _suggestedValidationResults = null!;
private readonly bool? _alwaysSameResultForProcessed;
private readonly bool? _alwaysSameResultForSuggested;
private readonly bool? _alwaysSameResultForSuggested = suggestedValidationResult;

public TestBlockValidator(bool suggestedValidationResult = true, bool processedValidationResult = true)
{
_alwaysSameResultForSuggested = suggestedValidationResult;
_alwaysSameResultForProcessed = processedValidationResult;
}

public TestBlockValidator(Queue<bool> suggestedValidationResults, Queue<bool> processedValidationResults)
{
_suggestedValidationResults = suggestedValidationResults ?? throw new ArgumentNullException(nameof(suggestedValidationResults));
_processedValidationResults = processedValidationResults ?? throw new ArgumentNullException(nameof(processedValidationResults));
}

public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle, [NotNullWhen(false)] out string? error)
public bool Validate(BlockHeader header, BlockHeader parent, bool isUncle, [NotNullWhen(false)] out string? error) => Validate(out error);
public bool ValidateOrphaned(BlockHeader header, [NotNullWhen(false)] out string? error) => Validate(out error);
public bool ValidateSuggestedBlock(Block block, BlockHeader parent, [NotNullWhen(false)] out string? error, bool validateHashes = true) => Validate(out error);
public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, [NotNullWhen(false)] out string? error) => Validate(out error);
public bool ValidateWithdrawals(Block block, out string? error) => Validate(out error);
public bool ValidateOrphanedBlock(Block block, [NotNullWhen(false)] out string? error) => Validate(out error);
public bool ValidateBodyAgainstHeader(BlockHeader header, BlockBody toBeValidated, [NotNullWhen(false)] out string? error) => Validate(out error);
private bool Validate(out string? error)
{
var result = _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
error = result ? null : "";
return result;
}

public bool ValidateSuggestedBlock(Block block, BlockHeader? parent, [NotNullWhen(false)] out string? error, bool validateHashes = true)
{
error = null;
return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}

public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, [NotNullWhen(false)] out string? error)
{
error = null;
return _alwaysSameResultForProcessed ?? _processedValidationResults.Dequeue();
}

public bool ValidateWithdrawals(Block block, out string? error)
{
error = null;

return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}

public bool ValidateOrphanedBlock(Block block, [NotNullWhen(false)] out string? error)
{
error = null;
return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}

public bool ValidateBodyAgainstHeader(BlockHeader header, BlockBody toBeValidated, [NotNullWhen(false)] out string? errorMessage)
{
errorMessage = null;
return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}
}
21 changes: 9 additions & 12 deletions src/Nethermind/Nethermind.Consensus.Clique/CliqueSealValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,21 @@

namespace Nethermind.Consensus.Clique
{
internal class CliqueSealValidator : ISealValidator
internal class CliqueSealValidator(
ICliqueConfig cliqueConfig,
ISnapshotManager snapshotManager,
ILogManager logManager)
: ISealValidator
{
private readonly ICliqueConfig _cliqueConfig;
private readonly ISnapshotManager _snapshotManager;
private readonly ILogger _logger;

public CliqueSealValidator(ICliqueConfig cliqueConfig, ISnapshotManager snapshotManager, ILogManager logManager)
{
_cliqueConfig = cliqueConfig ?? throw new ArgumentNullException(nameof(cliqueConfig));
_snapshotManager = snapshotManager ?? throw new ArgumentNullException(nameof(snapshotManager));
_logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
}
private readonly ICliqueConfig _cliqueConfig = cliqueConfig ?? throw new ArgumentNullException(nameof(cliqueConfig));
private readonly ISnapshotManager _snapshotManager = snapshotManager ?? throw new ArgumentNullException(nameof(snapshotManager));
private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle = false)
{
long number = header.Number;
// Retrieve the snapshot needed to validate this header and cache it
Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(number - 1, header.ParentHash);
Snapshot snapshot = _snapshotManager.GetOrCreateSnapshot(number - 1, header.ParentHash!);
// Resolve the authorization key and check against signers
header.Author ??= _snapshotManager.GetBlockSealer(header);
Address signer = header.Author;
Expand Down
50 changes: 50 additions & 0 deletions src/Nethermind/Nethermind.Consensus/Validators/Always.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.TxPool;

namespace Nethermind.Consensus.Validators;

public class Always : IBlockValidator, ISealValidator, IUnclesValidator, ITxValidator
{
private readonly bool _result;
private readonly ValidationResult _validationResult;

private Always(bool result)
{
_validationResult = result ? ValidationResult.Success : "Always invalid.";
_result = result;
}

// ReSharper disable once NotNullMemberIsNotInitialized
private static Always _valid;

public static Always Valid => LazyInitializer.EnsureInitialized(ref _valid, static () => new Always(true));

// ReSharper disable once NotNullMemberIsNotInitialized
private static Always _invalid;

public static Always Invalid => LazyInitializer.EnsureInitialized(ref _invalid, static () => new Always(false));

public bool Validate(BlockHeader header, BlockHeader parent, bool isUncle, out string? error) => Validate(out error);
public bool ValidateOrphaned(BlockHeader header, [NotNullWhen(false)] out string? error) => Validate(out error);
public bool ValidateParams(BlockHeader parent, BlockHeader header, bool isUncle = false) => Validate(out _);
public bool ValidateSeal(BlockHeader header, bool force) => Validate(out _);
public bool Validate(BlockHeader header, BlockHeader[] uncles) => Validate(out _);
public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec) => _validationResult;
public bool ValidateWithdrawals(Block block, out string? error) => Validate(out error);
public bool ValidateOrphanedBlock(Block block, out string? error) => Validate(out error);
public bool ValidateSuggestedBlock(Block block, BlockHeader parent, out string? error, bool validateHashes = true) => Validate(out error);
public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, out string? error) => Validate(out error);
public bool ValidateBodyAgainstHeader(BlockHeader header, BlockBody toBeValidated, [NotNullWhen(false)] out string? error) => Validate(out error);

private bool Validate(out string? error)
{
error = _result ? null : "Always invalid.";
return _result;
}
}
95 changes: 0 additions & 95 deletions src/Nethermind/Nethermind.Consensus/Validators/AlwaysValid.cs

This file was deleted.

Loading