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

EIP-2935: Save historical block hashes in state #6925

Merged
merged 45 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
60608c9
add params for eip2935
tanishqjasoria Apr 12, 2024
3751349
Add handler
tanishqjasoria Apr 12, 2024
1cb6d54
Add block tree to block processor
tanishqjasoria Apr 12, 2024
edac2d4
Add init thing
tanishqjasoria Apr 12, 2024
c06bd4c
refactor
tanishqjasoria Apr 16, 2024
87d724c
use block hash from state
tanishqjasoria Apr 17, 2024
7677f1b
refactor for simpler tests
tanishqjasoria Apr 17, 2024
9c8483a
remove tracer
tanishqjasoria Apr 17, 2024
f8ce7de
add block hash to v3 test
tanishqjasoria Apr 17, 2024
9aed996
reafc
tanishqjasoria Apr 17, 2024
b2d14d7
query from handler also - how to get this in evm?
tanishqjasoria Apr 17, 2024
7183f99
query from handler in vm
tanishqjasoria Apr 18, 2024
7a600e7
modify blockHash provider instead
tanishqjasoria Apr 19, 2024
ed9a04e
account for null
tanishqjasoria Apr 19, 2024
da2c3e7
fix errors
tanishqjasoria Apr 19, 2024
30f48d2
add one test
tanishqjasoria Apr 19, 2024
e71bf5c
whitespace
tanishqjasoria Apr 19, 2024
00df46d
add test to check correct implementation is being used
tanishqjasoria Apr 19, 2024
00f7248
fix other solutions
tanishqjasoria Apr 19, 2024
96d5e02
update test
tanishqjasoria Apr 19, 2024
88047c3
whitespaces
tanishqjasoria Apr 19, 2024
0e55089
cosmetic
MarekM25 Apr 22, 2024
374607a
fix constants
tanishqjasoria Apr 22, 2024
619972c
get block hash
tanishqjasoria Apr 22, 2024
52ddf96
fix get block hash
tanishqjasoria Apr 22, 2024
aa72dc9
eip clarification
tanishqjasoria Apr 23, 2024
69657fd
consolidate the interfaces
tanishqjasoria Apr 25, 2024
5eafc8d
refactor
tanishqjasoria Apr 25, 2024
83134c4
Refac
tanishqjasoria Apr 25, 2024
40ebcfc
fix benchmarks and ethereum tests
tanishqjasoria Apr 25, 2024
f044dfe
fix ethereum tests
tanishqjasoria Apr 25, 2024
69f2194
cleanup
tanishqjasoria Apr 25, 2024
60b0b11
fix empty check
tanishqjasoria Apr 25, 2024
6ff6046
use block finder instead
tanishqjasoria May 1, 2024
e51a39d
move everything to blockHashStore
tanishqjasoria May 1, 2024
efbe0a8
refactor the blockHashStore
tanishqjasoria May 1, 2024
d0d1dbb
Parallelize the tests
tanishqjasoria May 1, 2024
fc31145
refactor the interface
tanishqjasoria May 1, 2024
715dbdc
whitespace
tanishqjasoria May 1, 2024
6122e25
fix other tests
tanishqjasoria May 1, 2024
831cc60
whitespace
tanishqjasoria May 1, 2024
911b07f
update test
tanishqjasoria May 3, 2024
7ccf3f2
remove redundant check
tanishqjasoria May 3, 2024
d7ceca4
update
tanishqjasoria May 3, 2024
0493860
Merge branch 'master' into eip-2935
MarekM25 May 7, 2024
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
4 changes: 3 additions & 1 deletion src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading;
using System.Threading.Tasks;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Consensus;
Expand Down Expand Up @@ -142,7 +143,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager);

IReceiptStorage receiptStorage = NullReceiptStorage.Instance;
IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager);
IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, specProvider, stateProvider, _logManager);
ITxValidator txValidator = new TxValidator(TestBlockchainIds.ChainId);
IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager);
Expand All @@ -166,6 +167,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
stateProvider,
receiptStorage,
NullWitnessCollector.Instance,
new BlockhashStore(blockTree, specProvider, stateProvider),
_logManager);

IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Nethermind.AccountAbstraction.Executor;
using Nethermind.AccountAbstraction.Source;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Contracts.Json;
using Nethermind.Consensus;
using Nethermind.Consensus.Comparers;
Expand Down Expand Up @@ -190,6 +191,7 @@ protected override BlockProcessor CreateBlockProcessor()
State,
ReceiptStorage,
NullWitnessCollector.Instance,
new BlockhashStore(BlockTree, SpecProvider, State),
LogManager);

AbiParameterConverter.RegisterFactory(new AbiTypeFactory(new AbiTuple<UserOperationAbi>()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using System.Threading.Tasks;
using System.Threading;
using FluentAssertions;
using Nethermind.Blockchain.Blocks;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Rewards;
using Nethermind.Core.Test.Blockchain;
Expand All @@ -49,6 +50,7 @@ public void Prepared_block_contains_author_field()
stateProvider,
NullReceiptStorage.Instance,
NullWitnessCollector.Instance,
Substitute.For<IBlockhashStore>(),
LimboLogs.Instance);

BlockHeader header = Build.A.BlockHeader.WithAuthor(TestItem.AddressD).TestObject;
Expand Down Expand Up @@ -80,6 +82,7 @@ public void Can_store_a_witness()
stateProvider,
NullReceiptStorage.Instance,
witnessCollector,
Substitute.For<IBlockhashStore>(),
LimboLogs.Instance);

BlockHeader header = Build.A.BlockHeader.WithAuthor(TestItem.AddressD).TestObject;
Expand Down Expand Up @@ -109,6 +112,7 @@ public void Recovers_state_on_cancel()
stateProvider,
NullReceiptStorage.Instance,
NullWitnessCollector.Instance,
Substitute.For<IBlockhashStore>(),
LimboLogs.Instance);

BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithAuthor(TestItem.AddressD).TestObject;
Expand Down
128 changes: 103 additions & 25 deletions src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Find;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Db;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.Specs.Forks;
using Nethermind.Specs.Test;
using Nethermind.State;
using Nethermind.Trie.Pruning;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test
{
[TestFixture]
[TestFixture, Parallelizable(ParallelScope.All)]
public class BlockhashProviderTests
{
private static IWorldState CreateWorldState()
{
var trieStore = new TrieStore(new MemDb(), LimboLogs.Instance);
var worldState = new WorldState(trieStore, new MemDb(), LimboLogs.Instance);
worldState.CreateAccount(Eip2935Constants.BlockHashHistoryAddress, 0, 1);
worldState.Commit(Frontier.Instance);
return worldState;
}
private static BlockhashProvider CreateBlockHashProvider(IBlockFinder tree, IReleaseSpec spec)
{
IWorldState worldState = CreateWorldState();
BlockhashProvider provider = new(tree, new TestSpecProvider(spec), worldState, LimboLogs.Instance);
return provider;
}

[Test, Timeout(Timeout.MaxTestTime)]
public void Can_get_parent_only_headers()
{
Expand All @@ -21,10 +45,10 @@ public void Can_get_parent_only_headers()

BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None);
Block current = Build.A.Block.WithParent(head!).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1);
Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1);
Assert.That(result, Is.EqualTo(head?.Hash));
}

Expand All @@ -36,10 +60,10 @@ public void Can_lookup_up_to_256_before_with_headers_only()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256);
Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256);
Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash));
}

Expand All @@ -51,10 +75,10 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
Block current = Build.A.Block.WithParent(headBlock).TestObject;
long lookupNumber = chainLength - 256;
Hash256 result = provider.GetBlockhash(current.Header, lookupNumber);
Hash256? result = provider.GetBlockhash(current.Header, lookupNumber);
Assert.NotNull(result);
}

Expand All @@ -66,12 +90,12 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
Block current = Build.A.Block.WithParent(headBlock).TestObject;
tree.SuggestBlock(current);
tree.UpdateMainChain(current);
long lookupNumber = chainLength - 256;
Hash256 result = provider.GetBlockhash(current.Header, lookupNumber);
Hash256? result = provider.GetBlockhash(current.Header, lookupNumber);
Assert.NotNull(result);
}

Expand All @@ -83,7 +107,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);

Block current = Build.A.Block.WithParent(headBlock).TestObject;
for (int i = 0; i < 6; i++)
Expand All @@ -94,7 +118,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync()
}

long lookupNumber = current.Number - 256;
Hash256 result = provider.GetBlockhash(current.Header, lookupNumber);
Hash256? result = provider.GetBlockhash(current.Header, lookupNumber);
Assert.NotNull(result);
}

Expand All @@ -113,9 +137,9 @@ public void Can_handle_non_main_chain_in_fast_sync()
current = Build.A.Block.WithParent(current).TestObject;
}

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);

Hash256 result = provider.GetBlockhash(current.Header, 509);
Hash256? result = provider.GetBlockhash(current.Header, 509);
Assert.NotNull(result);
}

Expand All @@ -128,10 +152,10 @@ public void Can_get_parent_hash()

BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1);
Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1);
Assert.That(result, Is.EqualTo(head.Hash));
}

Expand All @@ -143,10 +167,10 @@ public void Cannot_ask_for_self()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength);
Hash256? result = provider.GetBlockhash(current.Header, chainLength);
Assert.Null(result);
}

Expand All @@ -158,10 +182,10 @@ public void Cannot_ask_about_future()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength + 1);
Hash256? result = provider.GetBlockhash(current.Header, chainLength + 1);
Assert.Null(result);
}

Expand All @@ -173,10 +197,10 @@ public void Can_lookup_up_to_256_before()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256);
Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256);
Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash));
}

Expand All @@ -188,10 +212,10 @@ public void No_lookup_more_than_256_before()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, chainLength - 257);
Hash256? result = provider.GetBlockhash(current.Header, chainLength - 257);
Assert.Null(result);
}

Expand All @@ -203,11 +227,65 @@ public void UInt_256_overflow()
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject;

BlockhashProvider provider = new(tree, LimboLogs.Instance);
BlockhashProvider provider = CreateBlockHashProvider(tree, Frontier.Instance);
BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!;
Block current = Build.A.Block.WithParent(head).TestObject;
Hash256 result = provider.GetBlockhash(current.Header, 127);
Hash256? result = provider.GetBlockhash(current.Header, 127);
Assert.That(result, Is.EqualTo(head.Hash));
}

[Timeout(Timeout.MaxTestTime)]
[TestCase(1)]
[TestCase(512)]
[TestCase(8192)]
[TestCase(8193)]
public void Eip2935_init_block_history_and_then_get_hash(int chainLength)
{
Block genesis = Build.A.Block.Genesis.TestObject;
BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject;

BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None);
// number = chainLength
Block current = Build.A.Block.WithParent(head!).TestObject;
tree.SuggestHeader(current.Header);

IWorldState worldState = CreateWorldState();
var specToUse = new OverridableReleaseSpec(Prague.Instance)
{
Eip2935TransitionTimestamp = current.Timestamp
};
var specProvider = new CustomSpecProvider(
(new ForkActivation(0, genesis.Timestamp), Frontier.Instance),
(new ForkActivation(0, current.Timestamp), specToUse));
BlockhashProvider provider = new(tree, specProvider, worldState, LimboLogs.Instance);
BlockhashStore store = new(tree, specProvider, worldState);

store.ApplyHistoryBlockHashes(current.Header);
worldState.Commit(specToUse);

Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1);
Assert.That(result, Is.EqualTo(head?.Hash));
AssertGenesisHash(provider, current.Header, genesis.Hash!);

head = current.Header;
// number = chainLength + 1
current = Build.A.Block.WithParent(head!).TestObject;
tree.SuggestHeader(current.Header);

store.ApplyHistoryBlockHashes(current.Header);
result = provider.GetBlockhash(current.Header, chainLength);
Assert.That(result, Is.EqualTo(head?.Hash));

AssertGenesisHash(provider, current.Header, genesis.Hash!);
}

private static void AssertGenesisHash(BlockhashProvider provider, BlockHeader currentHeader, Hash256 genesisHash)
{
Hash256? result = provider.GetBlockhash(currentHeader, 0);
if (currentHeader.Number > Eip2935Constants.RingBufferSize)
Assert.That(result, Is.Null);
else
Assert.That(result, Is.EqualTo(genesisHash));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Threading;
using FluentAssertions;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Receipts;
using Nethermind.Config;
using Nethermind.Consensus.Processing;
Expand Down Expand Up @@ -55,7 +56,7 @@ public void Test()
dbProvider.RegisteredDbs[DbNames.Code],
LimboLogs.Instance);
StateReader stateReader = new(trieStore, dbProvider.GetDb<IDb>(DbNames.State), LimboLogs.Instance);
BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance);
BlockhashProvider blockhashProvider = new(blockTree, specProvider, stateProvider, LimboLogs.Instance);
VirtualMachine virtualMachine = new(
blockhashProvider,
specProvider,
Expand All @@ -73,6 +74,7 @@ public void Test()
stateProvider,
NullReceiptStorage.Instance,
NullWitnessCollector.Instance,
new BlockhashStore(blockTree, specProvider, stateProvider),
LimboLogs.Instance);
BlockchainProcessor blockchainProcessor = new(
blockTree,
Expand Down
4 changes: 3 additions & 1 deletion src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using FluentAssertions;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Receipts;
using Nethermind.Consensus.Comparers;
using Nethermind.Consensus.Processing;
Expand Down Expand Up @@ -56,7 +57,7 @@ public void Setup()
new TxValidator(specProvider.ChainId),
LimboLogs.Instance,
transactionComparerProvider.GetDefaultComparer());
BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance);
BlockhashProvider blockhashProvider = new(_blockTree, specProvider, stateProvider, LimboLogs.Instance);
VirtualMachine virtualMachine = new(
blockhashProvider,
specProvider,
Expand All @@ -75,6 +76,7 @@ public void Setup()
stateProvider,
NullReceiptStorage.Instance,
new WitnessCollector(memDbProvider.StateDb, LimboLogs.Instance),
new BlockhashStore(_blockTree, MainnetSpecProvider.Instance, stateProvider),
LimboLogs.Instance);
_blockchainProcessor = new BlockchainProcessor(
_blockTree,
Expand Down
Loading