-
Notifications
You must be signed in to change notification settings - Fork 406
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
Add support for eth68 #4866
Merged
Merged
Add support for eth68 #4866
Changes from 28 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
0299694
eth68 implementation
deffrian b734ab5
test
deffrian 692ef07
refactor serializer
marcindsobczak e8b67ee
change typesSize back
marcindsobczak c8059ad
Tests and enable capability
deffrian f5feb4e
serializer tests
deffrian a7560b1
Fix whitespaces
deffrian d7097d9
fix whitespaces
deffrian a0ccb0b
Merge branch 'master' into feature/eth68
deffrian cfbc257
Refactor
deffrian 260d7ee
Fix serialization & peer drop
deffrian f8e1f33
RequestTransactions68
deffrian ba8f74d
Metrics & logs
deffrian f0b3442
Reduce paket max size
deffrian 5a10857
Calculate length properly
deffrian a2a1f2f
fix tests & length
deffrian b892322
huge transaction test
deffrian 5881a23
fix spaces
deffrian 9b349ad
Make size calculated once per transaction
deffrian e123c19
Refactor & optimizations
deffrian e84f311
Fix hive tests
deffrian 2c3e0a2
Merge branch 'master' into feature/eth68
deffrian 81f6d18
Copyright fix
deffrian 77701f6
ubuntu 20.04 workflow
deffrian 3a15b7f
Merge branch 'master' into feature/eth68
deffrian 648e156
Revert "ubuntu 20.04 workflow"
deffrian 89991e8
Revert "Revert "ubuntu 20.04 workflow""
deffrian ae32d99
Remove metrics & for loop
deffrian a82d574
Remove test & RequestTransactionsEth68
deffrian 63ddc23
EncodeList implementation
deffrian b04541f
Fix test
deffrian dc84be6
Revert renaming
deffrian 9227f4f
Rename write
deffrian 879e1a7
Remove Request68
deffrian 7793937
Fix run-nethermind-tests.yml
deffrian ac14f58
Fix run-nethermind-tests.yml
deffrian 7ae7424
Merge branch 'master' into feature/eth68
deffrian File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
189 changes: 189 additions & 0 deletions
189
src/Nethermind/Nethermind.Network.Test/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandlerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Net; | ||
using DotNetty.Buffers; | ||
using FluentAssertions; | ||
using Nethermind.Consensus; | ||
using Nethermind.Core; | ||
using Nethermind.Core.Crypto; | ||
using Nethermind.Core.Specs; | ||
using Nethermind.Core.Test.Builders; | ||
using Nethermind.Core.Timers; | ||
using Nethermind.Logging; | ||
using Nethermind.Network.P2P; | ||
using Nethermind.Network.P2P.Subprotocols; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V65; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V66.Messages; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V68; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V68.Messages; | ||
using Nethermind.Network.Rlpx; | ||
using Nethermind.Network.Test.Builders; | ||
using Nethermind.Serialization.Rlp; | ||
using Nethermind.Stats; | ||
using Nethermind.Stats.Model; | ||
using Nethermind.Synchronization; | ||
using Nethermind.TxPool; | ||
using NSubstitute; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Network.Test.P2P.Subprotocols.Eth.V68; | ||
|
||
public class Eth68ProtocolHandlerTests | ||
{ | ||
private ISession _session; | ||
private IMessageSerializationService _svc; | ||
private ISyncServer _syncManager; | ||
private ITxPool _transactionPool; | ||
private IPooledTxsRequestor _pooledTxsRequestor; | ||
private IGossipPolicy _gossipPolicy; | ||
private ISpecProvider _specProvider; | ||
private Block _genesisBlock; | ||
private Eth68ProtocolHandler _handler; | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
_svc = Build.A.SerializationService().WithEth68().TestObject; | ||
|
||
NetworkDiagTracer.IsEnabled = true; | ||
|
||
_session = Substitute.For<ISession>(); | ||
Node node = new(TestItem.PublicKeyA, new IPEndPoint(IPAddress.Broadcast, 30303)); | ||
_session.Node.Returns(node); | ||
_syncManager = Substitute.For<ISyncServer>(); | ||
_transactionPool = Substitute.For<ITxPool>(); | ||
_pooledTxsRequestor = Substitute.For<IPooledTxsRequestor>(); | ||
_specProvider = Substitute.For<ISpecProvider>(); | ||
_gossipPolicy = Substitute.For<IGossipPolicy>(); | ||
_genesisBlock = Build.A.Block.Genesis.TestObject; | ||
_syncManager.Head.Returns(_genesisBlock.Header); | ||
_syncManager.Genesis.Returns(_genesisBlock.Header); | ||
ITimerFactory timerFactory = Substitute.For<ITimerFactory>(); | ||
_handler = new Eth68ProtocolHandler( | ||
_session, | ||
_svc, | ||
new NodeStatsManager(timerFactory, LimboLogs.Instance), | ||
_syncManager, | ||
_transactionPool, | ||
_pooledTxsRequestor, | ||
_gossipPolicy, | ||
_specProvider, | ||
LimboLogs.Instance); | ||
_handler.Init(); | ||
} | ||
|
||
[TearDown] | ||
public void TearDown() | ||
{ | ||
_handler.Dispose(); | ||
} | ||
|
||
[Test] | ||
public void Metadata_correct() | ||
{ | ||
_handler.ProtocolCode.Should().Be("eth"); | ||
_handler.Name.Should().Be("eth68"); | ||
_handler.ProtocolVersion.Should().Be(68); | ||
_handler.MessageIdSpaceSize.Should().Be(17); | ||
_handler.IncludeInTxPool.Should().BeTrue(); | ||
_handler.ClientId.Should().Be(_session.Node?.ClientId); | ||
_handler.HeadHash.Should().BeNull(); | ||
_handler.HeadNumber.Should().Be(0); | ||
} | ||
|
||
[TestCase(0)] | ||
[TestCase(1)] | ||
[TestCase(2)] | ||
[TestCase(100)] | ||
public void Can_handle_NewPooledTransactions_message(int txCount) | ||
{ | ||
GenerateLists(txCount, out List<byte> types, out List<int> sizes, out List<Keccak> hashes); | ||
|
||
var msg = new NewPooledTransactionHashesMessage68(types, sizes, hashes); | ||
|
||
HandleIncomingStatusMessage(); | ||
HandleZeroMessage(msg, Eth68MessageCode.NewPooledTransactionHashes); | ||
_pooledTxsRequestor.Received().RequestTransactionsEth68(Arg.Any<Action<GetPooledTransactionsMessage>>(), | ||
Arg.Any<IReadOnlyList<Keccak>>(), Arg.Any<IReadOnlyList<int>>(), Arg.Any<IReadOnlyList<byte>>()); | ||
} | ||
|
||
[TestCase(true)] | ||
[TestCase(false)] | ||
public void Should_throw_when_sizes_doesnt_match(bool removeSize) | ||
{ | ||
GenerateLists(4, out List<byte> types, out List<int> sizes, out List<Keccak> hashes); | ||
|
||
if (removeSize) | ||
{ | ||
sizes.RemoveAt(sizes.Count - 1); | ||
} | ||
else | ||
{ | ||
types.RemoveAt(sizes.Count - 1); | ||
} | ||
|
||
var msg = new NewPooledTransactionHashesMessage68(types, sizes, hashes); | ||
|
||
HandleIncomingStatusMessage(); | ||
Action action = () => HandleZeroMessage(msg, Eth68MessageCode.NewPooledTransactionHashes); | ||
action.Should().Throw<SubprotocolException>(); | ||
} | ||
|
||
[Test] | ||
public void Should_process_huge_transaction() | ||
{ | ||
Transaction tx = Build.A.Transaction.WithType(TxType.EIP1559).WithData(new byte[2 * 1024 * 1024]) | ||
.WithHash(TestItem.KeccakA).TestObject; | ||
|
||
TxDecoder txDecoder = new(); | ||
|
||
var msg = new NewPooledTransactionHashesMessage68(new[] { (byte)tx.Type }, | ||
new[] { txDecoder.GetLength(tx, RlpBehaviors.None) }, new[] { tx.Hash }); | ||
|
||
HandleIncomingStatusMessage(); | ||
|
||
HandleZeroMessage(msg, Eth68MessageCode.NewPooledTransactionHashes); | ||
_pooledTxsRequestor.Received().RequestTransactionsEth68(Arg.Any<Action<GetPooledTransactionsMessage>>(), | ||
Arg.Any<IReadOnlyList<Keccak>>(), Arg.Any<IReadOnlyList<int>>(), Arg.Any<IReadOnlyList<byte>>()); | ||
} | ||
|
||
private void HandleIncomingStatusMessage() | ||
{ | ||
var statusMsg = new StatusMessage(); | ||
statusMsg.GenesisHash = _genesisBlock.Hash; | ||
statusMsg.BestHash = _genesisBlock.Hash; | ||
|
||
IByteBuffer statusPacket = _svc.ZeroSerialize(statusMsg); | ||
statusPacket.ReadByte(); | ||
_handler.HandleMessage(new ZeroPacket(statusPacket) { PacketType = 0 }); | ||
} | ||
|
||
private void HandleZeroMessage<T>(T msg, byte messageCode) where T : MessageBase | ||
{ | ||
IByteBuffer getBlockHeadersPacket = _svc.ZeroSerialize(msg); | ||
getBlockHeadersPacket.ReadByte(); | ||
_handler.HandleMessage(new ZeroPacket(getBlockHeadersPacket) { PacketType = messageCode }); | ||
} | ||
|
||
private void GenerateLists(int txCount, out List<byte> types, out List<int> sizes, out List<Keccak> hashes) | ||
{ | ||
TxDecoder txDecoder = new(); | ||
types = new(); | ||
sizes = new(); | ||
hashes = new(); | ||
|
||
for (int i = 0; i < txCount; ++i) | ||
{ | ||
Transaction tx = Build.A.Transaction.WithType((TxType)(i % 3)).WithData(new byte[i]) | ||
.WithHash(i % 2 == 0 ? TestItem.KeccakA : TestItem.KeccakB).TestObject; | ||
|
||
types.Add((byte)tx.Type); | ||
sizes.Add(txDecoder.GetLength(tx, RlpBehaviors.None)); | ||
hashes.Add(tx.Hash); | ||
} | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
...Network.Test/P2P/Subprotocols/Eth/V68/NewPooledTransactionHashesMessageSerializerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System.Linq; | ||
using Nethermind.Core; | ||
using Nethermind.Core.Crypto; | ||
using Nethermind.Core.Test.Builders; | ||
using Nethermind.Network.P2P.Subprotocols.Eth.V68.Messages; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Network.Test.P2P.Subprotocols.Eth.V68; | ||
|
||
[TestFixture, Parallelizable(ParallelScope.All)] | ||
public class NewPooledTransactionHashesMessageSerializerTests | ||
{ | ||
private static void Test(TxType[] types, int[] sizes, Keccak[] hashes, string expected = null) | ||
{ | ||
NewPooledTransactionHashesMessage68 message = new(types.Select(t => (byte)t).ToList(), sizes, hashes); | ||
NewPooledTransactionHashesMessageSerializer serializer = new(); | ||
|
||
SerializerTester.TestZero(serializer, message, expected); | ||
} | ||
|
||
[Test] | ||
public void Roundtrip() | ||
{ | ||
TxType[] types = { TxType.Legacy, TxType.AccessList, TxType.EIP1559 }; | ||
int[] sizes = { 5, 10, 1500 }; | ||
Keccak[] hashes = { TestItem.KeccakA, TestItem.KeccakB, TestItem.KeccakC }; | ||
Test(types, sizes, hashes); | ||
} | ||
|
||
[Test] | ||
public void Empty_serialization() | ||
{ | ||
TxType[] types = { }; | ||
int[] sizes = { }; | ||
Keccak[] hashes = { }; | ||
Test(types, sizes, hashes, "c380c0c0"); | ||
} | ||
|
||
[Test] | ||
public void Empty_hashes_serialization() | ||
{ | ||
TxType[] types = { TxType.EIP1559 }; | ||
int[] sizes = { 10 }; | ||
Keccak[] hashes = { }; | ||
Test(types, sizes, hashes, "c402c10ac0"); | ||
} | ||
|
||
[Test] | ||
public void Non_empty_serialization() | ||
{ | ||
TxType[] types = { TxType.AccessList }; | ||
int[] sizes = { 2 }; | ||
Keccak[] hashes = { TestItem.KeccakA }; | ||
Test(types, sizes, hashes, | ||
"e5" + "01" + "c102" + "e1a0" + TestItem.KeccakA.ToString(false)); | ||
} | ||
|
||
[Test] | ||
public void Empty_to_string() | ||
{ | ||
NewPooledTransactionHashesMessage68 message | ||
= new(new byte[] { }, new int[] { }, new Keccak[] { }); | ||
_ = message.ToString(); | ||
} | ||
deffrian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not do the whole comparision:
_handler.Should().BeEquivalentTo(expectedHandler)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is an updated copy-paste of metadata tests for older protocols. Purpose of this test is to check if metadata are correct and it is doing it perfectly. If we create another instance o
Eth68ProtocolHandler
and compare equivalence with_handler
, we will still don't know if these details are correct in both or wrong in both of them. It is not overwritable from the outside, so no way to ensure correctness ofexpectedHandler