Skip to content
This repository has been archived by the owner on Jun 4, 2018. It is now read-only.

Commit

Permalink
Check RPC server version during client connect.
Browse files Browse the repository at this point in the history
Fixes #42.
  • Loading branch information
jrick committed Feb 25, 2016
1 parent f1b17da commit f2507cf
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions Paymetheus.Rpc/Paymetheus.Rpc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<Compile Include="ProcessExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ErrorHandling.cs" />
<Compile Include="SemanticVersion.cs" />
<Compile Include="TimeoutException.cs" />
<Compile Include="TransactionNotifications.cs" />
<Compile Include="TransportSecurity.cs" />
Expand Down
49 changes: 49 additions & 0 deletions Paymetheus.Rpc/SemanticVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2016 The btcsuite developers
// Licensed under the ISC license. See LICENSE file in the project root for full license information.

using System;

namespace Paymetheus.Rpc
{
public struct SemanticVersion
{
public SemanticVersion(uint major, uint minor, uint patch)
{
Major = major;
Minor = minor;
Patch = patch;
}

public uint Major { get; }
public uint Minor { get; }
public uint Patch { get; }

public override string ToString() => $"{Major}.{Minor}.{Patch}";

public static void AssertCompatible(SemanticVersion required, SemanticVersion actual)
{
if (required.Major != actual.Major)
throw IncompatibleVersionException.Major(required, actual);
if (required.Minor > actual.Minor)
throw IncompatibleVersionException.Minor(required, actual);
if (required.Minor == actual.Minor && required.Patch > actual.Patch)
throw IncompatibleVersionException.Patch(required, actual);
}
}

public class IncompatibleVersionException : Exception
{
private IncompatibleVersionException(string whatVersion, SemanticVersion required, SemanticVersion actual)
: base($"Incompatible {whatVersion} versions: required={required} actual={actual}")
{ }

public static IncompatibleVersionException Major(SemanticVersion required, SemanticVersion actual) =>
new IncompatibleVersionException("major", required, actual);

public static IncompatibleVersionException Minor(SemanticVersion required, SemanticVersion actual) =>
new IncompatibleVersionException("minor", required, actual);

public static IncompatibleVersionException Patch(SemanticVersion required, SemanticVersion actual) =>
new IncompatibleVersionException("patch", required, actual);
}
}
9 changes: 9 additions & 0 deletions Paymetheus.Rpc/WalletClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace Paymetheus.Rpc
{
public sealed class WalletClient : IDisposable
{
private static readonly SemanticVersion RequiredRpcServerVersion = new SemanticVersion(0, 3, 0);

public static void Initialize()
{
Environment.SetEnvironmentVariable("GRPC_SSL_CIPHER_SUITES", "HIGH+ECDSA");
Expand Down Expand Up @@ -67,6 +69,13 @@ public static async Task<WalletClient> ConnectAsync(string networkAddress, strin
await channel.ShutdownAsync();
throw new ConnectTimeoutException();
}

// Ensure the server is running a compatible version.
var versionClient = VersionService.NewClient(channel);
var response = await versionClient.VersionAsync(new VersionRequest(), deadline: deadline);
var serverVersion = new SemanticVersion(response.Major, response.Minor, response.Patch);
SemanticVersion.AssertCompatible(RequiredRpcServerVersion, serverVersion);

return new WalletClient(channel);
}

Expand Down

0 comments on commit f2507cf

Please sign in to comment.