Skip to content

Commit

Permalink
P2P
Browse files Browse the repository at this point in the history
  • Loading branch information
deffrian committed Sep 7, 2024
1 parent f8527c9 commit be22107
Show file tree
Hide file tree
Showing 21 changed files with 775 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "src/bench_precompiles"]
path = src/bench_precompiles
url = https://github.com/shamatar/bench_precompiles.git
[submodule "src/dotnet-libp2p"]
path = src/dotnet-libp2p
url = https://github.com/NethermindEth/dotnet-libp2p.git
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);NUnit1032</NoWarn>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>

<ItemGroup>
Expand Down
14 changes: 14 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/CLConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core;

namespace Nethermind.Optimism.CL;

public class CLConfig : ICLConfig
{
public Address? BatcherInboxAddress { get; set; }
public Address? BatcherAddress { get; set; }
public string? L1BeaconApiEndpoint { get; set; }
public string? L1EthApiEndpoint { get; set; }
}
60 changes: 60 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/Driver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Linq;
using Nethermind.Blockchain.Find;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Facade.Eth;
using Nethermind.JsonRpc.Modules.Eth;

namespace Nethermind.Optimism.CL;

public class Driver
{
private readonly ICLConfig _config;
private readonly IL1Bridge _l1Bridge;

public Driver(IL1Bridge l1Bridge, ICLConfig config)
{
_config = config;
_l1Bridge = l1Bridge;
}

private void Start()
{
_l1Bridge.OnNewL1Head += OnNewL1Head;
}

private void OnNewL1Head(BlockForRpc block, ulong slotNumber)
{
// Filter batch submitter transaction
foreach (TransactionForRpc transaction in block.Transactions.Cast<TransactionForRpc>())
{
if (_config.BatcherInboxAddress == transaction.To && _config.BatcherAddress == transaction.From)
{
if (transaction.Type == TxType.Blob)
{
ProcessBlobBatcherTransaction(transaction);
}
else
{
ProcessCalldataBatcherTransaction(transaction);
}
}
}
}

private void ProcessBlobBatcherTransaction(TransactionForRpc transaction)
{
int numberOfBlobs = transaction.BlobVersionedHashes!.Length;
for (int i = 0; i < numberOfBlobs; ++i)
{

}
}

private void ProcessCalldataBatcherTransaction(TransactionForRpc transaction)
{
}
}
17 changes: 17 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/EthereumBeaconApi.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.Optimism.CL;

public class EthereumBeaconApi : IBeaconApi
{
public BeaconBlock GetHead()
{
throw new System.NotImplementedException();
}

public BlobSidecar[] GetBlobSidecars(int slot)
{
throw new System.NotImplementedException();
}
}
27 changes: 27 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/EthereumEthApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Threading.Tasks;
using Nethermind.Facade.Eth;
using Nethermind.JsonRpc.Client;
using Nethermind.Logging;
using Nethermind.Serialization.Json;

namespace Nethermind.Optimism.CL;

public class EthereumEthApi : IEthApi
{
private readonly IJsonRpcClient _ethRpcClient;

public EthereumEthApi(ICLConfig config, IJsonSerializer jsonSerializer, ILogManager logManager)
{
ArgumentNullException.ThrowIfNull(config.L1EthApiEndpoint);
_ethRpcClient = new BasicJsonRpcClient(new Uri(config.L1EthApiEndpoint), jsonSerializer, logManager);
}

public Task<BlockForRpc?> GetBlockByNumber(ulong blockNumber)
{
return _ethRpcClient.Post<BlockForRpc>("eth_getBlockByNumber", new object[] { blockNumber, true });
}
}
73 changes: 73 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/EthereumL1Bridge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Threading.Tasks;
using Nethermind.Facade.Eth;
using Nethermind.Logging;

namespace Nethermind.Optimism.CL;

public class EthereumL1Bridge : IL1Bridge
{
private readonly ICLConfig _config;
private readonly IEthApi _ethL1Api;
private readonly IBeaconApi _beaconApi;
private readonly Task _headUpdateTask;
private readonly ILogger _logger;

private ulong _currentSlot = 0;

public EthereumL1Bridge(IEthApi ethL1Rpc, IBeaconApi beaconApi, ICLConfig config, ILogManager logManager)
{
ArgumentNullException.ThrowIfNull(config.L1EthApiEndpoint);
_logger = logManager.GetClassLogger();
_config = config;
_ethL1Api = ethL1Rpc;
_beaconApi = beaconApi;
_headUpdateTask = new Task(() =>
{
HeadUpdateLoop();
});
}

private async void HeadUpdateLoop()
{
// TODO: Cancellation token
while (true)
{
BeaconBlock beaconBlock = _beaconApi.GetHead();
while (beaconBlock.SlotNumber <= _currentSlot)
{
beaconBlock = _beaconApi.GetHead();
}

// new slot
_currentSlot = beaconBlock.SlotNumber;
BlockForRpc? block = await _ethL1Api.GetBlockByNumber(beaconBlock.PayloadNumber);

if (block is null)
{
if (_logger.IsError) _logger.Error($"Unable to get L1 block");
return;
}

OnNewL1Head?.Invoke(block, _currentSlot);

// Wait next slot
await Task.Delay(12000);
}
}

public void Start()
{
_headUpdateTask.Start();
}

public event Action<BlockForRpc, ulong>? OnNewL1Head;

public BlobSidecar[] GetBlobSidecars(int slotNumber)
{
return _beaconApi.GetBlobSidecars(slotNumber);
}
}
25 changes: 25 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/IBeaconApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

namespace Nethermind.Optimism.CL;

public interface IBeaconApi
{
// /eth/v2/beacon/blocks/head
BeaconBlock GetHead();

// /eth/v1/beacon/blob_sidecars/:slot:
BlobSidecar[] GetBlobSidecars(int slot);
}

public struct BeaconBlock
{
public ulong SlotNumber;
public ulong PayloadNumber;
}

public struct BlobSidecar
{
public byte[] Blob;
public byte[] Kzg;
}
15 changes: 15 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/ICLConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Config;
using Nethermind.Core;

namespace Nethermind.Optimism.CL;

public interface ICLConfig : IConfig
{
Address? BatcherInboxAddress { get; set; }
Address? BatcherAddress { get; set; }
string? L1BeaconApiEndpoint { get; set; }
string? L1EthApiEndpoint { get; set; }
}
12 changes: 12 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/IEthApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading.Tasks;
using Nethermind.Facade.Eth;

namespace Nethermind.Optimism.CL;

public interface IEthApi
{
Task<BlockForRpc?> GetBlockByNumber(ulong blockNumber);
}
13 changes: 13 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/IL1Bridge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Facade.Eth;

namespace Nethermind.Optimism.CL;

public interface IL1Bridge
{
event Action<BlockForRpc, ulong>? OnNewL1Head;
BlobSidecar[] GetBlobSidecars(int slotNumber);
}
26 changes: 26 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/IP2PBlockValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Merge.Plugin.Data;

namespace Nethermind.Optimism.CL;

// Validates p2p "blocks" messages
public interface IP2PBlockValidator
{
ValidityStatus Validate(ExecutionPayloadV3 payload, byte[] payloadData, byte[] signature, P2PTopic topic);
}

public enum ValidityStatus
{
Valid,
Reject,
Ignore
}

public enum P2PTopic
{
BlocksV1,
BlocksV2,
BlocksV3
}
12 changes: 12 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/IPayloadDecoder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Merge.Plugin.Data;

namespace Nethermind.Optimism.CL;

public interface IPayloadDecoder
{
ExecutionPayloadV3 DecodePayload(byte[] data);
byte[] EncodePayload(ExecutionPayloadV3 payload);
}
42 changes: 42 additions & 0 deletions src/Nethermind/Nethermind.Optimism/CL/OptimismCL.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Init.Steps;
using Nethermind.JsonRpc.Client;
using Nethermind.Libp2p.Protocols.Pubsub;
using Nethermind.Logging;
using Nethermind.Optimism.Rpc;
using Nethermind.Serialization.Json;

namespace Nethermind.Optimism.CL;

public class OptimismCL
{
private readonly ILogger _logger;
private readonly OptimismCLP2P _p2p;
private readonly EthereumL1Bridge _l1Bridge;
private readonly Driver _driver;
private readonly IOptimismEngineRpcModule _engineRpcModule;

public OptimismCL(ISpecProvider specProvider, ICLConfig config, IJsonSerializer jsonSerializer, ITimestamper timestamper, ILogManager logManager, IOptimismEngineRpcModule engineRpcModule)
{
_logger = logManager.GetClassLogger();
_engineRpcModule = engineRpcModule;
_p2p = new OptimismCLP2P(specProvider.ChainId, timestamper, logManager, engineRpcModule);
IEthApi ethApi = new EthereumEthApi(config, jsonSerializer, logManager);
IBeaconApi beaconApi = new EthereumBeaconApi();
_l1Bridge = new EthereumL1Bridge(ethApi, beaconApi, config, logManager);
_driver = new Driver(_l1Bridge, config);
}

public void Start()
{
_p2p.Start();
_l1Bridge.Start();
}
}
Loading

0 comments on commit be22107

Please sign in to comment.