diff --git a/src/Nethermind/Directory.Packages.props b/src/Nethermind/Directory.Packages.props
index b7fae1de28d..21ac26de7c4 100644
--- a/src/Nethermind/Directory.Packages.props
+++ b/src/Nethermind/Directory.Packages.props
@@ -54,7 +54,8 @@
-
+
+
diff --git a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg
index 1dc33ff7a65..ea1634e1b24 100644
--- a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg
+++ b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg
@@ -32,16 +32,13 @@
"ForceSealing": true
},
"Shutter": {
- "ValidatorRegistryContractAddress": "0xa9289A3Dd14FEBe10611119bE81E5d35eAaC3084",
"SequencerContractAddress": "0x2aD8E2feB0ED5b2EC8e700edB725f120576994ed",
+ "ValidatorRegistryContractAddress": "0xa9289A3Dd14FEBe10611119bE81E5d35eAaC3084",
"KeyBroadcastContractAddress": "0x9D31865BEffcE842FBd36CDA587aDDA8bef804B7",
"KeyperSetManagerContractAddress": "0xC4DE9FAf4ec882b33dA0162CBE628B0D8205D0c0",
"BootnodeP2PAddresses": [
- "/ip4/157.230.104.246/tcp/23003/p2p/12D3KooWFUYoPd3bdPuRi6FXkEQRSw7FRf2e23NAypjfDVYuvBAV",
- "/ip4/134.209.225.234/tcp/23003/p2p/12D3KooWAsBKAj1NEtvu7wcLiEVU49N6Z9GPK3tZ87m17tFdWdNE",
- "/ip4/157.230.114.117/tcp/23003/p2p/12D3KooWEDk8XJdxHjCHh9wTGVRXtpyCvCP4N4Jztr8zTJd4rMVX",
- "/ip4/64.225.104.2/tcp/23003/p2p/12D3KooWMXTYrwEz4v5aGa7chYHjVVpjzzkq9JSjZzxbdh9YgAQS",
- "/ip4/157.230.111.142/tcp/23003/p2p/12D3KooWA3FPqxV8whaFPbLzwbyDEWML4y73D6RJqb2mn7SHz6fg"
+ "/ip4/167.99.177.227/tcp/23005/p2p/12D3KooWSdm5guPBdn8DSaBphVBzUUgPLg9sZLnazEUrcbtLy254",
+ "/ip4/159.89.15.119/tcp/23005/p2p/12D3KooWPP6bp2PJQR8rUvG1SD4qNH4WFrKve6DMgWThyKxwNbbH"
],
"InstanceID": "102000"
},
diff --git a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg
index e98e44b71a9..768621bd8d7 100644
--- a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg
+++ b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg
@@ -24,6 +24,17 @@
"BlockProductionTimeoutMs": 3000,
"TargetBlockGasLimit": 17000000
},
+ "Shutter": {
+ "SequencerContractAddress": "0x2aD8E2feB00xc5C4b277277A1A8401E0F039dfC49151bA64DC2ED5b2EC8e700edB725f120576994ed",
+ "ValidatorRegistryContractAddress": "0xefCC23E71f6bA9B22C4D28F7588141d44496A6D6",
+ "KeyBroadcastContractAddress": "0x626dB87f9a9aC47070016A50e802dd5974341301",
+ "KeyperSetManagerContractAddress": "0x7C2337f9bFce19d8970661DA50dE8DD7d3D34abb",
+ "BootnodeP2PAddresses": [
+ "/ip4/167.99.177.227/tcp/23003/p2p/12D3KooWD35AESYCttDEi3J5WnQdTFuM5JNtmuXEb1x4eQ28gb1s",
+ "/ip4/159.89.15.119/tcp/23003/p2p/12D3KooWRzAhgPA16DiBQhiuYoasYzJaQSAbtc5i5FvgTi9ZDQtS"
+ ],
+ "InstanceID": "1000"
+ },
"Mining": {
"MinGasPrice": "1000000000"
},
diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs
index c1709d2879c..8f8d8ceb00c 100644
--- a/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs
+++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterApiSimulator.cs
@@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
+using System.IO.Abstractions;
using System.Linq;
+using System.Net;
using System.Threading.Tasks;
using Nethermind.Abi;
using Nethermind.Blockchain;
@@ -14,6 +16,7 @@
using Nethermind.Core.Test.Builders;
using Nethermind.Crypto;
using Nethermind.Facade.Find;
+using Nethermind.KeyStore.Config;
using Nethermind.Logging;
using Nethermind.Shutter.Config;
using Nethermind.State;
@@ -32,11 +35,14 @@ public class ShutterApiSimulator(
ISpecProvider specProvider,
ITimestamper timestamper,
IWorldStateManager worldStateManager,
+ IFileSystem fileSystem,
+ IKeyStoreConfig keyStoreConfig,
IShutterConfig cfg,
Dictionary validatorsInfo,
Random rnd
) : ShutterApi(abiEncoder, blockTree, ecdsa, logFinder, receiptStorage,
- logManager, specProvider, timestamper, worldStateManager, cfg, validatorsInfo, ShutterTestsCommon.SlotLength)
+ logManager, specProvider, timestamper, worldStateManager, fileSystem,
+ keyStoreConfig, cfg, validatorsInfo, ShutterTestsCommon.SlotLength, IPAddress.None)
{
public int EonUpdateCalled = 0;
public int KeysValidated = 0;
@@ -110,7 +116,7 @@ protected override async Task OnKeysReceived(Dto.DecryptionKeys decryptionKeys)
// fake out P2P module
- protected override void InitP2P(IShutterConfig cfg, ILogManager logManager)
+ protected override void InitP2P(IPAddress _)
{
P2P = Substitute.For();
}
diff --git a/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs b/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs
index 03b157963df..612414beca8 100644
--- a/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs
+++ b/src/Nethermind/Nethermind.Shutter.Test/ShutterTestsCommon.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.IO.Abstractions;
using Nethermind.Abi;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Receipts;
@@ -11,6 +12,7 @@
using Nethermind.Core.Specs;
using Nethermind.Crypto;
using Nethermind.Facade.Find;
+using Nethermind.KeyStore.Config;
using Nethermind.Logging;
using Nethermind.Shutter.Config;
using Nethermind.Specs;
@@ -56,7 +58,8 @@ public static ShutterApiSimulator InitApi(Random rnd, ITimestamper? timestamper
eventSimulator ?? InitEventSimulator(rnd),
AbiEncoder, blockTree, Ecdsa, logFinder, receiptStorage,
LogManager, SpecProvider, timestamper ?? Substitute.For(),
- worldStateManager, Cfg, [], rnd
+ worldStateManager, Substitute.For(),
+ Substitute.For(), Cfg, [], rnd
);
}
@@ -64,7 +67,8 @@ public static ShutterApiSimulator InitApi(Random rnd, MergeTestBlockchain chain,
=> new(
eventSimulator ?? InitEventSimulator(rnd),
AbiEncoder, chain.BlockTree.AsReadOnly(), chain.EthereumEcdsa, chain.LogFinder, chain.ReceiptStorage,
- chain.LogManager, chain.SpecProvider, timestamper ?? chain.Timestamper, chain.WorldStateManager, Cfg, [], rnd
+ chain.LogManager, chain.SpecProvider, timestamper ?? chain.Timestamper, chain.WorldStateManager,
+ Substitute.For(), Substitute.For(), Cfg, [], rnd
);
public static ShutterEventSimulator InitEventSimulator(Random rnd)
diff --git a/src/Nethermind/Nethermind.Shutter/Config/IShutterConfig.cs b/src/Nethermind/Nethermind.Shutter/Config/IShutterConfig.cs
index 7bc477ae4c8..f96b1b8c0dc 100644
--- a/src/Nethermind/Nethermind.Shutter/Config/IShutterConfig.cs
+++ b/src/Nethermind/Nethermind.Shutter/Config/IShutterConfig.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
+using System.Linq;
using Multiformats.Address;
using Nethermind.Config;
using Nethermind.Core;
@@ -11,15 +12,6 @@ namespace Nethermind.Shutter.Config;
public interface IShutterConfig : IConfig
{
- // todo: replace with bootnodes when peer discovery added
- private const string DefaultP2PAddresses =
-@"/ip4/139.59.130.109/tcp/23003/p2p/12D3KooWRZoofMsnpsjkgvfPQUyGXZQnn7EVnb4tw4ghNfwMnnsj,
-/ip4/167.71.169.248/tcp/23003/p2p/12D3KooWGH3VxoSQXZ6wUuCmsv5caGQnhwfGejbkXH6uS2r7sehA,
-/ip4/139.59.130.109/tcp/23003/p2p/12D3KooWNxTiw7CvD1fuyye5P8qPhKTTrRBW6wwZwMdqdTxjYF2H,
-/ip4/178.128.192.239/tcp/23003/p2p/12D3KooWCdpkipTiuzVMfkV7yLLgqbFeAL8WmEP78hCoBGBYLugN,
-/ip4/45.55.192.248/tcp/23003/p2p/12D3KooWMPuubKqksfMxvLwEBDScaopTdvPLr5J5SMmBEo2zkcMz,
-/ip4/178.128.126.237/tcp/23003/p2p/12D3KooWAg1pGUDAfFWSZftpN3JjBfLUCGLQcZApJHv2VntdMS9U";
-
[ConfigItem(Description = "Whether to enable Shutter.", DefaultValue = "false")]
bool Enabled { get; set; }
@@ -28,27 +20,27 @@ public interface IShutterConfig : IConfig
string? ValidatorInfoFile { get; set; }
[ConfigItem(Description = "The address of the Shutter sequencer contract.",
- DefaultValue = "0xc5C4b277277A1A8401E0F039dfC49151bA64DC2E")]
+ DefaultValue = "null")]
string? SequencerContractAddress { get; set; }
[ConfigItem(Description = "The address of the Shutter validator registry contract.",
- DefaultValue = "0xefCC23E71f6bA9B22C4D28F7588141d44496A6D6")]
+ DefaultValue = "null")]
string? ValidatorRegistryContractAddress { get; set; }
[ConfigItem(Description = "The address of the Shutter key broadcast contract.",
- DefaultValue = "0x626dB87f9a9aC47070016A50e802dd5974341301")]
+ DefaultValue = "null")]
string? KeyBroadcastContractAddress { get; set; }
[ConfigItem(Description = "The address of the Shutter keyper set manager contract.",
- DefaultValue = "0x7C2337f9bFce19d8970661DA50dE8DD7d3D34abb")]
+ DefaultValue = "null")]
string? KeyperSetManagerContractAddress { get; set; }
[ConfigItem(Description = "The p2p addresses of the Shutter Keyper network bootnodes.",
- DefaultValue = DefaultP2PAddresses)]
+ DefaultValue = null)]
string[]? BootnodeP2PAddresses { get; set; }
[ConfigItem(Description = "Instance ID of Shutter keyper set.",
- DefaultValue = "1000")]
+ DefaultValue = "0")]
ulong InstanceID { get; set; }
[ConfigItem(Description = "The port to connect to Shutter P2P network with.",
@@ -64,6 +56,9 @@ public interface IShutterConfig : IConfig
HiddenFromDocs = true)]
string? P2PAgentVersion { get; set; }
+ [ConfigItem(Description = "The filename to use for the Shutter P2P key. If this not specified, the key is autogenerated in `shutter.key.plain` file.")]
+ string ShutterKeyFile { get; set; }
+
[ConfigItem(Description = "The Shutter validator registry message version.",
DefaultValue = "0", HiddenFromDocs = true)]
ulong ValidatorRegistryMessageVersion { get; set; }
@@ -80,7 +75,7 @@ public interface IShutterConfig : IConfig
DefaultValue = "true", HiddenFromDocs = true)]
bool Validator { get; set; }
- public void Validate()
+ public void Validate(out Multiaddress[] bootnodeP2PAddresses)
{
if (Validator && ValidatorInfoFile is null)
{
@@ -127,16 +122,13 @@ public void Validate()
throw new ArgumentNullException(nameof(BootnodeP2PAddresses));
}
- foreach (string addr in BootnodeP2PAddresses)
+ try
+ {
+ bootnodeP2PAddresses = BootnodeP2PAddresses.Select(addr => Multiaddress.Decode(addr)).ToArray();
+ }
+ catch (NotSupportedException e)
{
- try
- {
- Multiaddress.Decode(addr);
- }
- catch (NotSupportedException)
- {
- throw new ArgumentException($"Could not decode Shutter keyper p2p address \"{addr}\".");
- }
+ throw new ArgumentException($"Could not decode Shutter bootnode p2p addresses.", e);
}
}
}
diff --git a/src/Nethermind/Nethermind.Shutter/Config/ShutterConfig.cs b/src/Nethermind/Nethermind.Shutter/Config/ShutterConfig.cs
index 1e0e9c662f3..a8ed781e0a8 100644
--- a/src/Nethermind/Nethermind.Shutter/Config/ShutterConfig.cs
+++ b/src/Nethermind/Nethermind.Shutter/Config/ShutterConfig.cs
@@ -16,6 +16,7 @@ public class ShutterConfig : IShutterConfig
public string? ValidatorInfoFile { get; set; }
public string? P2PProtocolVersion { get; set; } = "/shutter/0.1.0";
public string? P2PAgentVersion { get; set; } = "github.com/shutter-network/rolling-shutter/rolling-shutter";
+ public string ShutterKeyFile { get; set; } = "shutter.key.plain";
public ulong ValidatorRegistryMessageVersion { get; set; } = 0;
public ulong InstanceID { get; set; } = 0;
public int EncryptedGasLimit { get; set; } = 10000000;
diff --git a/src/Nethermind/Nethermind.Shutter/IShutterApi.cs b/src/Nethermind/Nethermind.Shutter/IShutterApi.cs
index c6ed5544372..4fff37c21bf 100644
--- a/src/Nethermind/Nethermind.Shutter/IShutterApi.cs
+++ b/src/Nethermind/Nethermind.Shutter/IShutterApi.cs
@@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
+using Multiformats.Address;
using Nethermind.Consensus;
namespace Nethermind.Shutter;
@@ -10,7 +11,7 @@ namespace Nethermind.Shutter;
public interface IShutterApi
{
ShutterTxSource TxSource { get; }
- Task StartP2P(CancellationTokenSource? cancellationTokenSource = null);
+ Task StartP2P(Multiaddress[] bootnodeP2PAddresses, CancellationTokenSource? cancellationTokenSource = null);
ShutterBlockImprovementContextFactory GetBlockImprovementContextFactory(IBlockProducer blockProducer);
ValueTask DisposeAsync();
}
diff --git a/src/Nethermind/Nethermind.Shutter/IShutterP2P.cs b/src/Nethermind/Nethermind.Shutter/IShutterP2P.cs
index 43f6bdb38e1..d72baa359c4 100644
--- a/src/Nethermind/Nethermind.Shutter/IShutterP2P.cs
+++ b/src/Nethermind/Nethermind.Shutter/IShutterP2P.cs
@@ -4,11 +4,12 @@
using System;
using System.Threading;
using System.Threading.Tasks;
+using Multiformats.Address;
namespace Nethermind.Shutter;
public interface IShutterP2P
{
- Task Start(Func onKeysReceived, CancellationTokenSource? cts = null);
+ Task Start(Multiaddress[] bootnodeP2PAddresses, Func onKeysReceived, CancellationTokenSource? cts = null);
ValueTask DisposeAsync();
}
diff --git a/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj b/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj
index 5f7acfe37b8..63efbd0fa08 100644
--- a/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj
+++ b/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj
@@ -31,6 +31,7 @@
+
diff --git a/src/Nethermind/Nethermind.Shutter/ShutterApi.cs b/src/Nethermind/Nethermind.Shutter/ShutterApi.cs
index 91b53f6a17d..7c87a7bf7a7 100644
--- a/src/Nethermind/Nethermind.Shutter/ShutterApi.cs
+++ b/src/Nethermind/Nethermind.Shutter/ShutterApi.cs
@@ -3,8 +3,11 @@
using System;
using System.Collections.Generic;
+using System.IO.Abstractions;
+using System.Net;
using System.Threading;
using System.Threading.Tasks;
+using Multiformats.Address;
using Nethermind.Abi;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Find;
@@ -15,6 +18,7 @@
using Nethermind.Core.Specs;
using Nethermind.Crypto;
using Nethermind.Facade.Find;
+using Nethermind.KeyStore.Config;
using Nethermind.Logging;
using Nethermind.Shutter.Config;
using Nethermind.State;
@@ -41,6 +45,8 @@ public class ShutterApi : IShutterApi
private readonly ReadOnlyTxProcessingEnvFactory _txProcessingEnvFactory;
private readonly IAbiEncoder _abiEncoder;
private readonly ILogManager _logManager;
+ private readonly IFileSystem _fileSystem;
+ private readonly IKeyStoreConfig _keyStoreConfig;
private readonly IShutterConfig _cfg;
private readonly TimeSpan _blockWaitCutoff;
@@ -54,9 +60,12 @@ public ShutterApi(
ISpecProvider specProvider,
ITimestamper timestamper,
IWorldStateManager worldStateManager,
+ IFileSystem fileSystem,
+ IKeyStoreConfig keyStoreConfig,
IShutterConfig cfg,
Dictionary validatorsInfo,
- TimeSpan slotLength
+ TimeSpan slotLength,
+ IPAddress ip
)
{
_cfg = cfg;
@@ -65,6 +74,8 @@ TimeSpan slotLength
_abiEncoder = abiEncoder;
_logManager = logManager;
_slotLength = slotLength;
+ _fileSystem = fileSystem;
+ _keyStoreConfig = keyStoreConfig;
_blockUpToDateCutoff = slotLength;
_blockWaitCutoff = _slotLength / 3;
@@ -92,11 +103,11 @@ TimeSpan slotLength
KeyValidator = new ShutterKeyValidator(_cfg, Eon, logManager);
- InitP2P(_cfg, logManager);
+ InitP2P(ip);
}
- public Task StartP2P(CancellationTokenSource? cancellationTokenSource = null)
- => P2P!.Start(OnKeysReceived, cancellationTokenSource);
+ public Task StartP2P(Multiaddress[] bootnodeP2PAddresses, CancellationTokenSource? cancellationTokenSource = null)
+ => P2P!.Start(bootnodeP2PAddresses, OnKeysReceived, cancellationTokenSource);
public ShutterBlockImprovementContextFactory GetBlockImprovementContextFactory(IBlockProducer blockProducer)
{
@@ -138,16 +149,14 @@ protected virtual async Task OnKeysReceived(Dto.DecryptionKeys decryptionKeys)
TxSource.LoadTransactions(head, parentHeader, keys.Value);
}
- protected virtual void InitP2P(IShutterConfig cfg, ILogManager logManager)
+ protected virtual void InitP2P(IPAddress ip)
{
- P2P = new ShutterP2P(cfg, logManager);
+ P2P = new ShutterP2P(_cfg, _logManager, _fileSystem, _keyStoreConfig, ip);
}
protected virtual IShutterEon InitEon()
=> new ShutterEon(_readOnlyBlockTree, _txProcessingEnvFactory, _abiEncoder, _cfg, _logManager);
protected virtual ShutterTime InitTime(ISpecProvider specProvider, ITimestamper timestamper)
- {
- return new(specProvider.BeaconChainGenesisTimestamp!.Value * 1000, timestamper, _slotLength, _blockUpToDateCutoff);
- }
+ => new(specProvider.BeaconChainGenesisTimestamp!.Value * 1000, timestamper, _slotLength, _blockUpToDateCutoff);
}
diff --git a/src/Nethermind/Nethermind.Shutter/ShutterP2P.cs b/src/Nethermind/Nethermind.Shutter/ShutterP2P.cs
index 6bd04185038..726df4f29db 100644
--- a/src/Nethermind/Nethermind.Shutter/ShutterP2P.cs
+++ b/src/Nethermind/Nethermind.Shutter/ShutterP2P.cs
@@ -10,14 +10,15 @@
using System.Threading.Tasks;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
-using System.Collections.Generic;
using Multiformats.Address;
using Nethermind.Shutter.Config;
using Nethermind.Logging;
-using Nethermind.Core.Extensions;
using ILogger = Nethermind.Logging.ILogger;
using System.Threading.Channels;
using Google.Protobuf;
+using System.IO.Abstractions;
+using Nethermind.KeyStore.Config;
+using System.Net;
namespace Nethermind.Shutter;
@@ -27,6 +28,8 @@ public class ShutterP2P : IShutterP2P
private readonly IShutterConfig _cfg;
private readonly Channel _msgQueue = Channel.CreateBounded(1000);
private readonly PubsubRouter _router;
+ private readonly PubsubPeerDiscoveryProtocol _disc;
+ private readonly PeerStore _peerStore;
private readonly ILocalPeer _peer;
private readonly ServiceProvider _serviceProvider;
private CancellationTokenSource? _cts;
@@ -35,7 +38,7 @@ public class ShutterP2P : IShutterP2P
public class ShutterP2PException(string message, Exception? innerException = null) : Exception(message, innerException);
- public ShutterP2P(IShutterConfig shutterConfig, ILogManager logManager)
+ public ShutterP2P(IShutterConfig shutterConfig, ILogManager logManager, IFileSystem fileSystem, IKeyStoreConfig keyStoreConfig, IPAddress ip)
{
_logger = logManager.GetClassLogger();
_cfg = shutterConfig;
@@ -55,6 +58,9 @@ public ShutterP2P(IShutterConfig shutterConfig, ILogManager logManager)
HighestDegree = 6,
LazyDegree = 3
})
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton(sp => sp.GetService()!.Build())
//.AddSingleton(new NethermindLoggerFactory(logManager))
// .AddLogging(builder =>
// builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace)
@@ -67,9 +73,12 @@ public ShutterP2P(IShutterConfig shutterConfig, ILogManager logManager)
.BuildServiceProvider();
IPeerFactory peerFactory = _serviceProvider!.GetService()!;
- _peer = peerFactory.Create(new Identity(), "/ip4/0.0.0.0/tcp/" + _cfg.P2PPort);
+
+ Identity identity = GetPeerIdentity(fileSystem, _cfg, keyStoreConfig);
+ _peer = peerFactory.Create(identity, $"/ip4/{ip}/tcp/{_cfg.P2PPort}");
_router = _serviceProvider!.GetService()!;
- ITopic topic = _router.Subscribe("decryptionKeys");
+ _disc = new(_router, _peerStore = _serviceProvider.GetService()!, new PubsubPeerDiscoverySettings() { Interval = 300 }, _peer);
+ ITopic topic = _router.GetTopic("decryptionKeys");
topic.OnMessage += (byte[] msg) =>
{
@@ -78,13 +87,12 @@ public ShutterP2P(IShutterConfig shutterConfig, ILogManager logManager)
};
}
- public async Task Start(Func onKeysReceived, CancellationTokenSource? cts = null)
+ public async Task Start(Multiaddress[] bootnodeP2PAddresses, Func onKeysReceived, CancellationTokenSource? cts = null)
{
- MyProto proto = new();
_cts = cts ?? new();
- _ = _router!.RunAsync(_peer, proto, token: _cts.Token);
- proto.SetupFinished().GetAwaiter().GetResult();
- ConnectToPeers(proto, _cfg.BootnodeP2PAddresses!);
+ _ = _router!.RunAsync(_peer, token: _cts.Token);
+ _ = _disc.DiscoverAsync(_peer.Address, _cts.Token);
+ _peerStore.Discover(bootnodeP2PAddresses);
if (_logger.IsInfo) _logger.Info($"Started Shutter P2P: {_peer.Address}");
@@ -128,19 +136,26 @@ public async ValueTask DisposeAsync()
await (_cts?.CancelAsync() ?? Task.CompletedTask);
}
- private class MyProto : IDiscoveryProtocol
+ private Identity GetPeerIdentity(IFileSystem fileSystem, IShutterConfig shutterConfig, IKeyStoreConfig keyStoreConfig)
{
- private readonly TaskCompletionSource taskCompletionSource = new();
- public Func? OnAddPeer { get; set; }
- public Func? OnRemovePeer { get; set; }
-
- public Task SetupFinished() => taskCompletionSource.Task;
+ string fp = shutterConfig.ShutterKeyFile.GetApplicationResourcePath(keyStoreConfig.KeyStoreDirectory);
+ Identity identity;
- public Task DiscoverAsync(Multiaddress localPeerAddr, CancellationToken token = default)
+ if (fileSystem.File.Exists(fp))
{
- taskCompletionSource.TrySetResult();
- return Task.CompletedTask;
+ if (_logger.IsInfo) _logger.Info("Loading Shutter P2P identity from disk.");
+ identity = new(fileSystem.File.ReadAllBytes(fp));
}
+ else
+ {
+ if (_logger.IsInfo) _logger.Info("Generating new Shutter P2P identity.");
+ identity = new();
+ string keyStoreDirectory = keyStoreConfig.KeyStoreDirectory.GetApplicationResourcePath();
+ fileSystem.Directory.CreateDirectory(keyStoreDirectory);
+ fileSystem.File.WriteAllBytes(fp, identity.PrivateKey!.Data.ToByteArray());
+ }
+
+ return identity;
}
private void ProcessP2PMessage(byte[] msg, Func onKeysReceived)
@@ -164,14 +179,4 @@ private void ProcessP2PMessage(byte[] msg, Func onKeys
if (_logger.IsDebug) _logger.Warn($"Could not parse Shutter decryption keys: {e}");
}
}
-
- private static void ConnectToPeers(MyProto proto, IEnumerable p2pAddresses)
- {
- // shuffle peers to connect to random subset of keypers
- int seed = (int)(DateTimeOffset.Now.ToUnixTimeSeconds() % int.MaxValue);
- foreach (string addr in p2pAddresses.Shuffle(new Random(seed)))
- {
- proto.OnAddPeer?.Invoke([addr]);
- }
- }
}
diff --git a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs
index 04b6a444699..bc75443016c 100644
--- a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs
+++ b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs
@@ -16,6 +16,8 @@
using Nethermind.Serialization.Json;
using System.Threading;
using Nethermind.Config;
+using Multiformats.Address;
+using Nethermind.KeyStore.Config;
namespace Nethermind.Shutter;
@@ -70,12 +72,14 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I
if (_api.SpecProvider is null) throw new ArgumentNullException(nameof(_api.SpecProvider));
if (_api.ReceiptFinder is null) throw new ArgumentNullException(nameof(_api.ReceiptFinder));
if (_api.WorldStateManager is null) throw new ArgumentNullException(nameof(_api.WorldStateManager));
+ if (_api.IpResolver is null) throw new ArgumentNullException(nameof(_api.IpResolver));
if (_logger.IsInfo) _logger.Info("Initializing Shutter block producer.");
+ Multiaddress[] bootnodeP2PAddresses;
try
{
- _shutterConfig!.Validate();
+ _shutterConfig!.Validate(out bootnodeP2PAddresses);
}
catch (ArgumentException e)
{
@@ -105,12 +109,15 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I
_api.SpecProvider,
_api.Timestamper,
_api.WorldStateManager,
+ _api.FileSystem,
+ _api.Config(),
_shutterConfig,
validatorsInfo,
- TimeSpan.FromSeconds(_blocksConfig!.SecondsPerSlot)
+ TimeSpan.FromSeconds(_blocksConfig!.SecondsPerSlot),
+ _api.IpResolver.ExternalIp
);
- _ = _shutterApi.StartP2P(_cts);
+ _ = _shutterApi.StartP2P(bootnodeP2PAddresses, _cts);
}
return consensusPlugin.InitBlockProducer(_shutterApi is null ? txSource : _shutterApi.TxSource.Then(txSource));