From 97ebc9e0a83e7def0fc96f9a92ef3a407793938b Mon Sep 17 00:00:00 2001 From: Jeremy Bokobza Date: Sun, 17 Jun 2018 20:38:44 +0100 Subject: [PATCH] Federation objects (#39) * Federation objects * added the pubkey setting to the .conf files examples --- .../Federation/Federation.cs | 95 ------------------- .../Federation/FederationMember.cs | 39 -------- .../Federation/FederationMemberPrivate.cs | 62 ------------ .../FederationMemberPrivate_Shall.cs | 33 ------- .../FederationMember_Shall.cs | 25 ----- .../Federation_Shall.cs | 74 --------------- 6 files changed, 328 deletions(-) delete mode 100644 src/Stratis.FederatedPeg.Features.FederationGateway/Federation/Federation.cs delete mode 100644 src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMember.cs delete mode 100644 src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMemberPrivate.cs delete mode 100644 src/Stratis.FederatedPeg.Tests/FederationMemberPrivate_Shall.cs delete mode 100644 src/Stratis.FederatedPeg.Tests/FederationMember_Shall.cs delete mode 100644 src/Stratis.FederatedPeg.Tests/Federation_Shall.cs diff --git a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/Federation.cs b/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/Federation.cs deleted file mode 100644 index d235d43adce..00000000000 --- a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/Federation.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NBitcoin; -using Stratis.FederatedPeg.Features.FederationGateway.NetworkHelpers; - -namespace Stratis.FederatedPeg.Features.FederationGateway.Federation -{ - /// - /// Represents an M-of-N federation where N is the number of members in the federation and M - /// is the quorum that needs to be reached in order that a Transaction is valid. - /// M-of-N eg 2-of-3. - /// - public interface IFederation - { - /// - /// The number of members in the federation. - /// - int N { get; } - - /// - /// The number of members required to sign transaction (quorum). - /// - int M { get; } - - /// - /// A list of all the members with their public info. - /// - IReadOnlyList Members { get; } - - /// - /// Gets the public keys for the specified chain. - /// - /// - /// An array of keys as strings. - string[] GetPublicKeys(Chain chain); - - /// - /// Creates the ScriptPubKey for the specified chain. - /// - /// The chain (either sidechain or mainchain). - /// The ScriptPubKey (redeem script.) - Script GenerateScriptPubkey(Chain chain); - } - - // Todo: Strickly N is not required other than for the check in the ctor. Consider removing. - /// - public class Federation : IFederation - { - /// - public int N { get; } - - /// - public int M { get; } - - /// - public IReadOnlyList Members { get; } - - /// - /// Create an M-of-N federation. Throws if - /// n does not match the number of members specified. - /// - /// The number of members required to sign transaction (quorum). - /// The number of members in the federation. - /// Enumerable list of FederationMembers. - public Federation(int m, int n, IEnumerable members) - { - if (members.Count() != n) - throw new ArgumentException($"Expected {n} members but found {members.Count()} federation members."); - - this.N = n; - this.M = m; - - this.Members = new List(members); - } - - /// - public Script GenerateScriptPubkey(Chain chain) - { - var pubKeys = new List(); - foreach (FederationMember member in this.Members) - pubKeys.Add(chain == Chain.Mainchain ? member.PublicKeyMainChain : member.PublicKeySideChain); - - // The order needs to be consistent. - var keys = (from p in pubKeys orderby p.ToHex() select p).ToArray(); - return PayToMultiSigTemplate.Instance.GenerateScriptPubKey(this.M, keys); - } - - /// - public string[] GetPublicKeys(Chain chain) => - chain == Chain.Mainchain - ? (from a in this.Members select a.PublicKeyMainChain.ToString()).ToArray() - : (from a in this.Members select a.PublicKeySideChain.ToString()).ToArray(); - } -} \ No newline at end of file diff --git a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMember.cs b/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMember.cs deleted file mode 100644 index 1bebb2dd020..00000000000 --- a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMember.cs +++ /dev/null @@ -1,39 +0,0 @@ -using NBitcoin; - -namespace Stratis.FederatedPeg.Features.FederationGateway.Federation -{ - // Todo: Consider renaming to FederationMemberPublic? - /// - /// The FederationMember class represents the public details held by a member of the federation. - /// - public class FederationMember - { - /// - /// Name used to distinguish the member from other members in the federation. - /// - public string Name { get; } - - /// - /// Public key used for the Mainchain multi-sig address. - /// - public PubKey PublicKeyMainChain { get; } - - /// - /// Public key used for the Sidechain multi-sig address. - /// - public PubKey PublicKeySideChain { get; } - - /// - /// Create a federation member with only the publicly known keys. - /// - /// The name used to identify the member. - /// The public key used for the multi-sig address on the Mainchain. - /// The public key used for the multi-sig address on the Sidechain. - public FederationMember(string name, PubKey publicKeyMainchain, PubKey publicKeySidechain) - { - this.Name = name; - this.PublicKeyMainChain = publicKeyMainchain; - this.PublicKeySideChain = publicKeySidechain; - } - } -} diff --git a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMemberPrivate.cs b/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMemberPrivate.cs deleted file mode 100644 index 683fb40bd53..00000000000 --- a/src/Stratis.FederatedPeg.Features.FederationGateway/Federation/FederationMemberPrivate.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Security; -using NBitcoin; - -namespace Stratis.FederatedPeg.Features.FederationGateway.Federation -{ - /// - /// The private version of the FederationMember. Includes the private key and the password used to - /// encrypt it on disk. - /// - public class FederationMemberPrivate - { - /// - /// Name of the federation member. This enables the Sidechain Generator actor to track which members - /// he has received keys from. - /// - public string Name { get; } - - // The password used. - private string Password { get; } - - // Mainchain private key. - private Key PrivateKeyMainchain { set; get; } - - // Sidechain private key. - private Key PrivateKeySidechain { set; get; } - - //The public version of the FederationMemeber. Does not have private key. - private readonly FederationMember federationMember; - - // Constructor called from the CreateNew method. - public FederationMemberPrivate(string name, string password, Key privateKeyMainchain, Key privateKeySidechain) - { - this.Name = name; - this.Password = password; - - this.PrivateKeyMainchain = privateKeyMainchain; - this.PrivateKeySidechain = privateKeySidechain; - - this.federationMember = new FederationMember(this.Name, privateKeyMainchain.PubKey, privateKeySidechain.PubKey); - } - - /// - /// Creates a new FederationMember and generates new private keys. - /// - /// Name of the federation member. - /// Password to encrypt the file on disk. - /// The newly created private FederationMember. - public static FederationMemberPrivate CreateNew(string name, string password) - { - return new FederationMemberPrivate(name, password, new Key(), new Key()); - } - - /// - /// Gets the public version of the FederationMember without any private key info. - /// - /// Public version of the FederationMember. - public FederationMember ToFederationMember() - { - return this.federationMember; - } - } -} \ No newline at end of file diff --git a/src/Stratis.FederatedPeg.Tests/FederationMemberPrivate_Shall.cs b/src/Stratis.FederatedPeg.Tests/FederationMemberPrivate_Shall.cs deleted file mode 100644 index 7060f56b144..00000000000 --- a/src/Stratis.FederatedPeg.Tests/FederationMemberPrivate_Shall.cs +++ /dev/null @@ -1,33 +0,0 @@ -using FluentAssertions; -using NBitcoin; -using NBitcoin.DataEncoders; -using Stratis.FederatedPeg.Features.FederationGateway.Federation; -using Xunit; - -namespace Stratis.FederatedPeg.Tests -{ - public class FederationMemberPrivate_Shall - { - [Fact] - public void create_a_federation_member() - { - //use know values to test - var publicKeyMainchain = - new Key(Encoders.Hex.DecodeData("ba45a6e9f3f4b203699a37b4f5a91d74bc24d1a49b4e63374c2d7e6efcc54914")); - var publicKeySidechain = - new Key(Encoders.Hex.DecodeData("7858de78e18347540a435142d5c86eded978c965b39cee465b2ef9e21d6c7e7a")); - - var federationMemberPrivate = - new FederationMemberPrivate("Bob", "passPhrase", publicKeyMainchain, publicKeySidechain); - federationMemberPrivate.Name.Should().Be("Bob"); - } - - [Fact] - public void creates_a_public_federation_member() - { - var federationMemberPrivate = FederationMemberPrivate.CreateNew("Alice", "password"); - federationMemberPrivate.ToFederationMember().GetType().Should().Be(typeof(FederationMember)); - federationMemberPrivate.ToFederationMember().Name.Should().Be("Alice"); - } - } -} diff --git a/src/Stratis.FederatedPeg.Tests/FederationMember_Shall.cs b/src/Stratis.FederatedPeg.Tests/FederationMember_Shall.cs deleted file mode 100644 index 3848217ec85..00000000000 --- a/src/Stratis.FederatedPeg.Tests/FederationMember_Shall.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using FluentAssertions; -using NBitcoin; -using Stratis.FederatedPeg.Features.FederationGateway.Federation; -using Xunit; - -namespace Stratis.FederatedPeg.Tests -{ - public class FederationMember_Shall - { - [Fact] - public void create_a_federation_member() - { - var publicKeyMainchain = new Key().PubKey; - var publicKeySidechain = new Key().PubKey; - - var federationMember = new FederationMember("Bob", publicKeyMainchain, publicKeySidechain); - federationMember.Name.Should().Be("Bob"); - federationMember.PublicKeyMainChain.Should().Be(publicKeyMainchain); - federationMember.PublicKeySideChain.Should().Be(publicKeySidechain); - } - } -} diff --git a/src/Stratis.FederatedPeg.Tests/Federation_Shall.cs b/src/Stratis.FederatedPeg.Tests/Federation_Shall.cs deleted file mode 100644 index 3ab0edb0dc0..00000000000 --- a/src/Stratis.FederatedPeg.Tests/Federation_Shall.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using FluentAssertions; -using Xunit; - -using NBitcoin; -using Stratis.FederatedPeg.Features.FederationGateway.NetworkHelpers; -using Stratis.FederatedPeg.Features.FederationGateway.Federation; - -namespace Stratis.FederatedPeg.Tests -{ - [Collection("FederatedPegTests")] - public class Federation_Shall - { - [Fact] - public void create_a_federation() - { - var federation = new Federation(2, 3, this.GetSampleMembers()); - federation.M.Should().Be(2); - federation.N.Should().Be(3); - federation.Members.Count.Should().Be(3); - federation.Members.Should().OnlyHaveUniqueItems(); - } - - [Fact] - public void generate_addresses() - { - var federation = new Federation(2, 3, this.GetSampleMembers()); - federation.GetPublicKeys(Chain.Mainchain).Length.Should().Be(3); - federation.GetPublicKeys(Chain.Mainchain).Should().OnlyHaveUniqueItems(); - federation.GetPublicKeys(Chain.Sidechain).Length.Should().Be(3); - federation.GetPublicKeys(Chain.Sidechain).Should().OnlyHaveUniqueItems(); - } - - [Fact] - public void generate_scriptpubkey() - { - var federation = new Federation(2, 3, this.GetSampleMembers()); - federation.GenerateScriptPubkey(Chain.Mainchain).ToHex().Length.Should().BeGreaterThan(160); - } - - [Fact] - public void give_correct_payment_script() - { - var publicKey1 = new PubKey("0374860560f816100ee4917af0bfb416d559cfcbb587e539e55f09e22c8cf07c9a"); - var publicKey2 = new PubKey("0226874aa4fb722ed3294c7d56f5d9dfdbaa0f79aaebf6f2eb925dc3bd0d7b5458"); - var publicKey3 = new PubKey("0390da9f7a8bdcc3a9e2a6ad89349fb86599c65d92b36b00e0b175cc3ad10fda2e"); - - var script = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(3, - new[] {publicKey1, - publicKey2, - publicKey3 - }); - - var paymentScipt = script.PaymentScript; - - var address = script.Hash.GetAddress(Network.StratisRegTest); - var paymentScript2 = address.ScriptPubKey; - paymentScipt.Should().BeEquivalentTo(paymentScript2); - - var bitcoinAddress = BitcoinAddress.Create(address.ToString(), Network.StratisRegTest); - var paymentScript3 = bitcoinAddress.ScriptPubKey; - paymentScript2.Should().BeEquivalentTo(paymentScript3); - } - - private IEnumerable GetSampleMembers() - { - var member1 = FederationMemberPrivate.CreateNew("John Smith", "pass1").ToFederationMember(); - var member2 = FederationMemberPrivate.CreateNew("Ivan Draco", "pass2").ToFederationMember(); - var member3 = FederationMemberPrivate.CreateNew("Elizabeth", "pass3").ToFederationMember(); - return new[] {member1, member2, member3}; - } - } -}