-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
457e092
commit 5c69d8b
Showing
2 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace Ipfs | ||
{ | ||
/// <summary> | ||
/// A node on the IPFS network. | ||
/// </summary> | ||
public class Peer : IEquatable<Peer> | ||
{ | ||
static MultiAddress[] noAddress = new MultiAddress[0]; | ||
const string unknown = "unknown/0.0"; | ||
|
||
/// <summary> | ||
/// Universally unique identifier. | ||
/// </summary> | ||
/// <value> | ||
/// This is the <see cref="MultiHash"/> of the peer's <see cref="PublicKey"/>. | ||
/// </value> | ||
public MultiHash Id { get; set; } | ||
|
||
/// <summary> | ||
/// The public key of the node. | ||
/// </summary> | ||
/// <value> | ||
/// The base 64 encoding of the node's public key. The default is <b>null</b> | ||
/// </value> | ||
public string PublicKey { get; set; } | ||
|
||
/// <summary> | ||
/// The multiple addresses of the node. | ||
/// </summary> | ||
/// <value> | ||
/// Where the peer can be found. The default is an empty sequence. | ||
/// </value> | ||
public IEnumerable<MultiAddress> Addresses { get; set; } = noAddress; | ||
|
||
/// <summary> | ||
/// The name and version of the IPFS software. | ||
/// </summary> | ||
/// <value> | ||
/// For example "go-ipfs/0.4.17/". | ||
/// </value> | ||
/// <remarks> | ||
/// There is no specification that describes the agent version string. The default | ||
/// is "unknown/0.0". | ||
/// </remarks> | ||
public string AgentVersion { get; set; } = unknown; | ||
|
||
/// <summary> | ||
/// The name and version of the supported IPFS protocol. | ||
/// </summary> | ||
/// <value> | ||
/// For example "ipfs/0.1.0". | ||
/// </value> | ||
/// <remarks> | ||
/// There is no specification that describes the protocol version string. The default | ||
/// is "unknown/0.0". | ||
/// </remarks> | ||
public string ProtocolVersion { get; set; } = unknown; | ||
|
||
/// <summary> | ||
/// Determines if the information on the peer is valid. | ||
/// </summary> | ||
/// <returns> | ||
/// <b>true</b> if all validation rules pass; otherwise <b>false</b>. | ||
/// </returns> | ||
/// <remarks> | ||
/// Verifies that | ||
/// <list type="bullet"> | ||
/// <item><description>The <see cref="Id"/> is defined</description></item> | ||
/// <item><description>The <see cref="Id"/> is a hash of the <see cref="PublicKey"/></description></item> | ||
/// </list> | ||
/// </remarks> | ||
public bool IsValid() | ||
{ | ||
if (Id == null) | ||
return false; | ||
if (PublicKey != null && !Id.Matches(Convert.FromBase64String(PublicKey))) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override int GetHashCode() | ||
{ | ||
return ToString().GetHashCode(); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override bool Equals(object obj) | ||
{ | ||
var that = obj as Peer; | ||
return (that == null) | ||
? false | ||
: this.ToString() == that.ToString(); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public bool Equals(Peer that) | ||
{ | ||
return this.ToString() == that.ToString(); | ||
} | ||
|
||
/// <summary> | ||
/// Value equality. | ||
/// </summary> | ||
public static bool operator ==(Peer a, Peer b) | ||
{ | ||
if (object.ReferenceEquals(a, b)) return true; | ||
if (object.ReferenceEquals(a, null)) return false; | ||
if (object.ReferenceEquals(b, null)) return false; | ||
|
||
return a.Equals(b); | ||
} | ||
|
||
/// <summary> | ||
/// Value inequality. | ||
/// </summary> | ||
public static bool operator !=(Peer a, Peer b) | ||
{ | ||
if (object.ReferenceEquals(a, b)) return false; | ||
if (object.ReferenceEquals(a, null)) return true; | ||
if (object.ReferenceEquals(b, null)) return true; | ||
|
||
return !a.Equals(b); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the <see cref="Base58"/> encoding of the <see cref="Id"/>. | ||
/// </summary> | ||
/// <returns> | ||
/// A Base58 representaton of the peer. | ||
/// </returns> | ||
public override string ToString() | ||
{ | ||
return Id == null ? string.Empty : Id.ToBase58(); | ||
} | ||
|
||
/// <summary> | ||
/// Implicit casting of a <see cref="string"/> to a <see cref="Peer"/>. | ||
/// </summary> | ||
/// <param name="s"> | ||
/// A <see cref="Base58"/> encoded <see cref="Id"/>. | ||
/// </param> | ||
/// <returns> | ||
/// A new <see cref="Peer"/>. | ||
/// </returns> | ||
/// <remarks> | ||
/// Equivalent to <code>new Peer { Id = s }</code> | ||
/// </remarks> | ||
static public implicit operator Peer(string s) | ||
{ | ||
return new Peer { Id = s }; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
using System; | ||
using System.Text; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System.IO; | ||
|
||
namespace Ipfs | ||
{ | ||
|
||
[TestClass] | ||
public class PeerTest | ||
{ | ||
const string marsId = "QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3"; | ||
const string plutoId = "QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM"; | ||
const string marsPublicKey = "CAASogEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKGUtbRQf+a9SBHFEruNAUatS/tsGUnHuCtifGrlbYPELD3UyyhWf/FYczBCavx3i8hIPEW2jQv4ehxQxi/cg9SHswZCQblSi0ucwTBFr8d40JEiyB9CcapiMdFQxdMgGvXEOQdLz1pz+UPUDojkdKZq8qkkeiBn7KlAoGEocnmpAgMBAAE="; | ||
|
||
[TestMethod] | ||
public new void ToString() | ||
{ | ||
Assert.AreEqual("", new Peer().ToString()); | ||
Assert.AreEqual(marsId, new Peer { Id = marsId }.ToString()); | ||
} | ||
|
||
[TestMethod] | ||
public void DefaultValues() | ||
{ | ||
var peer = new Peer(); | ||
Assert.AreEqual(null, peer.Id); | ||
Assert.AreEqual(0, peer.Addresses.Count()); | ||
Assert.AreEqual("unknown/0.0", peer.ProtocolVersion); | ||
Assert.AreEqual("unknown/0.0", peer.AgentVersion); | ||
Assert.AreEqual(null, peer.PublicKey); | ||
Assert.AreEqual(false, peer.IsValid()); // missing peer ID | ||
} | ||
|
||
[TestMethod] | ||
public void Validation_No_Id() | ||
{ | ||
var peer = new Peer(); | ||
Assert.AreEqual(false, peer.IsValid()); | ||
} | ||
|
||
[TestMethod] | ||
public void Validation_With_Id() | ||
{ | ||
Peer peer = marsId; | ||
Assert.AreEqual(true, peer.IsValid()); | ||
} | ||
|
||
[TestMethod] | ||
public void Validation_With_Id_Pubkey() | ||
{ | ||
var peer = new Peer | ||
{ | ||
Id = marsId, | ||
PublicKey = marsPublicKey | ||
}; | ||
Assert.AreEqual(true, peer.IsValid()); | ||
} | ||
|
||
[TestMethod] | ||
public void Validation_With_Id_Invalid_Pubkey() | ||
{ | ||
var peer = new Peer | ||
{ | ||
Id = plutoId, | ||
PublicKey = marsPublicKey | ||
}; | ||
Assert.AreEqual(false, peer.IsValid()); | ||
} | ||
|
||
[TestMethod] | ||
public void Value_Equality() | ||
{ | ||
var a0 = new Peer { Id = marsId }; | ||
var a1 = new Peer { Id = marsId }; | ||
var b = new Peer { Id = plutoId }; | ||
Peer c = null; | ||
Peer d = null; | ||
|
||
Assert.IsTrue(c == d); | ||
Assert.IsFalse(c == b); | ||
Assert.IsFalse(b == c); | ||
|
||
Assert.IsFalse(c != d); | ||
Assert.IsTrue(c != b); | ||
Assert.IsTrue(b != c); | ||
|
||
#pragma warning disable 1718 | ||
Assert.IsTrue(a0 == a0); | ||
Assert.IsTrue(a0 == a1); | ||
Assert.IsFalse(a0 == b); | ||
|
||
#pragma warning disable 1718 | ||
Assert.IsFalse(a0 != a0); | ||
Assert.IsFalse(a0 != a1); | ||
Assert.IsTrue(a0 != b); | ||
|
||
Assert.IsTrue(a0.Equals(a0)); | ||
Assert.IsTrue(a0.Equals(a1)); | ||
Assert.IsFalse(a0.Equals(b)); | ||
|
||
Assert.AreEqual(a0, a0); | ||
Assert.AreEqual(a0, a1); | ||
Assert.AreNotEqual(a0, b); | ||
|
||
Assert.AreEqual<Peer>(a0, a0); | ||
Assert.AreEqual<Peer>(a0, a1); | ||
Assert.AreNotEqual<Peer>(a0, b); | ||
|
||
Assert.AreEqual(a0.GetHashCode(), a0.GetHashCode()); | ||
Assert.AreEqual(a0.GetHashCode(), a1.GetHashCode()); | ||
Assert.AreNotEqual(a0.GetHashCode(), b.GetHashCode()); | ||
} | ||
|
||
|
||
[TestMethod] | ||
public void Implicit_Conversion_From_String() | ||
{ | ||
Peer a = marsId; | ||
Assert.IsInstanceOfType(a, typeof(Peer)); | ||
} | ||
|
||
} | ||
} | ||
|
5c69d8b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closes #24