Skip to content

Commit bbc0977

Browse files
committed
Add dotnet tcp/noise/yamux
1 parent 09d15c0 commit bbc0977

File tree

8 files changed

+232
-2
lines changed

8 files changed

+232
-2
lines changed

Diff for: multidim-interop/Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ RUST_SUBDIRS := $(wildcard impl/rust/*/.)
44
NIM_SUBDIRS := $(wildcard impl/nim/*/.)
55
ZIG_SUBDIRS := $(wildcard impl/zig/*/.)
66
JAVA_SUBDIRS := $(wildcard impl/java/*/.)
7+
DOTNET_SUBDIRS := $(wildcard dotnet/*/.)
78

8-
all: $(GO_SUBDIRS) $(JS_SUBDIRS) $(RUST_SUBDIRS) $(NIM_SUBDIRS) $(ZIG_SUBDIRS) $(JAVA_SUBDIRS)
9+
all: $(GO_SUBDIRS) $(JS_SUBDIRS) $(RUST_SUBDIRS) $(NIM_SUBDIRS) $(ZIG_SUBDIRS) $(JAVA_SUBDIRS) $(DOTNET_SUBDIRS)
910
$(JS_SUBDIRS):
1011
$(MAKE) -C $@
1112
$(GO_SUBDIRS):
@@ -18,5 +19,7 @@ $(ZIG_SUBDIRS):
1819
$(MAKE) -C $@
1920
$(JAVA_SUBDIRS):
2021
$(MAKE) -C $@
22+
$(DOTNET_SUBDIRS):
23+
$(MAKE) -C $@
2124

22-
.PHONY: $(GO_SUBDIRS) $(JS_SUBDIRS) $(RUST_SUBDIRS) $(NIM_SUBDIRS) $(ZIG_SUBDIRS) $(JAVA_SUBDIRS) all
25+
.PHONY: $(GO_SUBDIRS) $(JS_SUBDIRS) $(RUST_SUBDIRS) $(NIM_SUBDIRS) $(ZIG_SUBDIRS) $(JAVA_SUBDIRS) $(DOTNET_SUBDIRS) all

Diff for: multidim-interop/impl/dotnet/v1.0/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bin/
2+
obj/
3+
.vs/
4+
.vscode/
5+
image.json

Diff for: multidim-interop/impl/dotnet/v1.0/Dockerfile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
2+
WORKDIR /app
3+
4+
COPY . ./
5+
RUN dotnet restore
6+
RUN dotnet publish -c Release -o out
7+
8+
FROM mcr.microsoft.com/dotnet/runtime:7.0
9+
WORKDIR /app
10+
COPY --from=build-env /app/out .
11+
ENTRYPOINT ["dotnet", "TestPlansApp.dll"]

Diff for: multidim-interop/impl/dotnet/v1.0/Makefile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
image_name := dotnet-v1.0
2+
3+
all: image.json
4+
5+
image.json: Dockerfile Program.cs
6+
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh .
7+
docker image inspect ${image_name} -f "{{.Id}}" | \
8+
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
9+
10+
.PHONY: clean all
11+
12+
clean:
13+
rm -f bin/ obj/

Diff for: multidim-interop/impl/dotnet/v1.0/Program.cs

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
2+
// SPDX-License-Identifier: MIT
3+
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Nethermind.Libp2p.Core;
6+
using Nethermind.Libp2p.Protocols;
7+
using StackExchange.Redis;
8+
using System.Diagnostics;
9+
using System.Net.NetworkInformation;
10+
using Microsoft.Extensions.Logging;
11+
12+
try
13+
{
14+
string transport = Environment.GetEnvironmentVariable("transport")!;
15+
string muxer = Environment.GetEnvironmentVariable("muxer")!;
16+
string security = Environment.GetEnvironmentVariable("security")!;
17+
18+
bool isDialer = bool.Parse(Environment.GetEnvironmentVariable("is_dialer")!);
19+
string ip = Environment.GetEnvironmentVariable("ip") ?? "0.0.0.0";
20+
21+
string redisAddr = Environment.GetEnvironmentVariable("redis_addr") ?? "redis:6379";
22+
23+
int testTimeoutSeconds = int.Parse(Environment.GetEnvironmentVariable("test_timeout_seconds") ?? "180");
24+
25+
IPeerFactory peerFactory = new TestPlansPeerFactoryBuilder(transport, muxer, security).Build();
26+
27+
Log($"Connecting to redis at {redisAddr}...");
28+
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisAddr);
29+
IDatabase db = redis.GetDatabase();
30+
31+
if (isDialer)
32+
{
33+
ILocalPeer localPeer = peerFactory.Create(localAddr: $"/ip4/0.0.0.0/tcp/0");
34+
string? listenerAddr = null;
35+
while ((listenerAddr = db.ListRightPop("listenerAddr")) is null)
36+
{
37+
await Task.Delay(20);
38+
}
39+
40+
Log($"Dialing {listenerAddr}...");
41+
Stopwatch handshakeStartInstant = Stopwatch.StartNew();
42+
IRemotePeer remotePeer = await localPeer.DialAsync(listenerAddr);
43+
44+
Stopwatch pingIstant = Stopwatch.StartNew();
45+
await remotePeer.DialAsync<PingProtocol>();
46+
long pingRTT = pingIstant.ElapsedMilliseconds;
47+
48+
long handshakePlusOneRTT = handshakeStartInstant.ElapsedMilliseconds;
49+
50+
PrintResult($"{{\"handshakePlusOneRTTMillis\": {handshakePlusOneRTT}, \"pingRTTMilllis\": {pingRTT}}}");
51+
Log("Done");
52+
return 0;
53+
}
54+
else
55+
{
56+
if (ip == "0.0.0.0")
57+
{
58+
IEnumerable<UnicastIPAddressInformation> addresses = NetworkInterface.GetAllNetworkInterfaces()!
59+
.FirstOrDefault(i => i.Name == "eth0")!
60+
.GetIPProperties()
61+
.UnicastAddresses
62+
.Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
63+
64+
Log("Available addresses detected, picking the first: " + string.Join(",", addresses.Select(a => a.Address)));
65+
ip = addresses.First().Address.ToString()!;
66+
}
67+
Log("Starting to listen...");
68+
ILocalPeer localPeer = peerFactory.Create(localAddr: $"/ip4/{ip}/tcp/0");
69+
IListener listener = await localPeer.ListenAsync(localPeer.Address);
70+
listener.OnConnection += async (peer) => Log($"Connected {peer.Address}");
71+
Log($"Listening on {listener.Address}");
72+
db.ListRightPush(new RedisKey("listenerAddr"), new RedisValue(localPeer.Address.ToString()));
73+
await Task.Delay(testTimeoutSeconds * 1000);
74+
await listener.DisconnectAsync();
75+
return -1;
76+
}
77+
}
78+
catch (Exception ex)
79+
{
80+
Log(ex.Message);
81+
return -1;
82+
}
83+
84+
static void Log(string info) => Console.Error.WriteLine(info);
85+
static void PrintResult(string info) => Console.WriteLine(info);
86+
87+
class TestPlansPeerFactoryBuilder : PeerFactoryBuilderBase<TestPlansPeerFactoryBuilder, PeerFactory>
88+
{
89+
private readonly string transport;
90+
private readonly string? muxer;
91+
private readonly string? security;
92+
private static IPeerFactoryBuilder? defaultPeerFactoryBuilder;
93+
94+
public TestPlansPeerFactoryBuilder(string transport, string? muxer, string? security)
95+
: base(new ServiceCollection()
96+
.AddLogging(builder =>
97+
builder.SetMinimumLevel(LogLevel.Trace)
98+
.AddSimpleConsole(l =>
99+
{
100+
l.SingleLine = true;
101+
l.TimestampFormat = "[HH:mm:ss.FFF]";
102+
}))
103+
.AddScoped(_ => defaultPeerFactoryBuilder!)
104+
.BuildServiceProvider())
105+
{
106+
defaultPeerFactoryBuilder = this;
107+
this.transport = transport;
108+
this.muxer = muxer;
109+
this.security = security;
110+
}
111+
112+
private static readonly string[] stacklessProtocols = new[] { "quic", "quic-v1", "webtransport" };
113+
114+
protected override ProtocolStack BuildStack()
115+
{
116+
ProtocolStack stack = transport switch
117+
{
118+
"tcp" => Over<IpTcpProtocol>(),
119+
_ => throw new NotImplementedException(),
120+
};
121+
122+
if (!stacklessProtocols.Contains(transport))
123+
{
124+
stack = stack.Over<MultistreamProtocol>();
125+
stack = security switch
126+
{
127+
"noise" => stack.Over<NoiseProtocol>(),
128+
_ => throw new NotImplementedException(),
129+
};
130+
stack = stack.Over<MultistreamProtocol>();
131+
stack = muxer switch
132+
{
133+
"yamux" => stack.Over<YamuxProtocol>(),
134+
_ => throw new NotImplementedException(),
135+
};
136+
stack = stack.Over<MultistreamProtocol>();
137+
}
138+
139+
return stack.AddAppLayerProtocol<IdentifyProtocol>()
140+
.AddAppLayerProtocol<PingProtocol>();
141+
}
142+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="NRedisStack" Version="0.8.1" />
12+
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
13+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
15+
16+
<PackageReference Include="Nethermind.Libp2p.Core" Version="1.0.0-preview.27" />
17+
<PackageReference Include="Nethermind.Libp2p.Protocols.IpTcp" Version="1.0.0-preview.27" />
18+
<PackageReference Include="Nethermind.Libp2p.Protocols.Noise" Version="1.0.0-preview.27" />
19+
<PackageReference Include="Nethermind.Libp2p.Protocols.Ping" Version="1.0.0-preview.27" />
20+
<PackageReference Include="Nethermind.Libp2p.Protocols.Yamux" Version="1.0.0-preview.27" />
21+
<PackageReference Include="Nethermind.Libp2p.Protocols.Identify" Version="1.0.0-preview.27" />
22+
<PackageReference Include="Nethermind.Libp2p.Protocols.Multistream" Version="1.0.0-preview.27" />
23+
</ItemGroup>
24+
25+
</Project>

Diff for: multidim-interop/impl/dotnet/v1.0/TestPlansApp.sln

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.7.34018.315
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlansApp", "TestPlansApp.csproj", "{4B9D7919-740C-4EF0-8890-AB43E6102952}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{4B9D7919-740C-4EF0-8890-AB43E6102952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{4B9D7919-740C-4EF0-8890-AB43E6102952}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{4B9D7919-740C-4EF0-8890-AB43E6102952}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{4B9D7919-740C-4EF0-8890-AB43E6102952}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {7BF72338-A0C5-4E70-A0F1-54B1EB8BB378}
24+
EndGlobalSection
25+
EndGlobal

Diff for: multidim-interop/versions.ts

+6
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,10 @@ export const versions: Array<Version> = [
125125
secureChannels: ["tls", "noise"],
126126
muxers: ["mplex", "yamux"],
127127
},
128+
{
129+
id: "dotnet-v1.0",
130+
transports: ["tcp"],
131+
secureChannels: ["noise"],
132+
muxers: ["yamux"],
133+
},
128134
].map((v: Version) => (typeof v.containerImageID === "undefined" ? ({ ...v, containerImageID: canonicalImageIDLookup }) : v))

0 commit comments

Comments
 (0)