gRPC connect to Concordium blockchain API with C#

Viewed 126

I realize that this a rather service specific subject, but I think that the reason for my problem is a general one, since I'm a novice in the gRPC arena.

I'm attempting to call a simple method PeerVersion in the Concordium blockchain gRPC API (https://github.com/Concordium/concordium-grpc-api) from a .NET Core 3.1 app, but I get what seems to be a rather general error in regard to SSL.

I can add that I have testet this call and others with BloomRPC (https://github.com/uw-labs/bloomrpc) and it works just fine.

You wont be able to call the API successfully without access to a Concordium node, but I recon that someone with better insight into gRPC than me, could maybe see what I'm doing wrong.

C# code

static async Task Main(string[] args)
{
    using var channel = GrpcChannel.ForAddress("https://192.168.1.18:10001"); // my local node running on the Concordium testnet

    var client = new Concordium.P2P.P2PClient(channel);

    var metadata = new Grpc.Core.Metadata() // required token for the API
    {
        { "authentication", "rpcadmin" }
    };

    var request = new Concordium.Empty();

    var reply = client.PeerVersion(request, metadata);

    Console.WriteLine("peer version: " + reply.Value);

    Console.WriteLine("press any key to exit...");

    Console.ReadKey();
}

When I run this I get the following exception. (Danish text reads "An existing connection was forcibly disconnected by an external host" or something like that).

-       $exception  {"Status(StatusCode=\"Unavailable\", Detail=\"Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. IOException: Unable to read data from the transport connection: En eksisterende forbindelse blev tvangsafbrudt af en ekstern vært.. SocketException: En eksisterende forbindelse blev tvangsafbrudt af en ekstern vært.\", DebugException=\"System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.IO.IOException: Unable to read data from the transport connection: En eksisterende forbindelse blev tvangsafbrudt af en ekstern vært..
 ---> System.Net.Sockets.SocketException (10054): En eksisterende forbindelse blev tvangsafbrudt af en ekstern vært.
   --- End of inner exception stack trace ---
   at System.Net.FixedSizeReader.ReadPacketAsync(Stream transport, AsyncProtocolRequest request)
   at System.Net.Security.SslStream.ThrowIfExceptional()
   at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Grpc.Net.Client.Internal.GrpcCall`2.RunCall(HttpRequestMessage request, Nullable`1 timeout)\")"}  Grpc.Core.RpcException

Is anyone able to give me some pointers as to what could be the problem here?

For anyone that knows BloobRPC, here is a screenshot of request and response. enter image description here

1 Answers

Ah, I got the answer to my problem elsewhere. It turns out that my assumption that the Concordium node requires a secure connection was wrong, in fact it doesn't support secure connections, so the URL was the wrong part.

So to fix the problem, I needed to create the client like this:

// to allow non secure connections
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

using var channel = GrpcChannel.ForAddress("http://192.168.1.18:10001");
Related