Skip to content

Commit

Permalink
Add data gas calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
flcl42 committed Apr 26, 2023
1 parent 3801dd6 commit 2a52b0b
Show file tree
Hide file tree
Showing 69 changed files with 536 additions and 273 deletions.
4 changes: 2 additions & 2 deletions src/Nethermind/Chains/eip4844_local.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"params": {
"terminalTotalDifficulty": "2",
"terminalPowBlockNumber": 1,
"chainID": "1",
"networkID": "69",
"chainID": "7",
"networkID": "7",
"maximumExtraDataSize": "1000000",
"eip140Transition": "0x0",
"eip145Transition": "0x0",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageVersion Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="6.0.5" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.5" />
<PackageVersion Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.5" />
<PackageVersion Include="Ckzg.Bindings" Version="0.1.2.402" />
<PackageVersion Include="Ckzg.Bindings" Version="0.1.2.112" />
<PackageVersion Include="Colorful.Console" Version="1.2.15" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="ConcurrentHashSet" Version="1.3.0" />
Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
blockTree.SuggestBlock(genesisBlock);

genesisProcessed.WaitOne();

BlockHeader parentBlockHeader = genesisBlock.Header;
for (int i = 0; i < correctRlp.Count; i++)
{
stopwatch?.Start();
Expand All @@ -243,7 +243,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
}

// TODO: mimic the actual behaviour where block goes through validating sync manager?
if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlp[i].Block))
if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlp[i].Block, parentBlockHeader))
{
blockTree.SuggestBlock(correctRlp[i].Block);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ private IBlockValidator CreateBlockValidator()
headerValidator,
Always.Valid,
SpecProvider,
BlockTree,
LogManager);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public void Test()
stateProvider,
storageProvider,
virtualMachine,
blockTree,
LimboLogs.Instance);
BlockProcessor blockProcessor = new(
specProvider,
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public void Setup()
stateProvider,
storageProvider,
virtualMachine,
_blockTree,
LimboLogs.Instance);

BlockProcessor blockProcessor = new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public static IEnumerable EnoughShardBlobTransactionsSelectedTestCases
tx.BlobVersionedHashes = new byte[1][];
});
maxTransactionsSelected.Transactions[1].BlobVersionedHashes =
new byte[Eip4844Constants.MaxBlobsPerBlock - 1][];
new byte[Eip4844Constants.MaxDataGasPerTransaction / Eip4844Constants.DataGasPerBlob - 1][];
maxTransactionsSelected.ExpectedSelectedTransactions.AddRange(
maxTransactionsSelected.Transactions.OrderBy(t => t.Nonce).Take(2));
yield return new TestCaseData(maxTransactionsSelected).SetName("Enough transactions selected");
Expand All @@ -168,7 +168,8 @@ public static IEnumerable EnoughShardBlobTransactionsSelectedTestCases
Transaction[] expectedSelectedTransactions =
enoughTransactionsSelected.Transactions.OrderBy(t => t.Nonce).ToArray();
expectedSelectedTransactions[0].Type = TxType.Blob;
expectedSelectedTransactions[0].BlobVersionedHashes = new byte[Eip4844Constants.MaxBlobsPerBlock][];
expectedSelectedTransactions[0].BlobVersionedHashes =
new byte[Eip4844Constants.MaxDataGasPerTransaction / Eip4844Constants.DataGasPerBlob][];
expectedSelectedTransactions[1].Type = TxType.Blob;
expectedSelectedTransactions[1].BlobVersionedHashes = new byte[1][];
enoughTransactionsSelected.ExpectedSelectedTransactions.AddRange(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Nethermind.Consensus.Validators;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Logging;
using Nethermind.Specs;
Expand All @@ -23,11 +24,11 @@ public void When_more_uncles_than_allowed_returns_false()
releaseSpec.MaximumUncleCount = 0;
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, releaseSpec));

BlockValidator blockValidator = new(txValidator, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
bool noiseRemoved = blockValidator.ValidateSuggestedBlock(Build.A.Block.TestObject);
BlockValidator blockValidator = new(txValidator, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
bool noiseRemoved = blockValidator.ValidateSuggestedBlock(Build.A.Block.TestObject, Build.An.EmptyBlockHeader);
Assert.True(noiseRemoved);

bool result = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithUncles(Build.A.BlockHeader.TestObject).TestObject);
bool result = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithUncles(Build.A.BlockHeader.TestObject).TestObject, Build.An.EmptyBlockHeader);
Assert.False(result);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using Nethermind.Consensus.Validators;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Evm;
using Nethermind.Logging;
using Nethermind.Specs.Forks;
using Nethermind.Specs.Test;
Expand All @@ -18,40 +20,40 @@ public class ShardBlobBlockValidatorTests
public void Not_null_ExcessDataGas_is_invalid_pre_cancun()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Shanghai.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block
.WithWithdrawalsRoot(TestItem.KeccakA)
.WithWithdrawals(TestItem.WithdrawalA_1Eth)
.WithExcessDataGas(1).TestObject);
.WithExcessDataGas(1).TestObject, Build.An.EmptyBlockHeader);
Assert.False(isValid);
}

[Test]
public void Null_ExcessDataGas_is_invalid_post_cancun()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Cancun.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block
.WithWithdrawalsRoot(TestItem.KeccakA)
.WithWithdrawals(TestItem.WithdrawalA_1Eth)
.TestObject);
.TestObject, Build.An.EmptyBlockHeader);
Assert.False(isValid);
}

[TestCase(0, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerBlock - 1, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerBlock, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerBlock + 1, ExpectedResult = false)]
[TestCase(Eip4844Constants.MaxDataGasPerBlock / Eip4844Constants.DataGasPerBlob - 1, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxDataGasPerBlock / Eip4844Constants.DataGasPerBlob, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxDataGasPerBlock / Eip4844Constants.DataGasPerBlob + 1, ExpectedResult = false)]
public bool Blobs_per_block_count_is_valid(int blobsCount)
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Cancun.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
return blockValidator.ValidateSuggestedBlock(
Build.A.Block
.WithWithdrawalsRoot(TestItem.KeccakA)
.WithWithdrawals(TestItem.WithdrawalA_1Eth)
.WithExcessDataGas(1)
.WithExcessDataGas(IntrinsicGasCalculator.CalculateExcessDataGas(0, blobsCount, specProvider.GenesisSpec)!.Value)
.WithTransactions(Build.A.Transaction.WithBlobVersionedHashes(blobsCount).TestObject)
.TestObject);
.TestObject, Build.An.EmptyBlockHeader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public bool Validate(BlockHeader header, bool isUncle)
return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}

public bool ValidateSuggestedBlock(Block block)
public bool ValidateSuggestedBlock(Block block, BlockHeader? parentBlockHeader)
{
return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ public bool MaxFeePerDataGas_should_be_set_for_blob_tx_only(TxType txType, bool
[TestCase(Eip4844Constants.MinBlobsPerTransaction - 1, ExpectedResult = false)]
[TestCase(Eip4844Constants.MinBlobsPerTransaction, ExpectedResult = true)]
[TestCase(Eip4844Constants.MinBlobsPerTransaction + 1, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerTransaction - 1, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerTransaction, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxBlobsPerTransaction + 1, ExpectedResult = false)]
[TestCase(Eip4844Constants.MaxDataGasPerTransaction / Eip4844Constants.DataGasPerBlob - 1, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxDataGasPerTransaction / Eip4844Constants.DataGasPerBlob, ExpectedResult = true)]
[TestCase(Eip4844Constants.MaxDataGasPerTransaction / Eip4844Constants.DataGasPerBlob + 1, ExpectedResult = false)]
public bool Blobs_count_should_be_within_constraints(int blobsCount)
{
byte[] sigData = new byte[65];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Logging;
using Nethermind.Specs.Forks;
Expand All @@ -20,50 +21,50 @@ public class WithdrawalValidatorTests
public void Not_null_withdrawals_are_invalid_pre_shanghai()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, London.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(new Withdrawal[] { TestItem.WithdrawalA_1Eth, TestItem.WithdrawalB_2Eth }).TestObject);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(new Withdrawal[] { TestItem.WithdrawalA_1Eth, TestItem.WithdrawalB_2Eth }).TestObject, Build.An.EmptyBlockHeader);
Assert.False(isValid);
}

[Test, Timeout(Timeout.MaxTestTime)]
public void Null_withdrawals_are_invalid_post_shanghai()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Shanghai.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.TestObject);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.TestObject, Build.An.EmptyBlockHeader);
Assert.False(isValid);
}

[Test, Timeout(Timeout.MaxTestTime)]
public void Withdrawals_with_incorrect_withdrawals_root_are_invalid()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Shanghai.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
Withdrawal[] withdrawals = { TestItem.WithdrawalA_1Eth, TestItem.WithdrawalB_2Eth };
Keccak withdrawalRoot = new WithdrawalTrie(withdrawals).RootHash;
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(TestItem.KeccakD).TestObject);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(TestItem.KeccakD).TestObject, Build.An.EmptyBlockHeader);
Assert.False(isValid);
}

[Test, Timeout(Timeout.MaxTestTime)]
public void Empty_withdrawals_are_valid_post_shanghai()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Shanghai.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
Withdrawal[] withdrawals = { };
Keccak withdrawalRoot = new WithdrawalTrie(withdrawals).RootHash;
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(withdrawalRoot).TestObject);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(withdrawalRoot).TestObject, Build.An.EmptyBlockHeader);
Assert.True(isValid);
}

[Test, Timeout(Timeout.MaxTestTime)]
public void Correct_withdrawals_block_post_shanghai()
{
ISpecProvider specProvider = new CustomSpecProvider(((ForkActivation)0, Shanghai.Instance));
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, LimboLogs.Instance);
BlockValidator blockValidator = new(Always.Valid, Always.Valid, Always.Valid, specProvider, NullBlockFinder.Instance, LimboLogs.Instance);
Withdrawal[] withdrawals = { TestItem.WithdrawalA_1Eth, TestItem.WithdrawalB_2Eth };
Keccak withdrawalRoot = new WithdrawalTrie(withdrawals).RootHash;
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(withdrawalRoot).TestObject);
bool isValid = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithWithdrawals(withdrawals).WithWithdrawalsRoot(withdrawalRoot).TestObject, Build.An.EmptyBlockHeader);
Assert.True(isValid);
}
}
6 changes: 6 additions & 0 deletions src/Nethermind/Nethermind.Blockchain/BlockTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Nethermind.Serialization.Rlp;
using Nethermind.State.Repositories;
using Nethermind.Db.Blooms;
using Nethermind.Evm.TransactionProcessing;

namespace Nethermind.Blockchain
{
Expand Down Expand Up @@ -2098,5 +2099,10 @@ public void ForkChoiceUpdated(Keccak? finalizedBlockHash, Keccak? safeBlockHash)
_metadataDb.Set(MetadataDbKeys.SafeBlockHash, Rlp.Encode(SafeHash!).Bytes);
}
}

BlockHeader? IParentBlockHeaderFinder.FindParentHeader(BlockHeader block) =>
this.FindParentHeader(block,
BlockTreeLookupOptions.TotalDifficultyNotNeeded | BlockTreeLookupOptions.DoNotCreateLevelIfMissing |
BlockTreeLookupOptions.AllowInvalid);
}
}
3 changes: 2 additions & 1 deletion src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
using System;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Evm.TransactionProcessing;

namespace Nethermind.Blockchain.Find
{
public interface IBlockFinder
public interface IBlockFinder : IParentBlockHeaderFinder
{
Keccak HeadHash { get; }

Expand Down
7 changes: 7 additions & 0 deletions src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Visitors;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Int256;

namespace Nethermind.Blockchain
Expand Down Expand Up @@ -198,5 +200,10 @@ IEnumerable<BlockHeader> GetPotentiallyCorruptedBlocks(long start)
public void UpdateMainChain(IReadOnlyList<Block> blocks, bool wereProcessed, bool forceHeadBlock = false) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(UpdateMainChain)} calls");

public void ForkChoiceUpdated(Keccak? finalizedBlockHash, Keccak? safeBlockBlockHash) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(ForkChoiceUpdated)} calls");

BlockHeader? IParentBlockHeaderFinder.FindParentHeader(BlockHeader block) =>
this.FindParentHeader(block,
BlockTreeLookupOptions.TotalDifficultyNotNeeded | BlockTreeLookupOptions.DoNotCreateLevelIfMissing |
BlockTreeLookupOptions.AllowInvalid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
using Nethermind.Consensus.Rewards;
using Nethermind.Consensus.Transactions;
using Nethermind.Consensus.Validators;
using Nethermind.Consensus.Withdrawals;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
Expand All @@ -37,7 +36,6 @@
using Nethermind.Trie.Pruning;
using Nethermind.TxPool;
using NUnit.Framework;
using BlockTree = Nethermind.Blockchain.BlockTree;
using Nethermind.Config;

namespace Nethermind.Clique.Test
Expand Down Expand Up @@ -124,7 +122,9 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
_genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash();

StorageProvider storageProvider = new(trieStore, stateProvider, nodeLogManager);
TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider, storageProvider, new VirtualMachine(blockhashProvider, specProvider, nodeLogManager), nodeLogManager);
TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider, storageProvider,
new VirtualMachine(blockhashProvider, specProvider, nodeLogManager), blockTree,
nodeLogManager);
BlockProcessor blockProcessor = new(
goerliSpecProvider,
Always.Valid,
Expand All @@ -144,7 +144,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
StateProvider minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager);
StorageProvider minerStorageProvider = new(minerTrieStore, minerStateProvider, nodeLogManager);
VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, nodeLogManager);
TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);
TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerStorageProvider, minerVirtualMachine, blockTree, nodeLogManager);

BlockProcessor minerBlockProcessor = new(
goerliSpecProvider,
Expand Down
Loading

0 comments on commit 2a52b0b

Please sign in to comment.