Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: standardized error responses for payload validation #7939

Merged
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
54 changes: 30 additions & 24 deletions src/Nethermind/Nethermind.Consensus/Messages/BlockErrorMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Int256;

namespace Nethermind.Consensus.Messages;
public static class BlockErrorMessages
Expand All @@ -13,8 +14,8 @@ public static string ExceededUncleLimit(int maxUncleCount) =>
public const string InsufficientMaxFeePerBlobGas =
"InsufficientMaxFeePerBlobGas: Not enough to cover blob gas fee.";

public const string InvalidLogsBloom =
"InvalidLogsBloom: Logs bloom in header does not match.";
public static string InvalidLogsBloom(Bloom expected, Bloom actual) =>
$"InvalidLogsBloom: Logs bloom in header does not match. Expected {expected}, got {actual}";

public static string InvalidTxRoot(Core.Crypto.Hash256 expected, Core.Crypto.Hash256 actual) =>
$"InvalidTxRoot: Expected {expected}, got {actual}";
Expand All @@ -34,20 +35,20 @@ public static string InvalidWithdrawalsRoot(Core.Crypto.Hash256 expected, Core.C
public const string WithdrawalsNotEnabled =
"WithdrawalsNotEnabled: Block body cannot have withdrawals.";

public const string InvalidReceiptsRoot =
"InvalidReceiptsRoot: Receipts root in header does not match.";
public static string InvalidReceiptsRoot(Hash256 expected, Hash256 actual) =>
$"InvalidReceiptsRoot: Receipts root in header does not match. Expected {expected}, got {actual}";

public const string InvalidStateRoot =
"InvalidStateRoot: State root in header does not match.";
public static string InvalidStateRoot(Hash256 expected, Core.Crypto.Hash256 actual) =>
$"InvalidStateRoot: State root in header does not match. Expected {expected}, got {actual}";

public const string InvalidParentBeaconBlockRoot =
"InvalidParentBeaconBlockRoot: Beacon block root in header does not match.";
public static string InvalidParentBeaconBlockRoot(Hash256 expected, Hash256 actual) =>
$"InvalidParentBeaconBlockRoot: Beacon block root in header does not match. Expected {expected}, got {actual}";

public const string BlobGasPriceOverflow =
"BlobGasPriceOverflow: Overflow in excess blob gas.";

public const string InvalidHeaderHash =
"InvalidHeaderHash: Header hash does not match.";
public static string InvalidHeaderHash(Hash256 expected, Hash256 actual) =>
$"InvalidHeaderHash: Header hash does not match. Expected {expected}, got {actual}";

public const string InvalidExtraData =
"InvalidExtraData: Extra data in header is not valid.";
Expand All @@ -73,8 +74,8 @@ public static string InvalidWithdrawalsRoot(Core.Crypto.Hash256 expected, Core.C
public const string InvalidBlockNumber =
"InvalidBlockNumber: Block number does not match the parent.";

public const string InvalidBaseFeePerGas =
"InvalidBaseFeePerGas: Does not match calculated.";
public static string InvalidBaseFeePerGas(UInt256? expected, UInt256 actual) =>
$"InvalidBaseFeePerGas: Does not match calculated. Expected {expected}, got {actual}";

public const string NotAllowedBlobGasUsed =
"NotAllowedBlobGasUsed: Cannot be set.";
Expand All @@ -91,19 +92,17 @@ public static string InvalidWithdrawalsRoot(Core.Crypto.Hash256 expected, Core.C
public static string InvalidTxInBlock(int i) =>
$"InvalidTxInBlock: Tx at index {i} in body.";

public const string HeaderGasUsedMismatch =
"HeaderGasUsedMismatch: Gas used in header does not match calculated.";
public static string HeaderGasUsedMismatch(long expected, long actual) =>
$"HeaderGasUsedMismatch: Gas used in header does not match calculated. Expected {expected}, got {actual}";

//Block's blob gas used in header is above the limit.
public static readonly string BlobGasUsedAboveBlockLimit =
$"BlockBlobGasExceeded: A block cannot have more than {Eip4844Constants.MaxBlobGasPerBlock} blob gas.";

//Block's excess blob gas in header is incorrect.
public const string IncorrectExcessBlobGas =
"HeaderExcessBlobGasMismatch: Excess blob gas in header does not match calculated.";
public static string IncorrectExcessBlobGas(ulong? expected, ulong? actual) =>
$"HeaderExcessBlobGasMismatch: Excess blob gas in header does not match calculated. Expected {expected}, got {actual}";

public const string HeaderBlobGasMismatch =
"HeaderBlobGasMismatch: Blob gas in header does not match calculated.";
public static string HeaderBlobGasMismatch(ulong? expected, ulong? actual) =>
$"HeaderBlobGasMismatch: Blob gas in header does not match calculated. Expected {expected}, got {actual}";

public const string InvalidTimestamp =
"InvalidTimestamp: Timestamp in header cannot be lower than ancestor.";
Expand All @@ -117,8 +116,15 @@ public static string InvalidTxInBlock(int i) =>
public const string NegativeGasUsed =
"NegativeGasUsed: Cannot be negative.";

public static string MissingRequests => "MissingRequests: Requests cannot be null in block when EIP-6110 or EIP-7002 are activated.";
public static string RequestsNotEnabled => "RequestsNotEnabled: Requests must be null in block when EIP-6110 and EIP-7002 are not activated.";
public static string InvalidRequestsHash(Hash256? expected, Hash256? actual) => $"InvalidRequestsHash: Requests hash hash mismatch in block: expected {expected}, got {actual}";
public static string InvalidRequestsOrder => "InvalidRequestsOrder: Requests are not in the correct order in block.";
public const string MissingRequests =
"MissingRequests: Requests cannot be null in block when EIP-6110 or EIP-7002 are activated.";

public const string RequestsNotEnabled =
"RequestsNotEnabled: Requests must be null in block when EIP-6110 and EIP-7002 are not activated.";

public static string InvalidRequestsHash(Hash256? expected, Hash256? actual) =>
$"InvalidRequestsHash: Requests hash hash mismatch in block: expected {expected}, got {actual}";

public const string InvalidRequestsOrder =
"InvalidRequestsOrder: Requests are not in the correct order in block.";
}
16 changes: 8 additions & 8 deletions src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,43 +173,43 @@ public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, B
if (processedBlock.Header.GasUsed != suggestedBlock.Header.GasUsed)
{
if (_logger.IsWarn) _logger.Warn($"- gas used: expected {suggestedBlock.Header.GasUsed}, got {processedBlock.Header.GasUsed} (diff: {processedBlock.Header.GasUsed - suggestedBlock.Header.GasUsed})");
error ??= BlockErrorMessages.HeaderGasUsedMismatch;
error ??= BlockErrorMessages.HeaderGasUsedMismatch(suggestedBlock.Header.GasUsed, processedBlock.Header.GasUsed);
}

if (processedBlock.Header.Bloom != suggestedBlock.Header.Bloom)
{
if (_logger.IsWarn) _logger.Warn($"- bloom: expected {suggestedBlock.Header.Bloom}, got {processedBlock.Header.Bloom}");
error ??= BlockErrorMessages.InvalidLogsBloom;
error ??= BlockErrorMessages.InvalidLogsBloom(suggestedBlock.Header.Bloom, processedBlock.Header.Bloom);
}

if (processedBlock.Header.ReceiptsRoot != suggestedBlock.Header.ReceiptsRoot)
{
if (_logger.IsWarn) _logger.Warn($"- receipts root: expected {suggestedBlock.Header.ReceiptsRoot}, got {processedBlock.Header.ReceiptsRoot}");
error ??= BlockErrorMessages.InvalidReceiptsRoot;
error ??= BlockErrorMessages.InvalidReceiptsRoot(suggestedBlock.Header.ReceiptsRoot, processedBlock.Header.ReceiptsRoot);
}

if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot)
{
if (_logger.IsWarn) _logger.Warn($"- state root: expected {suggestedBlock.Header.StateRoot}, got {processedBlock.Header.StateRoot}");
error ??= BlockErrorMessages.InvalidStateRoot;
error ??= BlockErrorMessages.InvalidStateRoot(suggestedBlock.Header.StateRoot, processedBlock.Header.StateRoot);
}

if (processedBlock.Header.BlobGasUsed != suggestedBlock.Header.BlobGasUsed)
{
if (_logger.IsWarn) _logger.Warn($"- blob gas used: expected {suggestedBlock.Header.BlobGasUsed}, got {processedBlock.Header.BlobGasUsed}");
error ??= BlockErrorMessages.HeaderBlobGasMismatch;
error ??= BlockErrorMessages.HeaderBlobGasMismatch(suggestedBlock.Header.BlobGasUsed, processedBlock.Header.BlobGasUsed);
}

if (processedBlock.Header.ExcessBlobGas != suggestedBlock.Header.ExcessBlobGas)
{
if (_logger.IsWarn) _logger.Warn($"- excess blob gas: expected {suggestedBlock.Header.ExcessBlobGas}, got {processedBlock.Header.ExcessBlobGas}");
error ??= BlockErrorMessages.IncorrectExcessBlobGas;
error ??= BlockErrorMessages.IncorrectExcessBlobGas(suggestedBlock.Header.ExcessBlobGas, processedBlock.Header.ExcessBlobGas);
}

if (processedBlock.Header.ParentBeaconBlockRoot != suggestedBlock.Header.ParentBeaconBlockRoot)
{
if (_logger.IsWarn) _logger.Warn($"- parent beacon block root : expected {suggestedBlock.Header.ParentBeaconBlockRoot}, got {processedBlock.Header.ParentBeaconBlockRoot}");
error ??= BlockErrorMessages.InvalidParentBeaconBlockRoot;
error ??= BlockErrorMessages.InvalidParentBeaconBlockRoot(suggestedBlock.Header.ParentBeaconBlockRoot, processedBlock.Header.ParentBeaconBlockRoot);
}

if (processedBlock.Header.RequestsHash != suggestedBlock.Header.RequestsHash)
Expand Down Expand Up @@ -346,7 +346,7 @@ protected virtual bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out

if (blobGasUsed != block.Header.BlobGasUsed)
{
error = BlockErrorMessages.HeaderBlobGasMismatch;
error = BlockErrorMessages.HeaderBlobGasMismatch(blobGasUsed, block.Header.BlobGasUsed);
if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} {nameof(BlockHeader.BlobGasUsed)} declared in the block header does not match actual blob gas used: {block.Header.BlobGasUsed} != {blobGasUsed}.");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private bool ValidateHash(BlockHeader header, ref string? error)
if (!hashAsExpected)
{
if (_logger.IsWarn) _logger.Warn($"Invalid block header ({header.Hash}) - invalid block hash");
error = BlockErrorMessages.InvalidHeaderHash;
error = BlockErrorMessages.InvalidHeaderHash(header.Hash, header.CalculateHash());
return false;
}

Expand Down Expand Up @@ -127,7 +127,7 @@ protected virtual bool Validate1559(BlockHeader header, BlockHeader parent, IRel
if (expectedBaseFee != header.BaseFeePerGas)
{
if (_logger.IsWarn) _logger.Warn($"Invalid block header ({header.ToString(BlockHeader.Format.Short)}) incorrect base fee. Expected base fee: {expectedBaseFee}, Current base fee: {header.BaseFeePerGas} ");
error = BlockErrorMessages.InvalidBaseFeePerGas;
error = BlockErrorMessages.InvalidBaseFeePerGas(expectedBaseFee, header.BaseFeePerGas);
return false;
}
}
Expand Down Expand Up @@ -357,7 +357,7 @@ protected virtual bool ValidateBlobGasFields(BlockHeader header, BlockHeader par
if (header.ExcessBlobGas != expectedExcessBlobGas)
{
if (_logger.IsWarn) _logger.Warn($"ExcessBlobGas field is incorrect: {header.ExcessBlobGas}, should be {expectedExcessBlobGas}.");
error = BlockErrorMessages.IncorrectExcessBlobGas;
error = BlockErrorMessages.IncorrectExcessBlobGas(expectedExcessBlobGas, header.ExcessBlobGas);
return false;
}
}
Expand Down
Loading