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

Fix/check withdrawal bodiessyncfeed #6345

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
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

using Nethermind.Consensus.Validators;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.Specs.Test;
using NSubstitute;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test.Validators
Expand All @@ -30,5 +32,61 @@ public void When_more_uncles_than_allowed_returns_false()
bool result = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithUncles(Build.A.BlockHeader.TestObject).TestObject);
Assert.False(result);
}

[Test]
public void ValidateBodyAgainstHeader_BlockIsValid_ReturnsTrue()
{
Block block = Build.A.Block
.WithTransactions(1, Substitute.For<IReleaseSpec>())
.WithWithdrawals(1)
.TestObject;

Assert.That(
BlockValidator.ValidateBodyAgainstHeader(block.Header, block.Body),
Is.True);
}

[Test]
public void ValidateBodyAgainstHeader_BlockHasInvalidTxRoot_ReturnsFalse()
{
Block block = Build.A.Block
.WithTransactions(1, Substitute.For<IReleaseSpec>())
.WithWithdrawals(1)
.TestObject;
block.Header.TxRoot = Keccak.OfAnEmptyString;

Assert.That(
BlockValidator.ValidateBodyAgainstHeader(block.Header, block.Body),
Is.False);
}


[Test]
public void ValidateBodyAgainstHeader_BlockHasInvalidUnclesRoot_ReturnsFalse()
{
Block block = Build.A.Block
.WithTransactions(1, Substitute.For<IReleaseSpec>())
.WithWithdrawals(1)
.TestObject;
block.Header.UnclesHash = Keccak.OfAnEmptyString;

Assert.That(
BlockValidator.ValidateBodyAgainstHeader(block.Header, block.Body),
Is.False);
}

[Test]
public void ValidateBodyAgainstHeader_BlockHasInvalidWithdrawalsRoot_ReturnsFalse()
{
Block block = Build.A.Block
.WithTransactions(1, Substitute.For<IReleaseSpec>())
.WithWithdrawals(1)
.TestObject;
block.Header.WithdrawalsRoot = Keccak.OfAnEmptyString;

Assert.That(
BlockValidator.ValidateBodyAgainstHeader(block.Header, block.Body),
Is.False);
}
}
}
35 changes: 27 additions & 8 deletions src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,28 +306,47 @@ private bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out string? e
return true;
}

public static bool ValidateBodyAgainstHeader(BlockHeader header, BlockBody toBeValidated) =>
ValidateTxRootMatchesTxs(header, toBeValidated, out _) &&
ValidateUnclesHashMatches(header, toBeValidated, out _) &&
ValidateWithdrawalsHashMatches(header, toBeValidated, out _);

public static bool ValidateTxRootMatchesTxs(Block block, out Hash256 txRoot)
{
txRoot = new TxTrie(block.Transactions).RootHash;
return txRoot == block.Header.TxRoot;
return ValidateTxRootMatchesTxs(block.Header, block.Body, out txRoot);
}
public static bool ValidateTxRootMatchesTxs(BlockHeader header, BlockBody body, out Hash256 txRoot)
{
txRoot = new TxTrie(body.Transactions).RootHash;
return txRoot == header.TxRoot;
}

public static bool ValidateUnclesHashMatches(Block block, out Hash256 unclesHash)
{
unclesHash = UnclesHash.Calculate(block);
return ValidateUnclesHashMatches(block.Header, block.Body, out unclesHash);
}

return block.Header.UnclesHash == unclesHash;
public static bool ValidateUnclesHashMatches(BlockHeader header, BlockBody body, out Hash256 unclesHash)
{
unclesHash = UnclesHash.Calculate(body.Uncles);

return header.UnclesHash == unclesHash;
}

public static bool ValidateWithdrawalsHashMatches(Block block, out Hash256? withdrawalsRoot)
{
return ValidateWithdrawalsHashMatches(block.Header, block.Body, out withdrawalsRoot);
}

public static bool ValidateWithdrawalsHashMatches(BlockHeader header, BlockBody body, out Hash256? withdrawalsRoot)
{
withdrawalsRoot = null;
if (block.Withdrawals == null)
return block.Header.WithdrawalsRoot == null;
if (body.Withdrawals == null)
return header.WithdrawalsRoot == null;

withdrawalsRoot = new WithdrawalTrie(block.Withdrawals).RootHash;
withdrawalsRoot = new WithdrawalTrie(body.Withdrawals).RootHash;

return block.Header.WithdrawalsRoot == withdrawalsRoot;
return header.WithdrawalsRoot == withdrawalsRoot;
}

private static string Invalid(Block block) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Consensus.Validators;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
Expand Down Expand Up @@ -193,10 +194,7 @@ public override SyncResponseHandlingResult HandleResponse(BodiesSyncBatch? batch
private bool TryPrepareBlock(BlockInfo blockInfo, BlockBody blockBody, out Block? block)
{
BlockHeader header = _blockTree.FindHeader(blockInfo.BlockHash, blockNumber: blockInfo.BlockNumber);
Hash256 rootHash = TxTrie.CalculateRoot(blockBody.Transactions);
bool txRootIsValid = rootHash == header.TxRoot;
bool unclesHashIsValid = UnclesHash.Calculate(blockBody.Uncles) == header.UnclesHash;
if (txRootIsValid && unclesHashIsValid)
if (BlockValidator.ValidateBodyAgainstHeader(header, blockBody))
{
block = new Block(header, blockBody);
}
Expand Down