diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs index 16b32069194..6a513856fd8 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/HeaderValidatorTests.cs @@ -258,5 +258,35 @@ public void When_gas_limit_is_long_max_value() Assert.True(result); } + + [Test] + public void When_block_number_is_negative() + { + _block.Header.Number = -1; + _block.Header.Hash = _block.CalculateHash(); + + bool result = _validator.Validate(_block.Header); + Assert.False(result); + } + + [Test] + public void When_gas_used_is_negative() + { + _block.Header.GasUsed = -1; + _block.Header.Hash = _block.CalculateHash(); + + bool result = _validator.Validate(_block.Header); + Assert.False(result); + } + + [Test] + public void When_gas_limit_is_negative() + { + _block.Header.GasLimit = -1; + _block.Header.Hash = _block.CalculateHash(); + + bool result = _validator.Validate(_block.Header); + Assert.False(result); + } } } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs index 78f27dc2669..f14facce0d2 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/HeaderValidator.cs @@ -63,6 +63,11 @@ public HeaderValidator( /// public virtual bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) { + if (!ValidateFieldLimit(header)) + { + return false; + } + bool hashAsExpected = ValidateHash(header); if (!hashAsExpected) @@ -148,6 +153,33 @@ public virtual bool Validate(BlockHeader header, BlockHeader? parent, bool isUnc extraDataValid && eip1559Valid; } + + private bool ValidateFieldLimit(BlockHeader blockHeader) + { + // Note, these are out of spec. Technically, there could be a block with field with very high value that is + // valid when using ulong, but wrapped to negative value when using long. However, switching to ulong + // at this point can cause other unexpected error. So we just won't support it for now. + if (blockHeader.Number < 0) + { + if (_logger.IsWarn) _logger.Warn($"Invalid block header ({blockHeader.Hash}) - Block number is negative {blockHeader.Number}"); + return false; + } + + if (blockHeader.GasLimit < 0) + { + if (_logger.IsWarn) _logger.Warn($"Invalid block header ({blockHeader.Hash}) - Block GasLimit is negative {blockHeader.GasLimit}"); + return false; + } + + if (blockHeader.GasUsed < 0) + { + if (_logger.IsWarn) _logger.Warn($"Invalid block header ({blockHeader.Hash}) - Block GasUsed is negative {blockHeader.GasUsed}"); + return false; + } + + return true; + } + protected virtual bool ValidateExtraData(BlockHeader header, BlockHeader? parent, IReleaseSpec spec, bool isUncle = false) { bool extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize