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

[new] PART-1 NamedPipeService #3452

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ jobs:
dotnet test ./tests/Neo.Plugins.RpcServer.Tests --output ./bin/tests/Neo.Plugins.RpcServer.Tests
dotnet test ./tests/Neo.Plugins.Storage.Tests --output ./bin/tests/Neo.Plugins.Storage.Tests
dotnet test ./tests/Neo.Plugins.ApplicationLogs.Tests --output ./bin/tests/Neo.Plugins.ApplicationLogs.Tests
dotnet test ./tests/Neo.Plugins.NamedPipeService.Tests --output ./bin/tests/Neo.Plugins.NamedPipeService.Tests

- name: Coveralls
if: matrix.os == 'ubuntu-latest'
Expand All @@ -109,6 +110,7 @@ jobs:
${{ github.workspace }}/tests/Neo.Plugins.Storage.Tests/TestResults/coverage.info
${{ github.workspace }}/tests/Neo.Plugins.ApplicationLogs.Tests/TestResults/coverage.info
${{ github.workspace }}/tests/Neo.Extensions.Tests/TestResults/coverage.info
${{ github.workspace }}/tests/Neo.Plugins.NamedPipeService.Tests/TestResults/coverage.info

PublishPackage:
if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
Expand Down
16 changes: 15 additions & 1 deletion neo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcClient", "src\Plugins\Rp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Plugins.ApplicationLogs.Tests", "tests\Neo.Plugins.ApplicationLogs.Tests\Neo.Plugins.ApplicationLogs.Tests.csproj", "{8C866DC8-2E55-4399-9563-2F47FD4602EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Extensions.Tests", "tests\Neo.Extensions.Tests\Neo.Extensions.Tests.csproj", "{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Extensions.Tests", "tests\Neo.Extensions.Tests\Neo.Extensions.Tests.csproj", "{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NamedPipeService", "src\Plugins\NamedPipeService\NamedPipeService.csproj", "{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.NamedPipeService.Tests", "tests\Neo.Plugins.NamedPipeService.Tests\Neo.Plugins.NamedPipeService.Tests.csproj", "{38599EC3-D97C-408C-BD3B-E712831955D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -228,6 +232,14 @@ Global
{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.Build.0 = Release|Any CPU
{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3}.Release|Any CPU.Build.0 = Release|Any CPU
{38599EC3-D97C-408C-BD3B-E712831955D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38599EC3-D97C-408C-BD3B-E712831955D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38599EC3-D97C-408C-BD3B-E712831955D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38599EC3-D97C-408C-BD3B-E712831955D0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -269,6 +281,8 @@ Global
{185ADAFC-BFC6-413D-BC2E-97F9FB0A8AF0} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{8C866DC8-2E55-4399-9563-2F47FD4602EC} = {7F257712-D033-47FF-B439-9D4320D06599}
{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
{DACD4CFA-3D24-4329-A1D3-D5EE9E268CE3} = {C2DC830A-327A-42A7-807D-295216D30DBB}
{38599EC3-D97C-408C-BD3B-E712831955D0} = {7F257712-D033-47FF-B439-9D4320D06599}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}
Expand Down
30 changes: 30 additions & 0 deletions src/Neo.Extensions/ObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ObjectExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;

namespace Neo.Extensions
{
public static class ObjectExtensions
{
public static TResult TryCatch<TSource, TResult>(this TSource obj, Func<TSource, TResult> func, TResult defaultOnError)
{
try
{
return func(obj);
}
catch
{
return defaultOnError;
}
}
}
}
83 changes: 83 additions & 0 deletions src/Neo.Extensions/TaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// TaskExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Threading.Tasks;

namespace Neo.Extensions
{
public static class TaskExtensions
{
private const int DefaultTimeoutSeconds = 10;

public static ValueTask<TResult> DefaultTimeout<TResult>(this ValueTask<TResult> valueTask) =>
TimeoutAfter(valueTask, TimeSpan.FromSeconds(DefaultTimeoutSeconds));

public static ValueTask DefaultTimeout(this ValueTask valueTask) =>
TimeoutAfter(valueTask, TimeSpan.FromSeconds(DefaultTimeoutSeconds));

public static Task<TResult> DefaultTimeout<TResult>(this Task<TResult> task) =>
TimeoutAfter(task, TimeSpan.FromSeconds(DefaultTimeoutSeconds));

public static Task DefaultTimeout(this Task task)
=> TimeoutAfter(task, TimeSpan.FromSeconds(DefaultTimeoutSeconds));

public static async ValueTask<TResult> TimeoutAfter<TResult>(this ValueTask<TResult> valueTask, TimeSpan timeout)
{
#if NET5_0_OR_GREATER
shargon marked this conversation as resolved.
Show resolved Hide resolved
return await valueTask.AsTask().WaitAsync(timeout).ConfigureAwait(false);
#else
var task = valueTask.AsTask();
if (task.Wait(timeout))
return await task.ConfigureAwait(false);
else
throw new TimeoutException();
#endif
}

public static async ValueTask TimeoutAfter(this ValueTask valueTask, TimeSpan timeout)
{
#if NET5_0_OR_GREATER
await valueTask.AsTask().WaitAsync(timeout).ConfigureAwait(false);
#else
var task = valueTask.AsTask();
if (task.Wait(timeout))
await task.ConfigureAwait(false);
else
throw new TimeoutException();
#endif
}

public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
{
#if NET5_0_OR_GREATER
return await task.WaitAsync(timeout).ConfigureAwait(false);
#else
if (task.Wait(timeout))
return await task.ConfigureAwait(false);
else
throw new TimeoutException();
#endif
}

public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
{
#if NET5_0_OR_GREATER
await task.WaitAsync(timeout).ConfigureAwait(false);
#else
if (task.Wait(timeout))
await task.ConfigureAwait(false);
else
throw new TimeoutException();
#endif
}
}
}
116 changes: 116 additions & 0 deletions src/Neo/Cryptography/Crc32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// Crc32.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Collections.Generic;
using System.Security.Cryptography;

namespace Neo.Cryptography
{
public sealed class Crc32 : HashAlgorithm
{
public static readonly uint DefaultPolynomial = 0xedb88320u;
public static readonly uint DefaultSeed = 0xffffffffu;

private static uint[] s_defaultTable;

public override int HashSize => 32;

private readonly uint _seed;
private readonly uint[] _table;
private uint _hash;

public Crc32() : this(DefaultPolynomial, DefaultSeed)
{

}

public Crc32(
uint polynomial,
uint seed)
{
if (BitConverter.IsLittleEndian)
throw new PlatformNotSupportedException("Not supported on Big Endian processors");

_table = InitializeTable(polynomial);
_seed = seed;
}

public override void Initialize()
{
_hash = _seed;
}

protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
_hash = CalculateHash(_table, _hash, array, ibStart, cbSize);
}

protected override byte[] HashFinal()
{
var hashBuffer = UInt32ToBigEndianBytes(~_hash);
HashValue = hashBuffer;
return hashBuffer;
}

public static uint Compute(byte[] buffer) =>
Compute(DefaultSeed, buffer);

public static uint Compute(uint seed, byte[] buffer) =>
Compute(DefaultPolynomial, seed, buffer);

public static uint Compute(uint polynomial, uint seed, byte[] buffer) =>
~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);

private static uint[] InitializeTable(uint polynomial)
{
if (polynomial == DefaultPolynomial && s_defaultTable != null)
return s_defaultTable;

var createTable = new uint[256];
for (var i = 0u; i < 256u; i++)
{
var entry = i;
for (var j = 0; j < 8; j++)
{
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry >>= 1;
}
createTable[i] = entry;
}

if (polynomial == DefaultPolynomial)
s_defaultTable = createTable;

return createTable;
}

private static uint CalculateHash(uint[] table, uint seed, IList<byte> buffer, int start, int size)
{
var hash = seed;
for (var i = start; i < start + size; i++)
hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff];
return hash;
}

private static byte[] UInt32ToBigEndianBytes(uint value)
{
var result = BitConverter.GetBytes(value);

if (BitConverter.IsLittleEndian)
Array.Reverse(result);

return result;
}
}
}
44 changes: 44 additions & 0 deletions src/Plugins/NamedPipeService/Buffers/MemoryPoolBlock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// MemoryPoolBlock.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Buffers;
using System.Runtime.InteropServices;

namespace Neo.Plugins.Buffers
{
internal sealed class MemoryPoolBlock : IMemoryOwner<byte>
{
public PinnedBlockMemoryPool Pool { get; }

internal MemoryPoolBlock(
PinnedBlockMemoryPool pool,
int length)
{
Pool = pool;

var pinnedArray = GC.AllocateUninitializedArray<byte>(length, pinned: true);

Memory = MemoryMarshal.CreateFromPinnedArray(pinnedArray, 0, pinnedArray.Length);
}

#region IMemoryOwner

public Memory<byte> Memory { get; }

void IDisposable.Dispose()
{
Pool.Return(this);
}

#endregion
}
}
68 changes: 68 additions & 0 deletions src/Plugins/NamedPipeService/Buffers/PinnedBlockMemoryPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// PinnedBlockMemoryPool.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Buffers;
using System.Collections.Concurrent;

namespace Neo.Plugins.Buffers
{
internal sealed class PinnedBlockMemoryPool : MemoryPool<byte>
{
private const int AnySize = -1;

private static readonly int s_blockSize = 4096;

public static int BlockSize => s_blockSize;

public override int MaxBufferSize { get; } = s_blockSize;

private readonly ConcurrentQueue<MemoryPoolBlock> _blocks = new();
private readonly object _disposedSync = new();

private bool _isDisposed;

public override IMemoryOwner<byte> Rent(int size = AnySize)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan(size, s_blockSize);
ObjectDisposedException.ThrowIf(_isDisposed, this);

if (_blocks.TryDequeue(out var block))
return block;

return new MemoryPoolBlock(this, BlockSize);
}

internal void Return(MemoryPoolBlock block)
{
if (_isDisposed == false)
_blocks.Enqueue(block);
}

protected override void Dispose(bool disposing)
{
if (_isDisposed)
return;

lock (_disposedSync)
{
_isDisposed = true;

if (disposing)
{
while (_blocks.TryDequeue(out _))
{
}
}
}
}
}
}
Loading
Loading