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

feature: Add support for block validation (flashbots_validateBuilderSubmissionV3) #7335

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d33add6
add init code for block validation
rjnrohit Aug 16, 2024
9eb6f70
format files
rjnrohit Aug 16, 2024
ae4357f
verify blobs
rjnrohit Aug 27, 2024
346330d
create block processor
rjnrohit Sep 2, 2024
b802039
add modal validate payload
rjnrohit Sep 4, 2024
6ad5909
format files
rjnrohit Sep 4, 2024
3cf82fe
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 4, 2024
256da82
add hook step
rjnrohit Sep 5, 2024
a749b8e
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 5, 2024
09b46b4
add config
rjnrohit Sep 5, 2024
621e297
format files
rjnrohit Sep 5, 2024
ffc25f0
address PR comments
rjnrohit Sep 12, 2024
1bebf60
Hookup BlockValidation plugin in Nethermind.Runner
LukaszRozmej Sep 12, 2024
570dce0
Update Fast Sync configuration in Nethermind repository (#7401)
core-repository-dispatch-app[bot] Sep 8, 2024
bec7a5d
Feature/geth like system tx (#7252)
LukaszRozmej Sep 9, 2024
8b8cd01
Heuristic tx censorship detection (#7259)
Arindam2407 Sep 10, 2024
69e36dd
Refactor `TxValidator` (#7386)
emlautarom1 Sep 10, 2024
17533eb
Moved BlockProductionTimeout to config, increased BlockProductionTime…
MarekM25 Sep 10, 2024
c1f9455
Reduce memory use during Archive Sync (#7407)
benaadams Sep 11, 2024
5aebe9b
Update Supported Networks in Readme (#7412)
MarekM25 Sep 11, 2024
37b9fb4
Change Windows native Allocator (#7418)
benaadams Sep 11, 2024
4a17264
Fast address equals (#7417)
benaadams Sep 11, 2024
413a5b3
Reduce backlog threshold for GC (#7415)
benaadams Sep 11, 2024
bb3753d
Bump unstable to 1.29.0 (#7416)
kamilchodola Sep 11, 2024
4373e5a
enable flashBots module
rjnrohit Sep 12, 2024
a73b41a
format files
rjnrohit Sep 12, 2024
cfe14f2
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 12, 2024
71e03eb
rename blockValidation -> flashbots
rjnrohit Sep 13, 2024
9f1bf85
rename params
rjnrohit Sep 13, 2024
d203d5e
revert holesky.cfg
rjnrohit Sep 13, 2024
1d7c272
add json required
rjnrohit Sep 19, 2024
2e4775c
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 19, 2024
0c15eea
fix parameter serialization
rjnrohit Sep 23, 2024
ea60068
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 23, 2024
558a425
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Sep 24, 2024
4eeeb9f
Add initial tests
rjnrohit Sep 26, 2024
c739854
Merge branch 'master' into feature/flashbots_endpoints
rjnrohit Oct 10, 2024
3bbce1f
format files
rjnrohit Oct 10, 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
1 change: 1 addition & 0 deletions .github/workflows/nethermind-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
- Nethermind.EthStats.Test
- Nethermind.Evm.Test
- Nethermind.Facade.Test
- Nethermind.Flashbots.Test
- Nethermind.HealthChecks.Test
- Nethermind.Hive.Test
- Nethermind.JsonRpc.Test
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Api/Extensions/PluginConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ namespace Nethermind.Api.Extensions;

public class PluginConfig : IPluginConfig
{
public string[] PluginOrder { get; set; } = { "Clique", "Aura", "Ethash", "Optimism", "Shutter", "AuRaMerge", "Merge", "MEV", "HealthChecks", "Hive" };
public string[] PluginOrder { get; set; } = { "Clique", "Aura", "Ethash", "Optimism", "Shutter", "AuRaMerge", "Merge", "Flashbots", "MEV", "HealthChecks", "Hive" };
}
171 changes: 171 additions & 0 deletions src/Nethermind/Nethermind.Flashbots.Test/FlashbotsModuleTests.Setup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading.Tasks;
using Nethermind.Blockchain.BeaconBlockRoot;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Consensus;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Rewards;
using Nethermind.Consensus.Validators;
using Nethermind.Consensus.Withdrawals;
using Nethermind.Core;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Blockchain;
using Nethermind.Crypto;
using Nethermind.Db;
using Nethermind.Flashbots;
using Nethermind.Flashbots.Handlers;
using Nethermind.Flashbots.Modules.Flashbots;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Merge.Plugin;
using Nethermind.Specs;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Specs.Forks;
using NUnit.Framework;

namespace Nethermind.Flasbots.Test;

public partial class FlashbotsModuleTests
{
TestKeyAndAddress? TestKeysAndAddress;

[SetUp]
public void SetUp()
{
TestKeysAndAddress = new TestKeyAndAddress();
}

internal class TestKeyAndAddress
{
public PrivateKey privateKey = new PrivateKey("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291");
public Address TestAddr;

public PrivateKey TestValidatorKey = new PrivateKey("28c3cd61b687fdd03488e167a5d84f50269df2a4c29a2cfb1390903aa775c5d0");
public Address TestValidatorAddr;

public PrivateKey TestBuilderKey = new PrivateKey("0bfbbbc68fefd990e61ba645efb84e0a62e94d5fff02c9b1da8eb45fea32b4e0");
public Address TestBuilderAddr;

public UInt256 TestBalance = UInt256.Parse("2000000000000000000");
public byte[] logCode = Bytes.FromHexString("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00");
public TestKeyAndAddress()
{
TestAddr = privateKey.Address;
TestValidatorAddr = TestValidatorKey.Address;
TestBuilderAddr = TestBuilderKey.Address;
}
}

protected virtual MergeTestBlockChain CreateBaseBlockChain(
IFlashbotsConfig flashbotsConfig,
ILogManager? logManager = null)
{
return new MergeTestBlockChain(flashbotsConfig, logManager);
}

protected async Task<MergeTestBlockChain> CreateBlockChain(
IReleaseSpec? releaseSpec = null,
IFlashbotsConfig? flashbotsConfig = null,
ILogManager? logManager = null)
=> await CreateBaseBlockChain(flashbotsConfig ?? new FlashbotsConfig(), logManager).Build(new TestSingleReleaseSpecProvider(releaseSpec ?? London.Instance));

private IFlashbotsRpcModule CreateFlashbotsModule(MergeTestBlockChain chain, ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv)
{
return new FlashbotsRpcModule(
new ValidateSubmissionHandler(
chain.HeaderValidator,
chain.BlockValidator,
readOnlyTxProcessingEnv,
chain.FlashbotsConfig
)
);
}

public class MergeTestBlockChain : TestBlockchain
{
public IFlashbotsConfig FlashbotsConfig;

public IMergeConfig MergeConfig;

public IWithdrawalProcessor? WithdrawalProcessor { get; set; }

public ReadOnlyTxProcessingEnv ReadOnlyTxProcessingEnv { get; set; }

public MergeTestBlockChain(IFlashbotsConfig flashbotsConfig, ILogManager? logManager = null)
{
FlashbotsConfig = flashbotsConfig;
MergeConfig = new MergeConfig() { TerminalTotalDifficulty = "0" };
LogManager = logManager ?? LogManager;
}

public sealed override ILogManager LogManager { get; set; } = LimboLogs.Instance;

public ReadOnlyTxProcessingEnv CreateReadOnlyTxProcessingEnv()
{
ReadOnlyTxProcessingEnv = new ReadOnlyTxProcessingEnv(
WorldStateManager,
BlockTree,
SpecProvider,
LogManager
);
return ReadOnlyTxProcessingEnv;
}

protected override IBlockProcessor CreateBlockProcessor()
{
BlockValidator = CreateBlockValidator();
WithdrawalProcessor = new WithdrawalProcessor(State, LogManager);
IBlockProcessor prcessor = new BlockProcessor(
SpecProvider,
BlockValidator,
NoBlockRewards.Instance,
new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State),
State,
ReceiptStorage,
TxProcessor,
new BeaconBlockRootHandler(TxProcessor),
new BlockhashStore(SpecProvider, State),
LogManager,
WithdrawalProcessor
);

return prcessor;
}

protected IBlockValidator CreateBlockValidator()
{
PoSSwitcher = new PoSSwitcher(MergeConfig, SyncConfig.Default, new MemDb(), BlockTree, SpecProvider, new ChainSpec() { Genesis = Core.Test.Builders.Build.A.Block.WithDifficulty(0).TestObject }, LogManager);
ISealValidator SealValidator = new MergeSealValidator(PoSSwitcher, Always.Valid);
HeaderValidator = new MergeHeaderValidator(
PoSSwitcher,
new HeaderValidator(BlockTree, SealValidator, SpecProvider, LogManager),
BlockTree,
SpecProvider,
SealValidator,
LogManager
);

return new BlockValidator(
new TxValidator(SpecProvider.ChainId),
HeaderValidator,
Always.Valid,
SpecProvider,
LogManager
);
}

protected override async Task<TestBlockchain> Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true)
{
TestBlockchain chain = await base.Build(specProvider, initialValues);
return chain;
}

public async Task<MergeTestBlockChain> Build(ISpecProvider? specProvider = null) =>
(MergeTestBlockChain)await Build(specProvider, null);

}
}
32 changes: 32 additions & 0 deletions src/Nethermind/Nethermind.Flashbots.Test/FlashbotsModuleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading.Tasks;
using Nethermind.Consensus.Processing;
using Nethermind.Core;
using Nethermind.Core.Extensions;
using Nethermind.Crypto;
using Nethermind.Flashbots.Modules.Flashbots;
using Nethermind.Int256;
using Nethermind.State;

namespace Nethermind.Flasbots.Test;

public partial class FlashbotsModuleTests
{

public async Task TestValidateBuilderSubmissionV3()
{
using MergeTestBlockChain chain = await CreateBlockChain();
ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv = chain.CreateReadOnlyTxProcessingEnv();
IFlashbotsRpcModule rpc = CreateFlashbotsModule(chain, readOnlyTxProcessingEnv);
BlockHeader currentHeader = chain.BlockTree.Head.Header;
IWorldState State = chain.State;

UInt256 nonce = State.GetNonce(TestKeysAndAddress.TestAddr);

Transaction tx1 = new Transaction(

);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Nullable>annotations</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NSubstitute" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Nethermind.JsonRpc.Test\Nethermind.JsonRpc.Test.csproj" />
<ProjectReference Include="..\Nethermind.Consensus\Nethermind.Consensus.csproj" />
<ProjectReference Include="..\Nethermind.Core.Test\Nethermind.Core.Test.csproj" />
<ProjectReference Include="..\Nethermind.Merge.Test\Nethermind.Merge.Test.csproj" />
<ProjectReference Include="..\Nethermind.Flashbots\Nethermind.Flashbots.csproj" />
</ItemGroup>

</Project>
29 changes: 29 additions & 0 deletions src/Nethermind/Nethermind.Flashbots/Data/BidTrace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Int256;

namespace Nethermind.Flashbots.Data;

public class BidTrace(
ulong slot,
Hash256 blockHash,
PublicKey builderPublicKey,
PublicKey proposerPublicKey,
Address proposerFeeRecipient,
long gasLimit,
long gasUsed,
UInt256 value)
{
public ulong Slot { get; } = slot;
public required Hash256 ParentHash { get; set; }
public Hash256 BlockHash { get; } = blockHash;
public PublicKey BuilderPublicKey { get; } = builderPublicKey;
public PublicKey ProposerPublicKey { get; } = proposerPublicKey;
public Address ProposerFeeRecipient { get; } = proposerFeeRecipient;
public long GasLimit { get; } = gasLimit;
public long GasUsed { get; } = gasUsed;
public UInt256 Value { get; } = value;
}
47 changes: 47 additions & 0 deletions src/Nethermind/Nethermind.Flashbots/Data/BlockValidationResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Text.Json.Serialization;
using Nethermind.JsonRpc;

namespace Nethermind.Flashbots.Data;

/// <summary>
/// Represents the result of a block validation.
/// </summary>
public class FlashbotsResult
{

public static ResultWrapper<FlashbotsResult> Invalid(string error)
{
return ResultWrapper<FlashbotsResult>.Success(new FlashbotsResult
{
Status = FlashbotsStatus.Invalid,
ValidationError = error
});
}

public static ResultWrapper<FlashbotsResult> Valid()
{
return ResultWrapper<FlashbotsResult>.Success(new FlashbotsResult
{
Status = FlashbotsStatus.Valid
});
}

public static ResultWrapper<FlashbotsResult> Error(string error)
{
return ResultWrapper<FlashbotsResult>.Fail(error);
}

/// <summary>
/// The status of the validation of the builder submissions
/// </summary>
public string Status { get; set; } = FlashbotsStatus.Invalid;

/// <summary>
/// Message providing additional details on the validation error if the payload is classified as <see cref="ValidationStatus.Invalid"/>.
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? ValidationError { get; set; }
}
17 changes: 17 additions & 0 deletions src/Nethermind/Nethermind.Flashbots/Data/BlockValidationStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

namespace Nethermind.Flashbots.Data;

public static class FlashbotsStatus
{
/// <summary>
/// The submissions are invalid.
/// </summary>
public const string Invalid = "Invalid";

/// <summary>
/// The submissions are valid.
/// </summary>
public const string Valid = "Valid";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Text.Json.Serialization;
using Nethermind.Core.Crypto;
using Nethermind.JsonRpc;

namespace Nethermind.Flashbots.Data;

public class BuilderBlockValidationRequest
{
/// <summary>
/// The block hash of the parent beacon block.
/// <see cref=https://github.com/flashbots/builder/blob/df9c765067d57ab4b2d0ad39dbb156cbe4965778/eth/block-validation/api.go#L198"/>
/// </summary>
[JsonRequired]
public required Hash256 ParentBeaconBlockRoot { get; set; }

[JsonRequired]
public long RegisterGasLimit { get; set; }

[JsonRequired]
public required SubmitBlockRequest BlockRequest { get; set; }
}
23 changes: 23 additions & 0 deletions src/Nethermind/Nethermind.Flashbots/Data/SubmitBlockRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core.Crypto;
using Nethermind.Merge.Plugin.Data;

namespace Nethermind.Flashbots.Data;

public class SubmitBlockRequest
{
private readonly ExecutionPayload _executionPayload;
private readonly BlobsBundleV1 _blobsBundle;

public SubmitBlockRequest(ExecutionPayload executionPayload, BlobsBundleV1 blobsBundle, BidTrace message)
{
_executionPayload = executionPayload;
_blobsBundle = blobsBundle;
Message = message;
}
public ExecutionPayload ExecutionPayload => _executionPayload;
public BlobsBundleV1 BlobsBundle => _blobsBundle;
public BidTrace Message { get; }
}
Loading
Loading