diff --git a/AntShares.sln b/AntShares.sln
index a3f97a75ca..a8c7f46e1e 100644
--- a/AntShares.sln
+++ b/AntShares.sln
@@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntSharesCore", "AntSharesC
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntSharesUI", "AntSharesUI\AntSharesUI.csproj", "{CFC243F0-F4E3-4754-8E21-8BA17E1C1788}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Miner", "Miner\Miner.csproj", "{58870D2E-9DAE-41EF-9766-17C39238ED0F}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntSharesDaemon", "AntSharesDaemon\AntSharesDaemon.csproj", "{3E7DD63A-6AD5-41F1-837D-42C11694246C}"
EndProject
Global
@@ -25,10 +23,6 @@ Global
{CFC243F0-F4E3-4754-8E21-8BA17E1C1788}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFC243F0-F4E3-4754-8E21-8BA17E1C1788}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFC243F0-F4E3-4754-8E21-8BA17E1C1788}.Release|Any CPU.Build.0 = Release|Any CPU
- {58870D2E-9DAE-41EF-9766-17C39238ED0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {58870D2E-9DAE-41EF-9766-17C39238ED0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {58870D2E-9DAE-41EF-9766-17C39238ED0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {58870D2E-9DAE-41EF-9766-17C39238ED0F}.Release|Any CPU.Build.0 = Release|Any CPU
{3E7DD63A-6AD5-41F1-837D-42C11694246C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E7DD63A-6AD5-41F1-837D-42C11694246C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E7DD63A-6AD5-41F1-837D-42C11694246C}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/AntSharesCore/AntSharesCore.csproj b/AntSharesCore/AntSharesCore.csproj
index be0474eac2..a798bc91d8 100644
--- a/AntSharesCore/AntSharesCore.csproj
+++ b/AntSharesCore/AntSharesCore.csproj
@@ -130,6 +130,14 @@
+
+
+
+
+
+
+
+
diff --git a/Miner/Miner/Consensus/ChangeView.cs b/AntSharesCore/Consensus/ChangeView.cs
similarity index 90%
rename from Miner/Miner/Consensus/ChangeView.cs
rename to AntSharesCore/Consensus/ChangeView.cs
index 8d254bb963..2916c312d0 100644
--- a/Miner/Miner/Consensus/ChangeView.cs
+++ b/AntSharesCore/Consensus/ChangeView.cs
@@ -1,28 +1,28 @@
-using System;
-using System.IO;
-
-namespace AntShares.Miner.Consensus
-{
- internal class ChangeView : ConsensusMessage
- {
- public byte NewViewNumber;
-
- public ChangeView()
- : base(ConsensusMessageType.ChangeView)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- NewViewNumber = reader.ReadByte();
- if (NewViewNumber == 0) throw new FormatException();
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(NewViewNumber);
- }
- }
-}
+using System;
+using System.IO;
+
+namespace AntShares.Consensus
+{
+ internal class ChangeView : ConsensusMessage
+ {
+ public byte NewViewNumber;
+
+ public ChangeView()
+ : base(ConsensusMessageType.ChangeView)
+ {
+ }
+
+ public override void Deserialize(BinaryReader reader)
+ {
+ base.Deserialize(reader);
+ NewViewNumber = reader.ReadByte();
+ if (NewViewNumber == 0) throw new FormatException();
+ }
+
+ public override void Serialize(BinaryWriter writer)
+ {
+ base.Serialize(writer);
+ writer.Write(NewViewNumber);
+ }
+ }
+}
diff --git a/Miner/Miner/Consensus/ConsensusContext.cs b/AntSharesCore/Consensus/ConsensusContext.cs
similarity index 96%
rename from Miner/Miner/Consensus/ConsensusContext.cs
rename to AntSharesCore/Consensus/ConsensusContext.cs
index 00f192e22f..3bea02ea59 100644
--- a/Miner/Miner/Consensus/ConsensusContext.cs
+++ b/AntSharesCore/Consensus/ConsensusContext.cs
@@ -1,132 +1,132 @@
-using AntShares.Core;
-using AntShares.Cryptography;
-using AntShares.Cryptography.ECC;
-using AntShares.IO;
-using AntShares.Network.Payloads;
-using AntShares.Wallets;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace AntShares.Miner.Consensus
-{
- internal class ConsensusContext
- {
- public const uint Version = 0;
- public ConsensusState State;
- public UInt256 PrevHash;
- public uint Height;
- public byte ViewNumber;
- public ECPoint[] Miners;
- public int MinerIndex;
- public uint PrimaryIndex;
- public uint Timestamp;
- public ulong Nonce;
- public UInt160 NextMiner;
- public UInt256[] TransactionHashes;
- public Dictionary Transactions;
- public byte[][] Signatures;
- public byte[] ExpectedView;
-
- public int M => Miners.Length - (Miners.Length - 1) / 3;
-
- public void ChangeView(byte view_number)
- {
- int p = ((int)Height - view_number) % Miners.Length;
- State &= ConsensusState.SignatureSent;
- ViewNumber = view_number;
- PrimaryIndex = p >= 0 ? (uint)p : (uint)(p + Miners.Length);
- if (State == ConsensusState.Initial)
- {
- TransactionHashes = null;
- Signatures = new byte[Miners.Length][];
- }
- _header = null;
- }
-
- public ConsensusPayload MakeChangeView()
- {
- return MakePayload(new ChangeView
- {
- NewViewNumber = ExpectedView[MinerIndex]
- });
- }
-
- private Block _header = null;
- public Block MakeHeader()
- {
- if (TransactionHashes == null) return null;
- if (_header == null)
- {
- _header = new Block
- {
- Version = Version,
- PrevBlock = PrevHash,
- MerkleRoot = MerkleTree.ComputeRoot(TransactionHashes),
- Timestamp = Timestamp,
- Height = Height,
- Nonce = Nonce,
- NextMiner = NextMiner,
- Transactions = new Transaction[0]
- };
- }
- return _header;
- }
-
- private ConsensusPayload MakePayload(ConsensusMessage message)
- {
- message.ViewNumber = ViewNumber;
- return new ConsensusPayload
- {
- Version = Version,
- PrevHash = PrevHash,
- Height = Height,
- MinerIndex = (ushort)MinerIndex,
- Timestamp = Timestamp,
- Data = message.ToArray()
- };
- }
-
- public ConsensusPayload MakePerpareRequest()
- {
- return MakePayload(new PerpareRequest
- {
- Nonce = Nonce,
- NextMiner = NextMiner,
- TransactionHashes = TransactionHashes,
- MinerTransaction = (MinerTransaction)Transactions[TransactionHashes[0]],
- Signature = Signatures[MinerIndex]
- });
- }
-
- public ConsensusPayload MakePerpareResponse(byte[] signature)
- {
- return MakePayload(new PerpareResponse
- {
- Signature = signature
- });
- }
-
- public void Reset(Wallet wallet)
- {
- State = ConsensusState.Initial;
- PrevHash = Blockchain.Default.CurrentBlockHash;
- Height = Blockchain.Default.Height + 1;
- ViewNumber = 0;
- Miners = Blockchain.Default.GetMiners();
- MinerIndex = -1;
- PrimaryIndex = Height % (uint)Miners.Length;
- TransactionHashes = null;
- Signatures = new byte[Miners.Length][];
- ExpectedView = new byte[Miners.Length];
- for (int i = 0; i < Miners.Length; i++)
- {
- if (wallet.ContainsAccount(Miners[i]))
- {
- MinerIndex = i;
- break;
- }
- }
- _header = null;
- }
- }
-}
+using AntShares.Core;
+using AntShares.Cryptography;
+using AntShares.Cryptography.ECC;
+using AntShares.IO;
+using AntShares.Network.Payloads;
+using AntShares.Wallets;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace AntShares.Consensus
+{
+ internal class ConsensusContext
+ {
+ public const uint Version = 0;
+ public ConsensusState State;
+ public UInt256 PrevHash;
+ public uint Height;
+ public byte ViewNumber;
+ public ECPoint[] Miners;
+ public int MinerIndex;
+ public uint PrimaryIndex;
+ public uint Timestamp;
+ public ulong Nonce;
+ public UInt160 NextMiner;
+ public UInt256[] TransactionHashes;
+ public Dictionary Transactions;
+ public byte[][] Signatures;
+ public byte[] ExpectedView;
+
+ public int M => Miners.Length - (Miners.Length - 1) / 3;
+
+ public void ChangeView(byte view_number)
+ {
+ int p = ((int)Height - view_number) % Miners.Length;
+ State &= ConsensusState.SignatureSent;
+ ViewNumber = view_number;
+ PrimaryIndex = p >= 0 ? (uint)p : (uint)(p + Miners.Length);
+ if (State == ConsensusState.Initial)
+ {
+ TransactionHashes = null;
+ Signatures = new byte[Miners.Length][];
+ }
+ _header = null;
+ }
+
+ public ConsensusPayload MakeChangeView()
+ {
+ return MakePayload(new ChangeView
+ {
+ NewViewNumber = ExpectedView[MinerIndex]
+ });
+ }
+
+ private Block _header = null;
+ public Block MakeHeader()
+ {
+ if (TransactionHashes == null) return null;
+ if (_header == null)
+ {
+ _header = new Block
+ {
+ Version = Version,
+ PrevBlock = PrevHash,
+ MerkleRoot = MerkleTree.ComputeRoot(TransactionHashes),
+ Timestamp = Timestamp,
+ Height = Height,
+ Nonce = Nonce,
+ NextMiner = NextMiner,
+ Transactions = new Transaction[0]
+ };
+ }
+ return _header;
+ }
+
+ private ConsensusPayload MakePayload(ConsensusMessage message)
+ {
+ message.ViewNumber = ViewNumber;
+ return new ConsensusPayload
+ {
+ Version = Version,
+ PrevHash = PrevHash,
+ Height = Height,
+ MinerIndex = (ushort)MinerIndex,
+ Timestamp = Timestamp,
+ Data = message.ToArray()
+ };
+ }
+
+ public ConsensusPayload MakePerpareRequest()
+ {
+ return MakePayload(new PerpareRequest
+ {
+ Nonce = Nonce,
+ NextMiner = NextMiner,
+ TransactionHashes = TransactionHashes,
+ MinerTransaction = (MinerTransaction)Transactions[TransactionHashes[0]],
+ Signature = Signatures[MinerIndex]
+ });
+ }
+
+ public ConsensusPayload MakePerpareResponse(byte[] signature)
+ {
+ return MakePayload(new PerpareResponse
+ {
+ Signature = signature
+ });
+ }
+
+ public void Reset(Wallet wallet)
+ {
+ State = ConsensusState.Initial;
+ PrevHash = Blockchain.Default.CurrentBlockHash;
+ Height = Blockchain.Default.Height + 1;
+ ViewNumber = 0;
+ Miners = Blockchain.Default.GetMiners();
+ MinerIndex = -1;
+ PrimaryIndex = Height % (uint)Miners.Length;
+ TransactionHashes = null;
+ Signatures = new byte[Miners.Length][];
+ ExpectedView = new byte[Miners.Length];
+ for (int i = 0; i < Miners.Length; i++)
+ {
+ if (wallet.ContainsAccount(Miners[i]))
+ {
+ MinerIndex = i;
+ break;
+ }
+ }
+ _header = null;
+ }
+ }
+}
diff --git a/Miner/Miner/Consensus/ConsensusMessage.cs b/AntSharesCore/Consensus/ConsensusMessage.cs
similarity index 94%
rename from Miner/Miner/Consensus/ConsensusMessage.cs
rename to AntSharesCore/Consensus/ConsensusMessage.cs
index 9cec8bdc6f..f377baa459 100644
--- a/Miner/Miner/Consensus/ConsensusMessage.cs
+++ b/AntSharesCore/Consensus/ConsensusMessage.cs
@@ -1,43 +1,43 @@
-using AntShares.IO;
-using System;
-using System.IO;
-
-namespace AntShares.Miner.Consensus
-{
- internal abstract class ConsensusMessage : ISerializable
- {
- public readonly ConsensusMessageType Type;
- public byte ViewNumber;
-
- protected ConsensusMessage(ConsensusMessageType type)
- {
- this.Type = type;
- }
-
- public virtual void Deserialize(BinaryReader reader)
- {
- if (Type != (ConsensusMessageType)reader.ReadByte())
- throw new FormatException();
- ViewNumber = reader.ReadByte();
- }
-
- public static ConsensusMessage DeserializeFrom(byte[] data)
- {
- ConsensusMessageType type = (ConsensusMessageType)data[0];
- string typeName = $"{typeof(ConsensusMessage).Namespace}.{type}";
- ConsensusMessage message = typeof(ConsensusMessage).Assembly.CreateInstance(typeName) as ConsensusMessage;
- using (MemoryStream ms = new MemoryStream(data, false))
- using (BinaryReader r = new BinaryReader(ms))
- {
- message.Deserialize(r);
- }
- return message;
- }
-
- public virtual void Serialize(BinaryWriter writer)
- {
- writer.Write((byte)Type);
- writer.Write(ViewNumber);
- }
- }
-}
+using AntShares.IO;
+using System;
+using System.IO;
+
+namespace AntShares.Consensus
+{
+ internal abstract class ConsensusMessage : ISerializable
+ {
+ public readonly ConsensusMessageType Type;
+ public byte ViewNumber;
+
+ protected ConsensusMessage(ConsensusMessageType type)
+ {
+ this.Type = type;
+ }
+
+ public virtual void Deserialize(BinaryReader reader)
+ {
+ if (Type != (ConsensusMessageType)reader.ReadByte())
+ throw new FormatException();
+ ViewNumber = reader.ReadByte();
+ }
+
+ public static ConsensusMessage DeserializeFrom(byte[] data)
+ {
+ ConsensusMessageType type = (ConsensusMessageType)data[0];
+ string typeName = $"{typeof(ConsensusMessage).Namespace}.{type}";
+ ConsensusMessage message = typeof(ConsensusMessage).Assembly.CreateInstance(typeName) as ConsensusMessage;
+ using (MemoryStream ms = new MemoryStream(data, false))
+ using (BinaryReader r = new BinaryReader(ms))
+ {
+ message.Deserialize(r);
+ }
+ return message;
+ }
+
+ public virtual void Serialize(BinaryWriter writer)
+ {
+ writer.Write((byte)Type);
+ writer.Write(ViewNumber);
+ }
+ }
+}
diff --git a/Miner/Miner/Consensus/ConsensusMessageType.cs b/AntSharesCore/Consensus/ConsensusMessageType.cs
similarity index 76%
rename from Miner/Miner/Consensus/ConsensusMessageType.cs
rename to AntSharesCore/Consensus/ConsensusMessageType.cs
index dbb988503b..91b60a249a 100644
--- a/Miner/Miner/Consensus/ConsensusMessageType.cs
+++ b/AntSharesCore/Consensus/ConsensusMessageType.cs
@@ -1,9 +1,9 @@
-namespace AntShares.Miner.Consensus
-{
- internal enum ConsensusMessageType : byte
- {
- ChangeView = 0x00,
- PerpareRequest = 0x20,
- PerpareResponse = 0x21,
- }
-}
+namespace AntShares.Consensus
+{
+ internal enum ConsensusMessageType : byte
+ {
+ ChangeView = 0x00,
+ PerpareRequest = 0x20,
+ PerpareResponse = 0x21,
+ }
+}
diff --git a/Miner/Miner/MinerService.cs b/AntSharesCore/Consensus/ConsensusService.cs
similarity index 66%
rename from Miner/Miner/MinerService.cs
rename to AntSharesCore/Consensus/ConsensusService.cs
index 053c717373..aee4c5c570 100644
--- a/Miner/Miner/MinerService.cs
+++ b/AntSharesCore/Consensus/ConsensusService.cs
@@ -1,448 +1,346 @@
-using AntShares.Core;
-using AntShares.Core.Scripts;
-using AntShares.Implementations.Wallets.EntityFramework;
-using AntShares.Miner.Consensus;
-using AntShares.Network;
-using AntShares.Network.Payloads;
-using AntShares.Shell;
-using AntShares.Wallets;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security;
-using System.Threading;
-
-namespace AntShares.Miner
-{
- internal class MinerService : MainService
- {
- private ConsensusContext context = new ConsensusContext();
- private UserWallet wallet;
- private Timer timer;
- private uint timer_height;
- private byte timer_view;
- private DateTime block_received_time;
-
- private bool AddTransaction(Transaction tx)
- {
- Program.Log($"{nameof(AddTransaction)} hash:{tx.Hash}");
- if (context.Transactions.SelectMany(p => p.Value.GetAllInputs()).Intersect(tx.GetAllInputs()).Count() > 0 ||
- Blockchain.Default.ContainsTransaction(tx.Hash) ||
- !tx.Verify())
- {
- Program.Log($"failed hash:{tx.Hash}");
- RequestChangeView();
- return false;
- }
- context.Transactions[tx.Hash] = tx;
- if (context.TransactionHashes.Length == context.Transactions.Count)
- {
- if (Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(context.Transactions.Values).ToArray()).Equals(context.NextMiner))
- {
- Program.Log($"SendPerpareResponse");
- context.State |= ConsensusState.SignatureSent;
- context.Signatures[context.MinerIndex] = context.MakeHeader().Sign(wallet.GetAccount(context.Miners[context.MinerIndex]));
- SignAndRelay(context.MakePerpareResponse(context.Signatures[context.MinerIndex]));
- CheckSignatures();
- }
- else
- {
- RequestChangeView();
- return false;
- }
- }
- return true;
- }
-
- private void Blockchain_PersistCompleted(object sender, Block block)
- {
- Program.Log($"{nameof(Blockchain_PersistCompleted)} hash:{block.Hash}");
- block_received_time = DateTime.Now;
- InitializeConsensus(0);
- }
-
- private void CheckExpectedView(byte view_number)
- {
- if (context.ViewNumber == view_number) return;
- if (context.ExpectedView.Count(p => p == view_number) >= context.M)
- {
- InitializeConsensus(view_number);
- }
- }
-
- private void CheckSignatures()
- {
- if (context.Signatures.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
- {
- Program.Log($"{nameof(CheckSignatures)} {context.Signatures.Count(p => p != null)}/{context.M}");
- Contract contract = Contract.CreateMultiSigContract(context.Miners[context.MinerIndex].EncodePoint(true).ToScriptHash(), context.M, context.Miners);
- Block block = context.MakeHeader();
- SignatureContext sc = new SignatureContext(block);
- for (int i = 0; i < context.Miners.Length; i++)
- if (context.Signatures[i] != null)
- sc.Add(contract, context.Miners[i], context.Signatures[i]);
- sc.Signable.Scripts = sc.GetScripts();
- block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray();
- Program.Log($"RelayBlock hash:{block.Hash}");
- if (!LocalNode.Relay(block))
- Program.Log($"failed hash:{block.Hash}");
- context.State |= ConsensusState.BlockSent;
- }
- }
-
- private MinerTransaction CreateMinerTransaction(IEnumerable transactions, uint height, ulong nonce)
- {
- Fixed8 amount_netfee = Block.CalculateNetFee(transactions);
- TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput
- {
- AssetId = Blockchain.AntCoin.Hash,
- Value = amount_netfee,
- ScriptHash = wallet.GetContracts().First().ScriptHash
- } };
- return new MinerTransaction
- {
- Nonce = (uint)(nonce % (uint.MaxValue + 1ul)),
- Attributes = new TransactionAttribute[0],
- Inputs = new TransactionInput[0],
- Outputs = outputs,
- Scripts = new Script[0]
- };
- }
-
- private static ulong GetNonce()
- {
- byte[] nonce = new byte[sizeof(ulong)];
- Random rand = new Random();
- rand.NextBytes(nonce);
- return BitConverter.ToUInt64(nonce, 0);
- }
-
- private void InitializeConsensus(byte view_number)
- {
- lock (context)
- {
- if (view_number == 0)
- context.Reset(wallet);
- else
- context.ChangeView(view_number);
- if (context.MinerIndex < 0) return;
- Program.Log($"{nameof(InitializeConsensus)} h:{context.Height} v:{view_number} i:{context.MinerIndex} s:{(context.MinerIndex == context.PrimaryIndex ? ConsensusState.Primary : ConsensusState.Backup)}");
- if (context.MinerIndex == context.PrimaryIndex)
- {
- context.State |= ConsensusState.Primary;
- timer_height = context.Height;
- timer_view = view_number;
- TimeSpan span = DateTime.Now - block_received_time;
- if (span >= Blockchain.TimePerBlock)
- timer.Change(0, Timeout.Infinite);
- else
- timer.Change(Blockchain.TimePerBlock - span, Timeout.InfiniteTimeSpan);
- }
- else
- {
- context.State = ConsensusState.Backup;
- timer_height = context.Height;
- timer_view = view_number;
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (view_number + 1)), Timeout.InfiniteTimeSpan);
- }
- }
- }
-
- private void LocalNode_NewInventory(object sender, IInventory inventory)
- {
- ConsensusPayload payload = inventory as ConsensusPayload;
- if (payload != null)
- {
- lock (context)
- {
- if (payload.MinerIndex == context.MinerIndex) return;
- if (payload.Version != ConsensusContext.Version || payload.PrevHash != context.PrevHash || payload.Height != context.Height)
- return;
- if (payload.MinerIndex >= context.Miners.Length) return;
- ConsensusMessage message = ConsensusMessage.DeserializeFrom(payload.Data);
- if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView)
- return;
- switch (message.Type)
- {
- case ConsensusMessageType.ChangeView:
- OnChangeViewReceived(payload, (ChangeView)message);
- break;
- case ConsensusMessageType.PerpareRequest:
- OnPerpareRequestReceived(payload, (PerpareRequest)message);
- break;
- case ConsensusMessageType.PerpareResponse:
- OnPerpareResponseReceived(payload, (PerpareResponse)message);
- break;
- }
- }
- }
- Transaction tx = inventory as Transaction;
- if (tx != null)
- {
- lock (context)
- {
- if (!context.State.HasFlag(ConsensusState.Backup) || !context.State.HasFlag(ConsensusState.RequestReceived) || context.State.HasFlag(ConsensusState.SignatureSent))
- return;
- if (context.Transactions.ContainsKey(tx.Hash)) return;
- if (!context.TransactionHashes.Contains(tx.Hash)) return;
- AddTransaction(tx);
- }
- }
- }
-
- private void OnChangeViewReceived(ConsensusPayload payload, ChangeView message)
- {
- Program.Log($"{nameof(OnChangeViewReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex} nv:{message.NewViewNumber}");
- if (message.NewViewNumber <= context.ExpectedView[payload.MinerIndex])
- return;
- context.ExpectedView[payload.MinerIndex] = message.NewViewNumber;
- CheckExpectedView(message.NewViewNumber);
- }
-
- protected override bool OnCommand(string[] args)
- {
- switch (args[0].ToLower())
- {
- case "create":
- return OnCreateCommand(args);
- case "list":
- return OnListCommand(args);
- case "open":
- return OnOpenCommand(args);
- default:
- return base.OnCommand(args);
- }
- }
-
- private bool OnCreateCommand(string[] args)
- {
- switch (args[1].ToLower())
- {
- case "wallet":
- return OnCreateWalletCommand(args);
- default:
- return base.OnCommand(args);
- }
- }
-
- private bool OnCreateWalletCommand(string[] args)
- {
- if (args.Length < 3)
- {
- Console.WriteLine("error");
- return true;
- }
- using (SecureString password = ReadSecureString("password"))
- using (SecureString password2 = ReadSecureString("password"))
- {
- if (!password.CompareTo(password2))
- {
- Console.WriteLine("error");
- return true;
- }
- wallet = UserWallet.Create(args[2], password);
- foreach (Account account in wallet.GetAccounts())
- {
- Console.WriteLine(account.PublicKey.EncodePoint(true).ToHexString());
- }
- }
- return true;
- }
-
- private bool OnListCommand(string[] args)
- {
- switch (args[1].ToLower())
- {
- case "account":
- return OnListAccountCommand(args);
- case "address":
- return OnListAddressCommand(args);
- default:
- return base.OnCommand(args);
- }
- }
-
- private bool OnListAccountCommand(string[] args)
- {
- if (wallet == null) return true;
- foreach (Account account in wallet.GetAccounts())
- {
- Console.WriteLine(account.PublicKey);
- }
- return true;
- }
-
- private bool OnListAddressCommand(string[] args)
- {
- if (wallet == null) return true;
- foreach (Contract contract in wallet.GetContracts())
- {
- Console.WriteLine($"{contract.Address}\t{contract.GetType()}");
- }
- return true;
- }
-
- private bool OnOpenCommand(string[] args)
- {
- switch (args[1].ToLower())
- {
- case "wallet":
- return OnOpenWalletCommand(args);
- default:
- return base.OnCommand(args);
- }
- }
-
- //TODO: 目前没有想到其它安全的方法来保存密码
- //所以只能暂时手动输入,但如此一来就不能以服务的方式启动了
- //未来再想想其它办法,比如采用智能卡之类的
- private bool OnOpenWalletCommand(string[] args)
- {
- if (args.Length < 3)
- {
- Console.WriteLine("error");
- return true;
- }
- using (SecureString password = ReadSecureString("password"))
- {
- if (password.Length == 0)
- {
- Console.WriteLine("cancelled");
- return true;
- }
- try
- {
- wallet = UserWallet.Open(args[2], password);
- }
- catch
- {
- Console.WriteLine($"failed to open file \"{args[2]}\"");
- return true;
- }
- }
- StartMine();
- return true;
- }
-
- private void OnPerpareRequestReceived(ConsensusPayload payload, PerpareRequest message)
- {
- Program.Log($"{nameof(OnPerpareRequestReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex} tx:{message.TransactionHashes.Length}");
- if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived))
- return;
- if (payload.MinerIndex != context.PrimaryIndex) return;
- if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp())
- {
- Program.Log($"Timestamp incorrect:{payload.Timestamp}");
- return;
- }
- context.State |= ConsensusState.RequestReceived;
- context.Timestamp = payload.Timestamp;
- context.Nonce = message.Nonce;
- context.NextMiner = message.NextMiner;
- context.TransactionHashes = message.TransactionHashes;
- context.Transactions = new Dictionary();
- if (!context.MakeHeader().VerifySignature(context.Miners[payload.MinerIndex], message.Signature)) return;
- context.Signatures = new byte[context.Miners.Length][];
- context.Signatures[payload.MinerIndex] = message.Signature;
- if (!AddTransaction(message.MinerTransaction)) return;
- Dictionary mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash);
- foreach (UInt256 hash in context.TransactionHashes.Skip(1))
- if (mempool.ContainsKey(hash))
- if (!AddTransaction(mempool[hash]))
- return;
- LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys));
- if (context.Transactions.Count < context.TransactionHashes.Length)
- LocalNode.SynchronizeMemoryPool();
- }
-
- private void OnPerpareResponseReceived(ConsensusPayload payload, PerpareResponse message)
- {
- Program.Log($"{nameof(OnPerpareResponseReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex}");
- if (context.State.HasFlag(ConsensusState.BlockSent)) return;
- if (context.Signatures[payload.MinerIndex] != null) return;
- Block header = context.MakeHeader();
- if (header == null || !header.VerifySignature(context.Miners[payload.MinerIndex], message.Signature)) return;
- context.Signatures[payload.MinerIndex] = message.Signature;
- CheckSignatures();
- }
-
- protected internal override void OnStop()
- {
- Program.Log($"{nameof(OnStop)}");
- if (timer != null) timer.Dispose();
- Blockchain.PersistCompleted -= Blockchain_PersistCompleted;
- LocalNode.NewInventory -= LocalNode_NewInventory;
- base.OnStop();
- }
-
- private void OnTimeout(object state)
- {
- Program.Log($"{nameof(OnTimeout)} h:{timer_height} v:{timer_view} state:{context.State}");
- lock (context)
- {
- if (timer_height != context.Height || timer_view != context.ViewNumber)
- {
- Program.Log($"ignored");
- return;
- }
- if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent))
- {
- Program.Log($"SendPerpareRequest h:{timer_height} v:{timer_view}");
- context.State |= ConsensusState.RequestSent;
- if (!context.State.HasFlag(ConsensusState.SignatureSent))
- {
- context.Timestamp = Math.Max(DateTime.Now.ToTimestamp(), Blockchain.Default.GetHeader(context.PrevHash).Timestamp + 1);
- context.Nonce = GetNonce();
- List transactions = LocalNode.GetMemoryPool().ToList();
- transactions.Insert(0, CreateMinerTransaction(transactions, context.Height, context.Nonce));
- context.TransactionHashes = transactions.Select(p => p.Hash).ToArray();
- context.Transactions = transactions.ToDictionary(p => p.Hash);
- context.NextMiner = Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(transactions).ToArray());
- context.Signatures[context.MinerIndex] = context.MakeHeader().Sign(wallet.GetAccount(context.Miners[context.MinerIndex]));
- }
- SignAndRelay(context.MakePerpareRequest());
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer_view + 1)), Timeout.InfiniteTimeSpan);
- }
- else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup))
- {
- RequestChangeView();
- }
- }
- }
-
- private void RequestChangeView()
- {
- context.ExpectedView[context.MinerIndex]++;
- Program.Log($"{nameof(RequestChangeView)} h:{context.Height} v:{context.ViewNumber} nv:{context.ExpectedView[context.MinerIndex]} state:{context.State}");
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (context.ExpectedView[context.MinerIndex] + 1)), Timeout.InfiniteTimeSpan);
- SignAndRelay(context.MakeChangeView());
- CheckExpectedView(context.ExpectedView[context.MinerIndex]);
- }
-
- private void SignAndRelay(ConsensusPayload payload)
- {
- SignatureContext sc;
- try
- {
- sc = new SignatureContext(payload);
- }
- catch (InvalidOperationException)
- {
- return;
- }
- wallet.Sign(sc);
- sc.Signable.Scripts = sc.GetScripts();
- LocalNode.Relay(payload);
- }
-
- private void StartMine()
- {
- Program.Log($"{nameof(StartMine)}");
- ShowPrompt = false;
- timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
- Blockchain.PersistCompleted += Blockchain_PersistCompleted;
- LocalNode.NewInventory += LocalNode_NewInventory;
- InitializeConsensus(0);
- }
- }
-}
+using AntShares.Core;
+using AntShares.Core.Scripts;
+using AntShares.Network;
+using AntShares.Network.Payloads;
+using AntShares.Wallets;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+
+namespace AntShares.Consensus
+{
+ public class ConsensusService : IDisposable
+ {
+ private ConsensusContext context = new ConsensusContext();
+ private LocalNode localNode;
+ private Wallet wallet;
+ private Timer timer;
+ private uint timer_height;
+ private byte timer_view;
+ private DateTime block_received_time;
+ private string log_dictionary;
+ private bool started = false;
+
+ public ConsensusService(LocalNode localNode, Wallet wallet, string log_dictionary = null)
+ {
+ this.localNode = localNode;
+ this.wallet = wallet;
+ this.timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
+ this.log_dictionary = log_dictionary;
+ }
+
+ private bool AddTransaction(Transaction tx)
+ {
+ Log($"{nameof(AddTransaction)} hash:{tx.Hash}");
+ if (context.Transactions.SelectMany(p => p.Value.GetAllInputs()).Intersect(tx.GetAllInputs()).Count() > 0 ||
+ Blockchain.Default.ContainsTransaction(tx.Hash) ||
+ !tx.Verify())
+ {
+ Log($"failed hash:{tx.Hash}");
+ RequestChangeView();
+ return false;
+ }
+ context.Transactions[tx.Hash] = tx;
+ if (context.TransactionHashes.Length == context.Transactions.Count)
+ {
+ if (Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(context.Transactions.Values).ToArray()).Equals(context.NextMiner))
+ {
+ Log($"SendPerpareResponse");
+ context.State |= ConsensusState.SignatureSent;
+ context.Signatures[context.MinerIndex] = context.MakeHeader().Sign(wallet.GetAccount(context.Miners[context.MinerIndex]));
+ SignAndRelay(context.MakePerpareResponse(context.Signatures[context.MinerIndex]));
+ CheckSignatures();
+ }
+ else
+ {
+ RequestChangeView();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void Blockchain_PersistCompleted(object sender, Block block)
+ {
+ Log($"{nameof(Blockchain_PersistCompleted)} hash:{block.Hash}");
+ block_received_time = DateTime.Now;
+ InitializeConsensus(0);
+ }
+
+ private void CheckExpectedView(byte view_number)
+ {
+ if (context.ViewNumber == view_number) return;
+ if (context.ExpectedView.Count(p => p == view_number) >= context.M)
+ {
+ InitializeConsensus(view_number);
+ }
+ }
+
+ private void CheckSignatures()
+ {
+ if (context.Signatures.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
+ {
+ Log($"{nameof(CheckSignatures)} {context.Signatures.Count(p => p != null)}/{context.M}");
+ Contract contract = Contract.CreateMultiSigContract(context.Miners[context.MinerIndex].EncodePoint(true).ToScriptHash(), context.M, context.Miners);
+ Block block = context.MakeHeader();
+ SignatureContext sc = new SignatureContext(block);
+ for (int i = 0; i < context.Miners.Length; i++)
+ if (context.Signatures[i] != null)
+ sc.Add(contract, context.Miners[i], context.Signatures[i]);
+ sc.Signable.Scripts = sc.GetScripts();
+ block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray();
+ Log($"RelayBlock hash:{block.Hash}");
+ if (!localNode.Relay(block))
+ Log($"failed hash:{block.Hash}");
+ context.State |= ConsensusState.BlockSent;
+ }
+ }
+
+ private MinerTransaction CreateMinerTransaction(IEnumerable transactions, uint height, ulong nonce)
+ {
+ Fixed8 amount_netfee = Block.CalculateNetFee(transactions);
+ TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput
+ {
+ AssetId = Blockchain.AntCoin.Hash,
+ Value = amount_netfee,
+ ScriptHash = wallet.GetContracts().First().ScriptHash
+ } };
+ return new MinerTransaction
+ {
+ Nonce = (uint)(nonce % (uint.MaxValue + 1ul)),
+ Attributes = new TransactionAttribute[0],
+ Inputs = new TransactionInput[0],
+ Outputs = outputs,
+ Scripts = new Script[0]
+ };
+ }
+
+ public void Dispose()
+ {
+ Log("OnStop");
+ if (timer != null) timer.Dispose();
+ if (started)
+ {
+ Blockchain.PersistCompleted -= Blockchain_PersistCompleted;
+ LocalNode.NewInventory -= LocalNode_NewInventory;
+ }
+ }
+
+ private static ulong GetNonce()
+ {
+ byte[] nonce = new byte[sizeof(ulong)];
+ Random rand = new Random();
+ rand.NextBytes(nonce);
+ return BitConverter.ToUInt64(nonce, 0);
+ }
+
+ private void InitializeConsensus(byte view_number)
+ {
+ lock (context)
+ {
+ if (view_number == 0)
+ context.Reset(wallet);
+ else
+ context.ChangeView(view_number);
+ if (context.MinerIndex < 0) return;
+ Log($"{nameof(InitializeConsensus)} h:{context.Height} v:{view_number} i:{context.MinerIndex} s:{(context.MinerIndex == context.PrimaryIndex ? ConsensusState.Primary : ConsensusState.Backup)}");
+ if (context.MinerIndex == context.PrimaryIndex)
+ {
+ context.State |= ConsensusState.Primary;
+ timer_height = context.Height;
+ timer_view = view_number;
+ TimeSpan span = DateTime.Now - block_received_time;
+ if (span >= Blockchain.TimePerBlock)
+ timer.Change(0, Timeout.Infinite);
+ else
+ timer.Change(Blockchain.TimePerBlock - span, Timeout.InfiniteTimeSpan);
+ }
+ else
+ {
+ context.State = ConsensusState.Backup;
+ timer_height = context.Height;
+ timer_view = view_number;
+ timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (view_number + 1)), Timeout.InfiniteTimeSpan);
+ }
+ }
+ }
+
+ private void LocalNode_NewInventory(object sender, IInventory inventory)
+ {
+ ConsensusPayload payload = inventory as ConsensusPayload;
+ if (payload != null)
+ {
+ lock (context)
+ {
+ if (payload.MinerIndex == context.MinerIndex) return;
+ if (payload.Version != ConsensusContext.Version || payload.PrevHash != context.PrevHash || payload.Height != context.Height)
+ return;
+ if (payload.MinerIndex >= context.Miners.Length) return;
+ ConsensusMessage message = ConsensusMessage.DeserializeFrom(payload.Data);
+ if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView)
+ return;
+ switch (message.Type)
+ {
+ case ConsensusMessageType.ChangeView:
+ OnChangeViewReceived(payload, (ChangeView)message);
+ break;
+ case ConsensusMessageType.PerpareRequest:
+ OnPerpareRequestReceived(payload, (PerpareRequest)message);
+ break;
+ case ConsensusMessageType.PerpareResponse:
+ OnPerpareResponseReceived(payload, (PerpareResponse)message);
+ break;
+ }
+ }
+ }
+ Transaction tx = inventory as Transaction;
+ if (tx != null)
+ {
+ lock (context)
+ {
+ if (!context.State.HasFlag(ConsensusState.Backup) || !context.State.HasFlag(ConsensusState.RequestReceived) || context.State.HasFlag(ConsensusState.SignatureSent))
+ return;
+ if (context.Transactions.ContainsKey(tx.Hash)) return;
+ if (!context.TransactionHashes.Contains(tx.Hash)) return;
+ AddTransaction(tx);
+ }
+ }
+ }
+
+ private void Log(string message)
+ {
+ DateTime now = DateTime.Now;
+ string line = $"[{now.TimeOfDay:hh\\:mm\\:ss}] {message}";
+ Console.WriteLine(line);
+ if (string.IsNullOrEmpty(log_dictionary)) return;
+ lock (log_dictionary)
+ {
+ Directory.CreateDirectory(log_dictionary);
+ string path = Path.Combine(log_dictionary, $"{now:yyyy-MM-dd}.log");
+ File.AppendAllLines(path, new[] { line });
+ }
+ }
+
+ private void OnChangeViewReceived(ConsensusPayload payload, ChangeView message)
+ {
+ Log($"{nameof(OnChangeViewReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex} nv:{message.NewViewNumber}");
+ if (message.NewViewNumber <= context.ExpectedView[payload.MinerIndex])
+ return;
+ context.ExpectedView[payload.MinerIndex] = message.NewViewNumber;
+ CheckExpectedView(message.NewViewNumber);
+ }
+
+ private void OnPerpareRequestReceived(ConsensusPayload payload, PerpareRequest message)
+ {
+ Log($"{nameof(OnPerpareRequestReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex} tx:{message.TransactionHashes.Length}");
+ if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived))
+ return;
+ if (payload.MinerIndex != context.PrimaryIndex) return;
+ if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp())
+ {
+ Log($"Timestamp incorrect:{payload.Timestamp}");
+ return;
+ }
+ context.State |= ConsensusState.RequestReceived;
+ context.Timestamp = payload.Timestamp;
+ context.Nonce = message.Nonce;
+ context.NextMiner = message.NextMiner;
+ context.TransactionHashes = message.TransactionHashes;
+ context.Transactions = new Dictionary();
+ if (!context.MakeHeader().VerifySignature(context.Miners[payload.MinerIndex], message.Signature)) return;
+ context.Signatures = new byte[context.Miners.Length][];
+ context.Signatures[payload.MinerIndex] = message.Signature;
+ if (!AddTransaction(message.MinerTransaction)) return;
+ Dictionary mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash);
+ foreach (UInt256 hash in context.TransactionHashes.Skip(1))
+ if (mempool.ContainsKey(hash))
+ if (!AddTransaction(mempool[hash]))
+ return;
+ LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys));
+ if (context.Transactions.Count < context.TransactionHashes.Length)
+ localNode.SynchronizeMemoryPool();
+ }
+
+ private void OnPerpareResponseReceived(ConsensusPayload payload, PerpareResponse message)
+ {
+ Log($"{nameof(OnPerpareResponseReceived)} h:{payload.Height} v:{message.ViewNumber} i:{payload.MinerIndex}");
+ if (context.State.HasFlag(ConsensusState.BlockSent)) return;
+ if (context.Signatures[payload.MinerIndex] != null) return;
+ Block header = context.MakeHeader();
+ if (header == null || !header.VerifySignature(context.Miners[payload.MinerIndex], message.Signature)) return;
+ context.Signatures[payload.MinerIndex] = message.Signature;
+ CheckSignatures();
+ }
+
+ private void OnTimeout(object state)
+ {
+ Log($"{nameof(OnTimeout)} h:{timer_height} v:{timer_view} state:{context.State}");
+ lock (context)
+ {
+ if (timer_height != context.Height || timer_view != context.ViewNumber)
+ {
+ Log($"ignored");
+ return;
+ }
+ if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent))
+ {
+ Log($"SendPerpareRequest h:{timer_height} v:{timer_view}");
+ context.State |= ConsensusState.RequestSent;
+ if (!context.State.HasFlag(ConsensusState.SignatureSent))
+ {
+ context.Timestamp = Math.Max(DateTime.Now.ToTimestamp(), Blockchain.Default.GetHeader(context.PrevHash).Timestamp + 1);
+ context.Nonce = GetNonce();
+ List transactions = LocalNode.GetMemoryPool().ToList();
+ transactions.Insert(0, CreateMinerTransaction(transactions, context.Height, context.Nonce));
+ context.TransactionHashes = transactions.Select(p => p.Hash).ToArray();
+ context.Transactions = transactions.ToDictionary(p => p.Hash);
+ context.NextMiner = Blockchain.GetMinerAddress(Blockchain.Default.GetMiners(transactions).ToArray());
+ context.Signatures[context.MinerIndex] = context.MakeHeader().Sign(wallet.GetAccount(context.Miners[context.MinerIndex]));
+ }
+ SignAndRelay(context.MakePerpareRequest());
+ timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer_view + 1)), Timeout.InfiniteTimeSpan);
+ }
+ else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup))
+ {
+ RequestChangeView();
+ }
+ }
+ }
+
+ private void RequestChangeView()
+ {
+ context.ExpectedView[context.MinerIndex]++;
+ Log($"{nameof(RequestChangeView)} h:{context.Height} v:{context.ViewNumber} nv:{context.ExpectedView[context.MinerIndex]} state:{context.State}");
+ timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (context.ExpectedView[context.MinerIndex] + 1)), Timeout.InfiniteTimeSpan);
+ SignAndRelay(context.MakeChangeView());
+ CheckExpectedView(context.ExpectedView[context.MinerIndex]);
+ }
+
+ private void SignAndRelay(ConsensusPayload payload)
+ {
+ SignatureContext sc;
+ try
+ {
+ sc = new SignatureContext(payload);
+ }
+ catch (InvalidOperationException)
+ {
+ return;
+ }
+ wallet.Sign(sc);
+ sc.Signable.Scripts = sc.GetScripts();
+ localNode.Relay(payload);
+ }
+
+ public void Start()
+ {
+ Log("OnStart");
+ started = true;
+ Blockchain.PersistCompleted += Blockchain_PersistCompleted;
+ LocalNode.NewInventory += LocalNode_NewInventory;
+ InitializeConsensus(0);
+ }
+ }
+}
diff --git a/Miner/Miner/Consensus/ConsensusState.cs b/AntSharesCore/Consensus/ConsensusState.cs
similarity index 84%
rename from Miner/Miner/Consensus/ConsensusState.cs
rename to AntSharesCore/Consensus/ConsensusState.cs
index 4b30c05fa7..1926155c1c 100644
--- a/Miner/Miner/Consensus/ConsensusState.cs
+++ b/AntSharesCore/Consensus/ConsensusState.cs
@@ -1,16 +1,16 @@
-using System;
-
-namespace AntShares.Miner.Consensus
-{
- [Flags]
- internal enum ConsensusState : byte
- {
- Initial = 0x00,
- Primary = 0x01,
- Backup = 0x02,
- RequestSent = 0x04,
- RequestReceived = 0x08,
- SignatureSent = 0x10,
- BlockSent = 0x20,
- }
-}
+using System;
+
+namespace AntShares.Consensus
+{
+ [Flags]
+ internal enum ConsensusState : byte
+ {
+ Initial = 0x00,
+ Primary = 0x01,
+ Backup = 0x02,
+ RequestSent = 0x04,
+ RequestReceived = 0x08,
+ SignatureSent = 0x10,
+ BlockSent = 0x20,
+ }
+}
diff --git a/Miner/Miner/Consensus/PerpareRequest.cs b/AntSharesCore/Consensus/PerpareRequest.cs
similarity index 94%
rename from Miner/Miner/Consensus/PerpareRequest.cs
rename to AntSharesCore/Consensus/PerpareRequest.cs
index e7fd7f1a8b..69c411e915 100644
--- a/Miner/Miner/Consensus/PerpareRequest.cs
+++ b/AntSharesCore/Consensus/PerpareRequest.cs
@@ -1,46 +1,46 @@
-using AntShares.Core;
-using AntShares.IO;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace AntShares.Miner.Consensus
-{
- internal class PerpareRequest : ConsensusMessage
- {
- public ulong Nonce;
- public UInt160 NextMiner;
- public UInt256[] TransactionHashes;
- public MinerTransaction MinerTransaction;
- public byte[] Signature;
-
- public PerpareRequest()
- : base(ConsensusMessageType.PerpareRequest)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Nonce = reader.ReadUInt64();
- NextMiner = reader.ReadSerializable();
- TransactionHashes = reader.ReadSerializableArray();
- if (TransactionHashes.Distinct().Count() != TransactionHashes.Length)
- throw new FormatException();
- MinerTransaction = reader.ReadSerializable();
- if (MinerTransaction.Hash != TransactionHashes[0])
- throw new FormatException();
- Signature = reader.ReadBytes(64);
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Nonce);
- writer.Write(NextMiner);
- writer.Write(TransactionHashes);
- writer.Write(MinerTransaction);
- writer.Write(Signature);
- }
- }
-}
+using AntShares.Core;
+using AntShares.IO;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace AntShares.Consensus
+{
+ internal class PerpareRequest : ConsensusMessage
+ {
+ public ulong Nonce;
+ public UInt160 NextMiner;
+ public UInt256[] TransactionHashes;
+ public MinerTransaction MinerTransaction;
+ public byte[] Signature;
+
+ public PerpareRequest()
+ : base(ConsensusMessageType.PerpareRequest)
+ {
+ }
+
+ public override void Deserialize(BinaryReader reader)
+ {
+ base.Deserialize(reader);
+ Nonce = reader.ReadUInt64();
+ NextMiner = reader.ReadSerializable();
+ TransactionHashes = reader.ReadSerializableArray();
+ if (TransactionHashes.Distinct().Count() != TransactionHashes.Length)
+ throw new FormatException();
+ MinerTransaction = reader.ReadSerializable();
+ if (MinerTransaction.Hash != TransactionHashes[0])
+ throw new FormatException();
+ Signature = reader.ReadBytes(64);
+ }
+
+ public override void Serialize(BinaryWriter writer)
+ {
+ base.Serialize(writer);
+ writer.Write(Nonce);
+ writer.Write(NextMiner);
+ writer.Write(TransactionHashes);
+ writer.Write(MinerTransaction);
+ writer.Write(Signature);
+ }
+ }
+}
diff --git a/Miner/Miner/Consensus/PerpareResponse.cs b/AntSharesCore/Consensus/PerpareResponse.cs
similarity index 89%
rename from Miner/Miner/Consensus/PerpareResponse.cs
rename to AntSharesCore/Consensus/PerpareResponse.cs
index 21777db1ae..1afb3a0054 100644
--- a/Miner/Miner/Consensus/PerpareResponse.cs
+++ b/AntSharesCore/Consensus/PerpareResponse.cs
@@ -1,26 +1,26 @@
-using System.IO;
-
-namespace AntShares.Miner.Consensus
-{
- internal class PerpareResponse : ConsensusMessage
- {
- public byte[] Signature;
-
- public PerpareResponse()
- : base(ConsensusMessageType.PerpareResponse)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Signature = reader.ReadBytes(64);
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Signature);
- }
- }
-}
+using System.IO;
+
+namespace AntShares.Consensus
+{
+ internal class PerpareResponse : ConsensusMessage
+ {
+ public byte[] Signature;
+
+ public PerpareResponse()
+ : base(ConsensusMessageType.PerpareResponse)
+ {
+ }
+
+ public override void Deserialize(BinaryReader reader)
+ {
+ base.Deserialize(reader);
+ Signature = reader.ReadBytes(64);
+ }
+
+ public override void Serialize(BinaryWriter writer)
+ {
+ base.Serialize(writer);
+ writer.Write(Signature);
+ }
+ }
+}
diff --git a/AntSharesCore/Wallets/Wallet.cs b/AntSharesCore/Wallets/Wallet.cs
index 01a6a0ce35..c2f391d498 100644
--- a/AntSharesCore/Wallets/Wallet.cs
+++ b/AntSharesCore/Wallets/Wallet.cs
@@ -188,9 +188,7 @@ private static Fixed8 CalculateClaimAmountInternal(IEnumerable unclai
public bool ChangePassword(string password_old, string password_new)
{
- byte[] passwordHash = LoadStoredData("PasswordHash");
- if (!passwordHash.SequenceEqual(password_old.ToAesKey().Sha256()))
- return false;
+ if (!VerifyPassword(password_old)) return false;
byte[] passwordKey = password_new.ToAesKey();
using (new ProtectedMemoryContext(masterKey, MemoryProtectionScope.SameProcess))
{
@@ -736,5 +734,15 @@ public static UInt160 ToScriptHash(string address)
throw new FormatException();
return new UInt160(data.Skip(1).Take(20).ToArray());
}
+
+ public bool VerifyPassword(string password)
+ {
+ return password.ToAesKey().Sha256().SequenceEqual(LoadStoredData("PasswordHash"));
+ }
+
+ public bool VerifyPassword(SecureString password)
+ {
+ return password.ToAesKey().Sha256().SequenceEqual(LoadStoredData("PasswordHash"));
+ }
}
}
diff --git a/AntSharesDaemon/AntSharesDaemon.csproj b/AntSharesDaemon/AntSharesDaemon.csproj
index 84dd2d146a..33c0ecbdaf 100644
--- a/AntSharesDaemon/AntSharesDaemon.csproj
+++ b/AntSharesDaemon/AntSharesDaemon.csproj
@@ -40,6 +40,7 @@
+
diff --git a/Miner/Helper.cs b/AntSharesDaemon/Helper.cs
similarity index 96%
rename from Miner/Helper.cs
rename to AntSharesDaemon/Helper.cs
index ccec336c6e..7549c67a6b 100644
--- a/Miner/Helper.cs
+++ b/AntSharesDaemon/Helper.cs
@@ -1,39 +1,39 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-
-namespace AntShares
-{
- internal static class Helper
- {
- public static bool CompareTo(this SecureString s1, SecureString s2)
- {
- if (s1.Length != s2.Length)
- return false;
- IntPtr p1 = IntPtr.Zero;
- IntPtr p2 = IntPtr.Zero;
- try
- {
- p1 = Marshal.SecureStringToGlobalAllocAnsi(s1);
- p2 = Marshal.SecureStringToGlobalAllocAnsi(s2);
- int i = 0;
- while (true)
- {
- byte b1 = Marshal.ReadByte(p1, i);
- byte b2 = Marshal.ReadByte(p2, i++);
- if (b1 == 0 && b2 == 0)
- return true;
- if (b1 != b2)
- return false;
- if (b1 == 0 || b2 == 0)
- return false;
- }
- }
- finally
- {
- Marshal.ZeroFreeGlobalAllocAnsi(p1);
- Marshal.ZeroFreeGlobalAllocAnsi(p2);
- }
- }
- }
-}
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace AntShares
+{
+ internal static class Helper
+ {
+ public static bool CompareTo(this SecureString s1, SecureString s2)
+ {
+ if (s1.Length != s2.Length)
+ return false;
+ IntPtr p1 = IntPtr.Zero;
+ IntPtr p2 = IntPtr.Zero;
+ try
+ {
+ p1 = Marshal.SecureStringToGlobalAllocAnsi(s1);
+ p2 = Marshal.SecureStringToGlobalAllocAnsi(s2);
+ int i = 0;
+ while (true)
+ {
+ byte b1 = Marshal.ReadByte(p1, i);
+ byte b2 = Marshal.ReadByte(p2, i++);
+ if (b1 == 0 && b2 == 0)
+ return true;
+ if (b1 != b2)
+ return false;
+ if (b1 == 0 || b2 == 0)
+ return false;
+ }
+ }
+ finally
+ {
+ Marshal.ZeroFreeGlobalAllocAnsi(p1);
+ Marshal.ZeroFreeGlobalAllocAnsi(p2);
+ }
+ }
+ }
+}
diff --git a/AntSharesDaemon/Shell/MainService.cs b/AntSharesDaemon/Shell/MainService.cs
index 853774aef6..64b3e9bf6b 100644
--- a/AntSharesDaemon/Shell/MainService.cs
+++ b/AntSharesDaemon/Shell/MainService.cs
@@ -1,16 +1,24 @@
-using AntShares.Core;
+using AntShares.Consensus;
+using AntShares.Core;
using AntShares.Implementations.Blockchains.LevelDB;
+using AntShares.Implementations.Wallets.EntityFramework;
using AntShares.Network;
using AntShares.Network.RPC;
using AntShares.Properties;
using AntShares.Services;
+using AntShares.Wallets;
using System;
+using System.IO;
+using System.Linq;
+using System.Security;
namespace AntShares.Shell
{
internal class MainService : ConsoleServiceBase
{
+ private UserWallet wallet;
private RpcServer rpc;
+ private ConsensusService consensus;
protected LocalNode LocalNode { get; private set; }
protected override string Prompt => "ant";
@@ -20,13 +28,228 @@ protected override bool OnCommand(string[] args)
{
switch (args[0].ToLower())
{
+ case "create":
+ return OnCreateCommand(args);
+ case "list":
+ return OnListCommand(args);
+ case "open":
+ return OnOpenCommand(args);
+ case "send":
+ return OnSendCommand(args);
case "show":
return OnShowCommand(args);
+ case "start":
+ return OnStartCommand(args);
default:
return base.OnCommand(args);
}
}
+ private bool OnCreateCommand(string[] args)
+ {
+ switch (args[1].ToLower())
+ {
+ case "wallet":
+ return OnCreateWalletCommand(args);
+ default:
+ return base.OnCommand(args);
+ }
+ }
+
+ private bool OnCreateWalletCommand(string[] args)
+ {
+ if (args.Length < 3)
+ {
+ Console.WriteLine("error");
+ return true;
+ }
+ using (SecureString password = ReadSecureString("password"))
+ using (SecureString password2 = ReadSecureString("password"))
+ {
+ if (!password.CompareTo(password2))
+ {
+ Console.WriteLine("error");
+ return true;
+ }
+ wallet = UserWallet.Create(args[2], password);
+ foreach (Account account in wallet.GetAccounts())
+ {
+ Console.WriteLine(account.PublicKey.EncodePoint(true).ToHexString());
+ }
+ }
+ return true;
+ }
+
+ private bool OnListCommand(string[] args)
+ {
+ switch (args[1].ToLower())
+ {
+ case "account":
+ return OnListAccountCommand(args);
+ case "address":
+ return OnListAddressCommand(args);
+ case "asset":
+ return OnListAssetCommand(args);
+ default:
+ return base.OnCommand(args);
+ }
+ }
+
+ private bool OnListAccountCommand(string[] args)
+ {
+ if (wallet == null) return true;
+ foreach (Account account in wallet.GetAccounts())
+ {
+ Console.WriteLine(account.PublicKey);
+ }
+ return true;
+ }
+
+ private bool OnListAddressCommand(string[] args)
+ {
+ if (wallet == null) return true;
+ foreach (Contract contract in wallet.GetContracts())
+ {
+ Console.WriteLine($"{contract.Address}\t{contract.GetType()}");
+ }
+ return true;
+ }
+
+ private bool OnListAssetCommand(string[] args)
+ {
+ if (wallet == null) return true;
+ foreach (var item in wallet.FindCoins().Where(p => p.State == CoinState.Unspent || p.State == CoinState.Unconfirmed).GroupBy(p => p.AssetId, (k, g) => new
+ {
+ Asset = (RegisterTransaction)Blockchain.Default.GetTransaction(k),
+ Balance = g.Sum(p => p.Value),
+ Confirmed = g.Where(p => p.State == CoinState.Unspent).Sum(p => p.Value)
+ }))
+ {
+ Console.WriteLine($" id:{item.Asset.Hash}");
+ Console.WriteLine($" name:{item.Asset.GetName()}");
+ Console.WriteLine($" balance:{item.Balance}");
+ Console.WriteLine($"confirmed:{item.Confirmed}");
+ Console.WriteLine();
+ }
+ return true;
+ }
+
+ private bool OnOpenCommand(string[] args)
+ {
+ switch (args[1].ToLower())
+ {
+ case "wallet":
+ return OnOpenWalletCommand(args);
+ default:
+ return base.OnCommand(args);
+ }
+ }
+
+ //TODO: 目前没有想到其它安全的方法来保存密码
+ //所以只能暂时手动输入,但如此一来就不能以服务的方式启动了
+ //未来再想想其它办法,比如采用智能卡之类的
+ private bool OnOpenWalletCommand(string[] args)
+ {
+ if (args.Length < 3)
+ {
+ Console.WriteLine("error");
+ return true;
+ }
+ using (SecureString password = ReadSecureString("password"))
+ {
+ if (password.Length == 0)
+ {
+ Console.WriteLine("cancelled");
+ return true;
+ }
+ try
+ {
+ wallet = UserWallet.Open(args[2], password);
+ }
+ catch
+ {
+ Console.WriteLine($"failed to open file \"{args[2]}\"");
+ return true;
+ }
+ }
+ return true;
+ }
+
+ private bool OnSendCommand(string[] args)
+ {
+ if (wallet == null)
+ {
+ Console.WriteLine("You have to open the wallet first.");
+ return true;
+ }
+ if (args.Length < 4 || args.Length > 5)
+ {
+ Console.WriteLine("error");
+ return true;
+ }
+ UInt256 assetId;
+ switch (args[1].ToLower())
+ {
+ case "ans":
+ assetId = Blockchain.AntShare.Hash;
+ break;
+ case "anc":
+ assetId = Blockchain.AntCoin.Hash;
+ break;
+ default:
+ assetId = UInt256.Parse(args[1]);
+ break;
+ }
+ UInt160 scriptHash = Wallet.ToScriptHash(args[2]);
+ Fixed8 value = Fixed8.Parse(args[3]);
+ Fixed8 fee = args.Length >= 5 ? Fixed8.Parse(args[4]) : Fixed8.Zero;
+ ContractTransaction tx = wallet.MakeTransaction(new ContractTransaction
+ {
+ Outputs = new[]
+ {
+ new TransactionOutput
+ {
+ AssetId = assetId,
+ Value = value,
+ ScriptHash = scriptHash
+ }
+ }
+ }, fee);
+ if (tx == null)
+ {
+ Console.WriteLine("Insufficient funds");
+ return true;
+ }
+ using (SecureString password = ReadSecureString("password"))
+ {
+ if (password.Length == 0)
+ {
+ Console.WriteLine("cancelled");
+ return true;
+ }
+ if (!wallet.VerifyPassword(password))
+ {
+ Console.WriteLine("Incorrect password");
+ return true;
+ }
+ }
+ SignatureContext context = new SignatureContext(tx);
+ wallet.Sign(context);
+ if (context.Completed)
+ {
+ tx.Scripts = context.GetScripts();
+ wallet.SaveTransaction(tx);
+ LocalNode.Relay(tx);
+ Console.WriteLine($"TXID: {tx.Hash}");
+ }
+ else
+ {
+ Console.WriteLine("SignatureContext:");
+ Console.WriteLine(context.ToString());
+ }
+ return true;
+ }
+
private bool OnShowCommand(string[] args)
{
switch (args[1].ToLower())
@@ -79,8 +302,34 @@ protected internal override void OnStart(string[] args)
}
}
+ private bool OnStartCommand(string[] args)
+ {
+ switch (args[1].ToLower())
+ {
+ case "consensus":
+ return OnStartConsensusCommand(args);
+ default:
+ return base.OnCommand(args);
+ }
+ }
+
+ private bool OnStartConsensusCommand(string[] args)
+ {
+ if (wallet == null)
+ {
+ Console.WriteLine("You have to open the wallet first.");
+ return true;
+ }
+ string log_dictionary = Path.Combine(AppContext.BaseDirectory, "Logs");
+ consensus = new ConsensusService(LocalNode, wallet, log_dictionary);
+ ShowPrompt = false;
+ consensus.Start();
+ return true;
+ }
+
protected internal override void OnStop()
{
+ if (consensus != null) consensus.Dispose();
if (rpc != null) rpc.Dispose();
LocalNode.Dispose();
Blockchain.Default.Dispose();
diff --git a/Miner/Algebra/FiniteFieldPoint.cs b/Miner/Algebra/FiniteFieldPoint.cs
deleted file mode 100644
index e16278a007..0000000000
--- a/Miner/Algebra/FiniteFieldPoint.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-using AntShares.IO;
-using System;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace AntShares.Algebra
-{
- ///
- /// Represents a single 2D point using finite field polynomials.
- ///
- public class FiniteFieldPoint : ISerializable
- {
- public FiniteFieldPolynomial X { get; private set; }
- public FiniteFieldPolynomial Y { get; private set; }
-
- public FiniteFieldPoint(FiniteFieldPolynomial x, FiniteFieldPolynomial y)
- {
- X = x;
- Y = y;
- }
-
- public void Deserialize(BinaryReader reader)
- {
- FiniteFieldPolynomial x, y;
- DeserializeFrom(reader, out x, out y);
- this.X = x;
- this.Y = y;
- }
-
- public static FiniteFieldPoint DeserializeFrom(BinaryReader reader)
- {
- FiniteFieldPolynomial x, y;
- DeserializeFrom(reader, out x, out y);
- return new FiniteFieldPoint(x, y);
- }
-
- public static FiniteFieldPoint DeserializeFrom(byte[] value)
- {
- using (MemoryStream ms = new MemoryStream(value, false))
- using (BinaryReader reader = new BinaryReader(ms))
- {
- return DeserializeFrom(reader);
- }
- }
-
- private static void DeserializeFrom(BinaryReader reader, out FiniteFieldPolynomial x, out FiniteFieldPolynomial y)
- {
- int x_i = (int)reader.ReadVarInt(int.MaxValue);
- byte[] y_b = reader.ReadVarBytes();
- IrreduciblePolynomial irp = new IrreduciblePolynomial(y_b.Length * 8);
- x = new FiniteFieldPolynomial(irp, x_i);
- y = new FiniteFieldPolynomial(irp, y_b.ToBigIntegerFromBigEndianUnsignedBytes());
- }
-
- public static FiniteFieldPoint Parse(string s)
- {
- FiniteFieldPoint result;
- if (!TryParse(s, out result))
- {
- throw new ArgumentException();
- }
-
- return result;
- }
-
- public void Serialize(BinaryWriter writer)
- {
- int expectedByteCount = Y.PrimePolynomial.SizeInBytes;
- byte[] pointBytes = Y.PolynomialValue.ToUnsignedBigEndianBytes();
- writer.WriteVarInt((long)X.PolynomialValue);
- writer.WriteVarInt(expectedByteCount);
- writer.Write(new byte[expectedByteCount - pointBytes.Length]);
- writer.Write(pointBytes);
- }
-
- public override string ToString()
- {
- return ToString((int)X.PolynomialValue);
- }
-
- public string ToString(int totalPoints)
- {
- var sb = new StringBuilder();
- // How many decimal digits do the total points take up?
-
- for (int remainder = totalPoints; remainder > 0; remainder /= 10)
- {
- sb.Append('0');
- }
-
- string format = sb.ToString();
-
- string shareNumber = ((long)X.PolynomialValue).ToString(format);
-
-
- var expectedByteCount = Y.PrimePolynomial.SizeInBytes;
- var pointBytes = Y.PolynomialValue.ToUnsignedBigEndianBytes();
-
- // Occasionally, the value won't fill all bytes, so we need to prefix with 0's as needed
- var prefixedPointBytes = Enumerable.Repeat((byte)0, expectedByteCount - pointBytes.Length).Concat(pointBytes);
-
- // To hex string on its own just wasn't working right
- string shareValue = String.Join("", prefixedPointBytes.Select(b => b.ToString("x2")));
- return shareNumber + "-" + shareValue;
- }
-
- public static bool TryParse(string s, out FiniteFieldPoint result)
- {
- var match = Regex.Match(s, @"(?[0-9]+)-(?[0-9a-fA-F]+)");
-
- if (!match.Success)
- {
- result = null;
- return false;
- }
-
- try
- {
- var xString = match.Groups["x"].Value.ToLowerInvariant();
- var yString = match.Groups["y"].Value.ToLowerInvariant();
-
- // Each hex letter makes up 4 bits, so to get the degree in bits
- // we multiply by 4
-
- int polynomialDegree = yString.Length * 4;
-
- var irp = new IrreduciblePolynomial(polynomialDegree);
-
- var x = new FiniteFieldPolynomial(irp, BigInteger.Parse(xString));
-
- // get bytes
- var bigEndianBytes = new byte[yString.Length / 2];
- for (int i = 0; i < yString.Length; i += 2)
- {
- bigEndianBytes[i / 2] = Byte.Parse(yString.Substring(i, 2), NumberStyles.HexNumber);
- }
- var y = new FiniteFieldPolynomial(irp, bigEndianBytes.ToBigIntegerFromBigEndianUnsignedBytes());
-
- result = new FiniteFieldPoint(x, y);
- return true;
- }
- catch
- {
- result = null;
- return false;
- }
- }
- }
-}
diff --git a/Miner/Algebra/FiniteFieldPolynomial.cs b/Miner/Algebra/FiniteFieldPolynomial.cs
deleted file mode 100644
index 9884eac8de..0000000000
--- a/Miner/Algebra/FiniteFieldPolynomial.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-using System.Numerics;
-
-namespace AntShares.Algebra
-{
- ///
- /// Represents a polynomial modulo an irreducible polynomial (in a finite field).
- ///
- public class FiniteFieldPolynomial
- {
- private readonly IrreduciblePolynomial _PrimePolynomial;
- private readonly BigInteger _PolynomialSetCoefficients;
-
- public FiniteFieldPolynomial(IrreduciblePolynomial primePolynomial, BigInteger polynomial)
- {
- _PrimePolynomial = primePolynomial;
- _PolynomialSetCoefficients = polynomial;
- }
-
- public FiniteFieldPolynomial(IrreduciblePolynomial primePolynomial, params int[] setCoefficients)
- {
- _PrimePolynomial = primePolynomial;
-
- _PolynomialSetCoefficients = BigInteger.Zero;
- for (int i = 0; i < setCoefficients.Length; i++)
- {
- _PolynomialSetCoefficients = _PolynomialSetCoefficients.SetBit(setCoefficients[i]);
- }
- }
-
- public FiniteFieldPolynomial Clone()
- {
- return new FiniteFieldPolynomial(_PrimePolynomial, _PolynomialSetCoefficients);
- }
-
- public BigInteger PolynomialValue
- {
- get { return _PolynomialSetCoefficients; }
- }
-
-
- public IrreduciblePolynomial PrimePolynomial
- {
- get { return _PrimePolynomial; }
- }
-
- public static FiniteFieldPolynomial EvaluateAt(long x, FiniteFieldPolynomial[] coefficients)
- {
- // Use Horner's Scheme: http://en.wikipedia.org/wiki/Horner_scheme
-
- FiniteFieldPolynomial xAsPoly = coefficients[0].GetValueInField(x);
-
- // assume the coefficient for highest monomial is 1
- FiniteFieldPolynomial result = xAsPoly.Clone();
-
- for (int i = coefficients.Length - 1; i > 0; i--)
- {
- result = result + coefficients[i];
- result = result * xAsPoly;
- }
-
- result = result + coefficients[0];
-
- return result;
- }
-
- public static FiniteFieldPolynomial operator +(FiniteFieldPolynomial left, FiniteFieldPolynomial right)
- {
- BigInteger result = left._PolynomialSetCoefficients ^ right._PolynomialSetCoefficients;
- return new FiniteFieldPolynomial(left._PrimePolynomial, result);
- }
-
- public static FiniteFieldPolynomial operator *(FiniteFieldPolynomial left, FiniteFieldPolynomial right)
- {
- // Use a modified version of the "peasant's algorithm":
- // http://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
- // The invariant is that a * b + p must always equal the product. We keep
- // doubling "a" and halving "b". If "b" is odd, then we add "a" to "p"
-
- BigInteger p = BigInteger.Zero;
- BigInteger a = left._PolynomialSetCoefficients;
- BigInteger b = right._PolynomialSetCoefficients;
-
- int degree = left._PrimePolynomial.Degree;
-
- BigInteger mask = (BigInteger.One << degree) - BigInteger.One;
-
- for (int i = 0; i < degree; i++)
- {
- if ((a == BigInteger.Zero) || (b == BigInteger.Zero))
- {
- break;
- }
-
- if (b.TestBit(0))
- {
- // It's odd, add it
- p = p ^ a;
- }
-
- bool highBitSet = a.TestBit(degree - 1);
-
- // multiply a by "x"
-
- a = a << 1;
- a = a & mask;
-
- if (highBitSet)
- {
- a = a ^ left._PrimePolynomial.PolynomialValue;
- a = a & mask;
- }
-
- b = b >> 1;
- }
-
- p = p & mask;
-
- return new FiniteFieldPolynomial(left._PrimePolynomial, p);
- }
-
- public FiniteFieldPolynomial GetInverse()
- {
- // We need to compute the inverse of the current polynomial
- // modulo the irreducible polynomial. We'll do this with
- // a simplified version of the Euclidean algorithm:
- // http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Computing_a_multiplicative_inverse_in_a_finite_field
- // Instead of allowing division by arbitrary polynomials such as
- // x^4 + x^3 + 1, we'll always divide by monomials like x^4.
- // This makes multiplication and division by using just shifts.
-
- BigInteger r_minus2 = _PrimePolynomial.PolynomialValue;
- BigInteger r_minus1 = _PolynomialSetCoefficients;
- BigInteger a_minus2 = BigInteger.Zero;
- BigInteger a_minus1 = BigInteger.One;
-
- while (!r_minus1.Equals(BigInteger.One))
- {
- // How much do I need to shift by?
- int shiftAmount = r_minus2.GetBitLength() - r_minus1.GetBitLength();
-
- if (shiftAmount < 0)
- {
- Swap(ref r_minus2, ref r_minus1);
- Swap(ref a_minus2, ref a_minus1);
- shiftAmount = -shiftAmount;
- }
-
- // Now r_minus2 should be as big or bigger than r_minus1
- // q = BigInteger.One.ShiftLeft(shiftAmount)
- BigInteger r_minus1TimesQ = r_minus1 << shiftAmount;
- BigInteger r_new = r_minus1TimesQ ^ r_minus2;
-
- BigInteger a_new = (a_minus1 << shiftAmount) ^ a_minus2;
-
- r_minus2 = r_minus1;
- r_minus1 = r_new;
- a_minus2 = a_minus1;
- a_minus1 = a_new;
- }
-
- return new FiniteFieldPolynomial(_PrimePolynomial, a_minus1);
- }
-
- public FiniteFieldPolynomial Zero
- {
- get { return GetValueInField(0); }
- }
-
- public FiniteFieldPolynomial One
- {
- get { return GetValueInField(1); }
- }
-
- private FiniteFieldPolynomial GetValueInField(long n)
- {
- return new FiniteFieldPolynomial(_PrimePolynomial, new BigInteger(n));
- }
-
- public override string ToString()
- {
- return _PolynomialSetCoefficients.ToPolynomialString();
- }
-
- private static void Swap(ref BigInteger a, ref BigInteger b)
- {
- var temp = b;
- b = a;
- a = temp;
- }
-
- public override bool Equals(object obj)
- {
- var other = obj as FiniteFieldPolynomial;
- if (other == null)
- {
- return base.Equals(obj);
- }
-
- return (PrimePolynomial == other.PrimePolynomial)
- &&
- (PolynomialValue.Equals(other.PolynomialValue));
- }
-
- public override int GetHashCode()
- {
- return PrimePolynomial.GetHashCode() ^ PolynomialValue.GetHashCode();
- }
- }
-}
diff --git a/Miner/Algebra/IrreduciblePolynomial.cs b/Miner/Algebra/IrreduciblePolynomial.cs
deleted file mode 100644
index 8d76f40668..0000000000
--- a/Miner/Algebra/IrreduciblePolynomial.cs
+++ /dev/null
@@ -1,397 +0,0 @@
-using System;
-using System.Numerics;
-
-namespace AntShares.Algebra
-{
- ///
- /// Polynomials that are irreducible (for use with a finite field).
- ///
- public class IrreduciblePolynomial
- {
- private const int InnerTermsPerPolynomial = 3;
- // pentanomials
- // For details on where this came from, see my question on:
- // http://math.stackexchange.com/questions/14787/finding-irreducible-polynomials-over-gf2-with-the-fewest-terms
- // The larger ones came directly from "Table of Low-Weight Binary Irreducible Polynomials" by HP Research
- private static readonly int[] _TermPowers = new[] {
- 4, 3, 1, 5, 3, 1, 4, 3, 1, 7, 3, 2, 5, 4, 3, 5, 3, 2, 7, 4
- , 2, 4, 3, 1, // x^64
- 10, 9, 3, 9, 4, 2, 7, 6, 2, 10, 9, 6, 4, 3, 1, 5, 4, 3, 4,
- 3, 1, 7, 2, 1, // x^128
- 5, 3, 2, 7, 4, 2, 6, 3, 2, 5, 3, 2, 15, 3, 2, 11, 3, 2, 9,
- 8, 7, 7, 2, 1, // x^192
- 5, 3, 2, 9, 3, 1, 7, 3, 1, 9, 8, 3, 9, 4, 2, 8, 5, 3, 15,
- 14, 10, 10, 5, 2, // x^256
- 9, 6, 2, 9, 3, 2, 9, 5, 2, 11, 10, 1, 7, 3, 2, 11, 2, 1, 9
- , 7, 4, 4, 3, 1, // x^320
- 8, 3, 1, 7, 4, 1, 7, 2, 1, 13, 11, 6, 5, 3, 2, 7, 3, 2, 8,
- 7, 5, 12, 3, 2, // x^384
- 13, 10, 6, 5, 3, 2, 5, 3, 2, 9, 5, 2, 9, 7, 2, 13, 4, 3, 4
- , 3, 1, 11, 6, 4, // x^448
- 18, 9, 6, 19, 18, 13, 11, 3, 2, 15, 9, 6, 4, 3, 1, 16, 5,
- 2, 15, 14, 6, 8, 5, 2, // x^512
- 15, 11, 2, 11, 6, 2, 7, 5, 3, 8, 3, 1, 19, 16, 9, 11, 9, 6
- , 15, 7, 6, 13, 4, 3, // x^576
- 14, 13, 3, 13, 6, 3, 9, 5, 2, 19, 13, 6, 19, 10, 3, 11, 6,
- 5, 9, 2, 1, 14, 3, 2, // x^640
- 13, 3, 1, 7, 5, 4, 11, 9, 8, 11, 6, 5, 23, 16, 9, 19, 14,
- 6, 23, 10, 2, 8, 3, 2, // x^704
- 5, 4, 3, 9, 6, 4, 4, 3, 2, 13, 8, 6, 13, 11, 1, 13, 10, 3,
- 11, 6, 5, 19, 17, 4, // x^768
- 15, 14, 7, 13, 9, 6, 9, 7, 3, 9, 7, 1, 14, 3, 2, 11, 8, 2,
- 11, 6, 4, 13, 5, 2, // x^832
- 11, 5, 1, 11, 4, 1, 19, 10, 3, 21, 10, 6, 13, 3, 1, 15, 7,
- 5, 19, 18, 10, 7, 5, 3, // x^896
- 12, 7, 2, 7, 5, 1, 14, 9, 6, 10, 3, 2, 15, 13, 12, 12, 11,
- 9, 16, 9, 7, 12, 9, 3, // x^960
- 9, 5, 2, 17, 10, 6, 24, 9, 3, 17, 15, 13, 5, 4, 3, 19, 17,
- 8, 15, 6, 3, 19, 6, 1, // x^1024
- 21, 15, 3, 15, 10, 8, 15, 7, 2, 11, 2, 1, 13, 11, 9, 19, 9
- , 8, 15, 9, 6, 22, 21, 10, // x^1088
- 24, 15, 6, 21, 9, 6, 15, 8, 6, 13, 9, 6, 7, 3, 1, 9, 4, 2,
- 11, 9, 7, 15, 3, 2, // x^1152
- 15, 11, 2, 12, 7, 2, 11, 9, 3, 5, 3, 2, 9, 8, 7, 15, 9, 6,
- 11, 10, 6, 27, 25, 9, // x^1216
- 12, 9, 7, 25, 10, 2, 17, 7, 5, 15, 5, 3, 31, 30, 2, 5, 3,
- 2, 16, 9, 7, 12, 7, 5, // x^1280
- 23, 16, 6, 15, 14, 2, 20, 17, 15, 15, 14, 2, 12, 9, 3, 21,
- 11, 3, 8, 3, 2, 15, 6, 1, // x^1344
- 17, 14, 6, 5, 3, 2, 15, 9, 5, 19, 18, 10, 11, 5, 1, 17, 15
- , 5, 8, 3, 1, 14, 13, 6, // x^1408
- 10, 9, 6, 11, 6, 2, 11, 10, 6, 14, 13, 7, 11, 3, 2, 9, 4,
- 2, 12, 9, 3, 11, 4, 1, // x^1472
- 11, 10, 2, 9, 8, 6, 13, 11, 4, 8, 3, 2, 10, 9, 3, 13, 10,
- 3, 18, 17, 7, 21, 6, 2, // x^1536
- 11, 7, 1, 19, 12, 2, 8, 5, 2, 21, 10, 7, 20, 9, 2, 21, 19,
- 13, 12, 7, 5, 14, 11, 1, // x^1600
- 15, 13, 1, 13, 4, 3, 13, 11, 5, 17, 15, 3, 7, 5, 1, 18, 13
- , 1, 19, 15, 10, 17, 9, 6, // x^1664
- 5, 4, 3, 11, 6, 2, 15, 8, 6, 15, 6, 3, 14, 11, 3, 15, 12,
- 5, 17, 14, 10, 11, 10, 5, // x^1728
- 19, 14, 6, 19, 18, 2, 6, 3, 2, 8, 3, 2, 25, 6, 5, 10, 9, 3
- , 23, 21, 6, 17, 14, 3, // x^1792
- 22, 5, 2, 19, 16, 9, 23, 18, 1, 7, 5, 1, 18, 13, 7, 21, 10
- , 2, 16, 13, 3, 11, 9, 4, // x^1856
- 11, 9, 1, 10, 5, 2, 15, 4, 2, 17, 13, 2, 26, 11, 2, 12, 11
- , 1, 20, 15, 10, 11, 3, 2, // x^1920
- 17, 16, 7, 15, 10, 1, 27, 22, 18, 15, 14, 6, 17, 15, 2, 25
- , 19, 14, 25, 19, 17, 13, 11, 5, // x^1984
- 6, 3, 2, 13, 10, 6, 26, 23, 13, 21, 15, 7, 40, 35, 9, 7, 6
- , 2, 7, 2, 1, 19, 14, 13, // x^2048
- 13, 12, 3, 17, 9, 2, 13, 10, 3, 4, 3, 1, 18, 11, 5, 19, 4,
- 2, 19, 15, 9, 16, 13, 7, // x^2112
- 17, 14, 6, 23, 9, 1, 15, 12, 9, 13, 7, 3, 24, 13, 7, 31,
- 25, 14, 11, 9, 3, 15, 8, 1, // x^2176
- 11, 10, 5, 8, 5, 3, 20, 15, 5, 21, 16, 6, 24, 7, 2, 21, 19
- , 5, 19, 17, 4, 23, 7, 1, // x^2240
- 9, 4, 3, 14, 9, 6, 15, 7, 2, 21, 10, 9, 13, 4, 2, 17, 16,
- 7, 15, 10, 1, 8, 7, 5, // x^2304
- 19, 6, 4, 13, 11, 5, 15, 9, 2, 15, 10, 8, 27, 26, 14, 23,
- 20, 2, 19, 10, 8, 13, 11, 8, // x^2368
- 7, 5, 4, 21, 19, 1, 31, 13, 3, 20, 19, 17, 23, 6, 4, 23, 6
- , 5, 21, 16, 6, 29, 22, 19, // x^2432
- 12, 7, 5, 21, 10, 4, 12, 5, 3, 5, 4, 3, 12, 3, 1, 20, 5, 2
- , 23, 13, 9, 12, 3, 1, // x^2496
- 19, 8, 6, 29, 21, 7, 31, 15, 13, 19, 9, 4, 21, 10, 9, 21,
- 20, 6, 28, 3, 2, 9, 3, 1, // x^2560
- 8, 5, 2, 7, 2, 1, 25, 19, 12, 15, 12, 5, 14, 13, 7, 15, 11
- , 2, 17, 8, 7, 15, 10, 4, // x^2624
- 19, 5, 3, 23, 11, 9, 15, 8, 1, 19, 11, 5, 27, 21, 19, 18,
- 7, 1, 15, 9, 4, 21, 10, 6, // x^2688
- 17, 15, 12, 12, 9, 7, 21, 12, 7, 25, 18, 1, 21, 7, 5, 16,
- 3, 1, 19, 18, 10, 15, 4, 2, // x^2752
- 29, 26, 7, 25, 19, 15, 7, 3, 2, 29, 21, 15, 12, 7, 2, 17,
- 14, 6, 15, 13, 1, 21, 19, 8, // x^2816
- 15, 14, 10, 27, 18, 1, 20, 15, 9, 15, 8, 1, 15, 13, 3, 21,
- 17, 15, 21, 5, 2, 13, 10, 6, // x^2880
- 11, 4, 1, 29, 6, 1, 27, 15, 6, 16, 9, 2, 19, 9, 5, 24, 21,
- 11, 5, 3, 2, 5, 3, 2, // x^2944
- 17, 13, 2, 12, 3, 2, 29, 27, 4, 21, 10, 3, 17, 9, 6, 23, 3
- , 1, 15, 12, 9, 15, 13, 1, // x^3008
- 38, 25, 9, 32, 3, 2, 17, 15, 4, 27, 21, 3, 18, 3, 2, 5, 4,
- 3, 25, 11, 9, 11, 10, 5, // x^3072
- 21, 19, 16, 20, 13, 11, 33, 29, 14, 23, 9, 5, 17, 15, 1,
- 18, 17, 11, 30, 19, 11, 15, 12, 10, // x^3136
- 23, 21, 8, 21, 17, 6, 7, 6, 2, 33, 31, 18, 13, 10, 5, 11,
- 10, 2, 25, 8, 7, 11, 6, 4, // x^3200
- 16, 13, 3, 21, 11, 3, 23, 19, 1, 12, 9, 7, 12, 3, 2, 15, 8
- , 1, 31, 26, 2, 17, 5, 2, // x^3264
- 23, 10, 1, 16, 15, 6, 21, 18, 11, 19, 14, 13, 19, 17, 3,
- 14, 9, 3, 17, 10, 4, 17, 9, 2, // x^3328
- 11, 10, 5, 30, 27, 15, 21, 20, 19, 18, 15, 5, 7, 5, 1, 11,
- 9, 1, 21, 9, 3, 23, 13, 6, // x^3392
- 14, 13, 6, 16, 15, 6, 28, 27, 1, 22, 15, 6, 25, 2, 1, 27,
- 16, 1, 17, 11, 6, 19, 18, 9, // x^3456
- 11, 6, 3, 17, 14, 7, 19, 15, 13, 12, 11, 1, 35, 21, 4, 23,
- 17, 10, 37, 35, 6, 32, 29, 3, // x^3520
- 25, 18, 7, 12, 7, 5, 21, 14, 2, 15, 9, 6, 17, 3, 2, 21, 12
- , 10, 19, 10, 3, 25, 12, 10, // x^3584
- 38, 33, 14, 9, 5, 2, 15, 14, 10, 25, 18, 7, 29, 27, 12, 26
- , 17, 5, 20, 15, 10, 23, 7, 2, // x^3648
- 17, 12, 11, 35, 24, 14, 19, 17, 8, 14, 13, 7, 32, 13, 11,
- 36, 33, 22, 14, 13, 1, 13, 12, 7, // x^3712
- 17, 15, 11, 9, 4, 2, 33, 22, 18, 27, 14, 2, 9, 4, 2, 23, 9
- , 1, 14, 7, 2, 7, 5, 4, // x^3776
- 29, 13, 6, 20, 7, 5, 24, 23, 21, 29, 18, 4, 19, 13, 9, 19,
- 13, 2, 35, 13, 2, 27, 9, 1, // x^3840
- 29, 18, 13, 39, 25, 3, 19, 15, 9, 10, 3, 2, 27, 5, 1, 45,
- 42, 6, 15, 7, 5, 17, 13, 2, // x^3904
- 24, 11, 2, 15, 13, 8, 8, 7, 5, 15, 5, 3, 31, 29, 28, 11, 6
- , 5, 29, 15, 2, 25, 18, 14, // x^3968
- 36, 3, 1, 19, 5, 2, 27, 8, 6, 31, 18, 17, 24, 9, 6, 33, 32
- , 23, 16, 9, 7, 15, 13, 6, // x^4032
- 29, 20, 15, 21, 5, 2, 21, 17, 6, 33, 29, 7, 13, 10, 6, 15,
- 9, 6, 15, 7, 2, 27, 15, 1, // x^4096
- 30, 13, 3, 23, 12, 1, 26, 17, 9, 31, 2, 1, 31, 29, 15, 15,
- 10, 1, 25, 13, 3, 27, 18, 12, // x^4160
- 17, 10, 6, 26, 15, 5, 29, 15, 7, 15, 11, 5, 12, 5, 2, 15,
- 6, 3, 13, 3, 2, 8, 3, 2, // x^4224
- 18, 13, 7, 31, 6, 1, 11, 6, 2, 15, 13, 8, 15, 14, 5, 11, 8
- , 1, 17, 14, 5, 5, 4, 3, // x^4288
- 14, 5, 2, 12, 7, 2, 21, 5, 2, 21, 20, 14, 20, 17, 15, 18,
- 11, 5, 8, 7, 5, 33, 27, 20, // x^4352
- 21, 4, 2, 27, 12, 6, 18, 7, 1, 27, 19, 17, 20, 19, 5, 37,
- 35, 3, 9, 8, 7, 31, 10, 6, // x^4416
- 21, 19, 13, 25, 5, 3, 26, 21, 14, 11, 9, 8, 24, 9, 7, 13,
- 3, 1, 30, 7, 2, 28, 21, 15, // x^4480
- 38, 35, 13, 17, 10, 7, 12, 9, 6, 12, 3, 1, 39, 25, 23, 23,
- 13, 9, 25, 11, 7, 25, 14, 7, // x^4544
- 34, 27, 18, 14, 13, 7, 22, 17, 6, 26, 19, 9, 19, 15, 9, 21
- , 16, 11, 17, 14, 1, 23, 20, 13, // x^4608
- 27, 23, 5, 26, 23, 10, 19, 16, 2, 25, 8, 7, 8, 5, 3, 27,
- 25, 4, 37, 6, 5, 27, 25, 23, // x^4672
- 10, 9, 3, 13, 7, 6, 18, 17, 11, 11, 8, 1, 25, 16, 6, 24,
- 19, 9, 26, 21, 14, 15, 10, 1, // x^4736
- 19, 14, 6, 29, 5, 2, 28, 11, 9, 25, 17, 3, 27, 23, 6, 30,
- 29, 7, 29, 18, 4, 29, 19, 11, // x^4800
- 13, 4, 2, 33, 31, 25, 25, 16, 3, 33, 30, 5, 25, 21, 2, 28,
- 27, 6, 27, 23, 21, 29, 22, 17, // x^4864
- 24, 9, 2, 32, 21, 7, 35, 21, 8, 21, 19, 12, 27, 18, 15, 30
- , 29, 7, 11, 9, 5, 29, 9, 3, // x^4928
- 27, 22, 15, 19, 6, 4, 29, 11, 5, 25, 20, 6, 26, 25, 17, 42
- , 7, 1, 23, 16, 9, 15, 8, 6, // x^4992
- 17, 15, 7, 21, 10, 3, 15, 12, 9, 33, 23, 14, 25, 6, 2, 24,
- 5, 3, 34, 15, 10, 22, 9, 6, // x^5056
- 21, 12, 11, 25, 5, 3, 21, 7, 6, 22, 21, 3, 19, 18, 13, 30,
- 13, 2, 42, 33, 9, 33, 27, 5, // x^5120
- 24, 15, 6, 27, 25, 4, 15, 11, 5, 15, 8, 1, 35, 31, 13, 15,
- 11, 5, 24, 21, 3, 20, 11, 5, // x^5184
- 11, 8, 2, 33, 27, 19, 23, 22, 2, 27, 19, 2, 29, 15, 1, 21,
- 11, 2, 33, 27, 21, 27, 18, 1, // x^5248
- 9, 5, 2, 16, 11, 9, 29, 18, 10, 13, 11, 1, 11, 10, 1, 8, 3
- , 2, 27, 6, 5, 22, 3, 2, // x^5312
- 19, 17, 3, 30, 27, 9, 23, 21, 8, 17, 11, 10, 23, 20, 1, 19
- , 11, 1, 19, 18, 3, 7, 4, 1, // x^5376
- 17, 15, 4, 7, 3, 2, 33, 17, 3, 30, 23, 1, 34, 31, 19, 16,
- 15, 13, 37, 34, 23, 24, 15, 10, // x^5440
- 43, 33, 15, 21, 14, 10, 15, 5, 2, 21, 15, 3, 13, 10, 3, 21
- , 19, 9, 13, 11, 4, 20, 19, 1, // x^5504
- 13, 11, 6, 10, 5, 2, 25, 18, 14, 20, 5, 3, 11, 10, 2, 15,
- 9, 8, 55, 46, 10, 33, 22, 7, // x^5568
- 27, 23, 6, 13, 9, 7, 29, 20, 7, 8, 5, 3, 22, 5, 2, 30, 15,
- 6, 21, 18, 14, 17, 15, 5, // x^5632
- 29, 27, 23, 21, 15, 8, 27, 12, 9, 31, 29, 11, 26, 25, 10,
- 40, 17, 2, 41, 20, 11, 26, 21, 14, // x^5696
- 27, 25, 14, 10, 9, 3, 32, 11, 2, 25, 24, 7, 25, 18, 10, 21
- , 11, 8, 21, 20, 7, 29, 23, 10, // x^5760
- 21, 14, 3, 19, 12, 1, 25, 22, 6, 33, 13, 11, 25, 7, 6, 43,
- 10, 1, 17, 15, 7, 23, 17, 10, // x^5824
- 21, 18, 13, 23, 14, 2, 19, 8, 6, 23, 15, 6, 27, 11, 10, 19
- , 15, 10, 21, 10, 3, 23, 10, 4, // x^5888
- 30, 23, 1, 32, 19, 5, 33, 22, 13, 16, 15, 6, 16, 7, 2, 27,
- 4, 1, 23, 21, 14, 25, 23, 2, // x^5952
- 37, 35, 25, 21, 14, 4, 18, 9, 6, 17, 7, 1, 29, 9, 2, 23,
- 21, 12, 30, 27, 15, 35, 34, 2, // x^6016
- 39, 33, 26, 44, 21, 14, 25, 11, 5, 17, 15, 8, 7, 6, 1, 23,
- 18, 11, 28, 15, 13, 19, 8, 6, // x^6080
- 23, 10, 3, 20, 11, 2, 13, 11, 6, 35, 12, 1, 4, 3, 1, 34,
- 15, 2, 17, 7, 5, 26, 7, 1, // x^6144
- 28, 27, 13, 38, 15, 10, 20, 11, 2, 29, 15, 1, 39, 13, 12,
- 20, 5, 2, 29, 10, 7, 25, 23, 14, // x^6208
- 39, 30, 9, 13, 4, 2, 17, 3, 1, 11, 10, 2, 18, 7, 2, 11, 10
- , 5, 17, 16, 7, 17, 10, 6, // x^6272
- 9, 7, 5, 34, 25, 5, 35, 19, 10, 13, 3, 1, 35, 33, 14, 29,
- 28, 10, 15, 6, 1, 22, 15, 9, // x^6336
- 21, 15, 2, 21, 11, 4, 13, 11, 1, 31, 9, 1, 28, 27, 5, 34,
- 29, 7, 39, 34, 10, 37, 12, 3, // x^6400
- 31, 12, 10, 29, 15, 7, 29, 18, 5, 26, 13, 7, 21, 18, 14,
- 25, 23, 8, 31, 25, 17, 25, 22, 6, // x^6464
- 31, 30, 2, 11, 10, 1, 21, 13, 7, 21, 5, 2, 23, 15, 9, 29,
- 27, 13, 37, 29, 11, 16, 7, 2, // x^6528
- 25, 10, 9, 19, 15, 1, 27, 22, 6, 19, 13, 11, 19, 15, 1, 27
- , 25, 19, 37, 23, 7, 45, 42, 1, // x^6592
- 21, 19, 16, 9, 4, 2, 33, 9, 3, 15, 14, 9, 27, 20, 17, 43,
- 32, 9, 25, 19, 16, 19, 15, 1, // x^6656
- 24, 15, 6, 26, 21, 5, 29, 7, 3, 55, 32, 9, 45, 19, 7, 11,
- 10, 6, 31, 26, 2, 12, 9, 7, // x^6720
- 21, 8, 2, 27, 14, 2, 29, 21, 15, 11, 8, 2, 37, 15, 7, 18,
- 15, 10, 25, 11, 6, 16, 15, 1, // x^6784
- 27, 25, 24, 26, 25, 1, 37, 19, 13, 22, 5, 2, 21, 14, 10,
- 35, 32, 25, 14, 9, 3, 29, 22, 18, // x^6848
- 30, 29, 17, 11, 5, 2, 25, 13, 2, 31, 30, 19, 24, 11, 9, 29
- , 17, 11, 36, 13, 11, 25, 15, 12, // x^6912
- 8, 3, 1, 8, 7, 5, 37, 31, 30, 23, 21, 8, 32, 21, 19, 14, 9
- , 3, 35, 32, 17, 19, 18, 9, // x^6976
- 8, 3, 2, 27, 11, 9, 27, 26, 11, 33, 25, 6, 23, 10, 7, 22,
- 15, 10, 19, 13, 9, 19, 18, 7, // x^7040
- 39, 17, 4, 27, 24, 10, 11, 5, 2, 37, 26, 17, 27, 18, 16,
- 32, 5, 2, 27, 17, 13, 15, 10, 4, // x^7104
- 35, 5, 2, 17, 15, 5, 19, 13, 2, 16, 3, 2, 33, 13, 3, 37,
- 23, 16, 27, 26, 9, 13, 10, 6, // x^7168
- 33, 31, 21, 33, 27, 2, 29, 14, 6, 29, 23, 3, 29, 23, 21,
- 15, 8, 1, 15, 12, 10, 35, 12, 9, // x^7232
- 33, 14, 2, 17, 7, 4, 22, 21, 7, 41, 36, 19, 23, 10, 4, 37,
- 6, 4, 25, 23, 17, 37, 7, 2, // x^7296
- 37, 30, 17, 25, 24, 3, 35, 28, 10, 41, 30, 26, 34, 21, 5,
- 33, 28, 3, 20, 5, 3, 23, 18, 2, // x^7360
- 19, 13, 11, 41, 22, 16, 31, 26, 9, 33, 27, 21, 19, 9, 5,
- 13, 3, 1, 35, 23, 9, 18, 13, 7, // x^7424
- 30, 19, 7, 22, 21, 15, 21, 20, 14, 27, 8, 1, 21, 18, 14,
- 23, 13, 7, 32, 15, 2, 21, 16, 6, // x^7488
- 23, 21, 12, 45, 17, 2, 22, 21, 3, 19, 9, 7, 18, 13, 1, 42,
- 21, 14, 23, 13, 7, 17, 8, 3, // x^7552
- 41, 21, 3, 15, 5, 3, 41, 40, 11, 51, 46, 10, 45, 10, 1, 19
- , 18, 2, 39, 25, 10, 31, 21, 14, // x^7616
- 9, 2, 1, 54, 3, 2, 29, 3, 2, 37, 33, 10, 30, 13, 7, 30, 23
- , 5, 39, 5, 1, 27, 9, 3, // x^7680
- 35, 16, 6, 17, 16, 15, 15, 12, 10, 27, 22, 5, 27, 25, 4,
- 21, 6, 3, 22, 11, 3, 33, 28, 27, // x^7744
- 35, 30, 2, 32, 23, 21, 27, 18, 15, 41, 39, 36, 7, 4, 2, 47
- , 31, 29, 11, 10, 5, 25, 24, 10, // x^7808
- 20, 3, 2, 39, 36, 14, 37, 19, 3, 33, 29, 23, 34, 31, 21,
- 12, 3, 2, 19, 13, 1, 27, 22, 18, // x^7872
- 25, 19, 17, 12, 9, 7, 45, 39, 7, 45, 34, 25, 7, 3, 2, 20,
- 19, 5, 23, 15, 5, 40, 23, 21, // x^7936
- 14, 7, 1, 19, 13, 2, 19, 13, 12, 27, 13, 12, 44, 5, 3, 37,
- 18, 2, 26, 25, 17, 16, 3, 1, // x^8000
- 23, 22, 17, 31, 30, 25, 21, 14, 11, 19, 15, 13, 39, 13, 7,
- 30, 23, 3, 27, 16, 5, 27, 23, 9, // x^8064
- 23, 11, 6, 39, 14, 11, 25, 10, 8, 32, 11, 2, 30, 23, 17,
- 15, 12, 2, 8, 3, 2, 25, 24, 19, // x^8128
- 11, 3, 2, 28, 27, 17, 29, 25, 14, 52, 45, 10, 25, 16, 6,
- 43, 32, 21, 32, 27, 6, 9, 5, 2, // x^8192
- 18, 15, 3, 19, 13, 11, 27, 24, 17, 39, 36, 25, 22, 15, 9,
- 14, 13, 7, 25, 15, 13, 32, 21, 14, // x^8256
- 15, 6, 3, 32, 25, 23, 30, 19, 9, 27, 5, 4, 37, 19, 6, 32,
- 17, 15, 45, 44, 30, 41, 39, 5, // x^8320
- 37, 23, 14, 33, 10, 2, 27, 15, 1, 35, 18, 14, 15, 14, 5,
- 35, 17, 4, 45, 39, 17, 19, 4, 2, // x^8384
- 17, 11, 1, 29, 28, 11, 20, 9, 2, 40, 33, 22, 33, 31, 28,
- 17, 15, 13, 18, 9, 6, 21, 17, 6, // x^8448
- 15, 13, 8, 34, 15, 5, 30, 21, 5, 21, 6, 3, 13, 6, 3, 25,
- 19, 3, 35, 24, 10, 33, 27, 4, // x^8512
- 28, 15, 13, 15, 4, 2, 19, 10, 3, 31, 5, 2, 29, 10, 1, 21,
- 13, 3, 28, 25, 10, 19, 9, 1, // x^8576
- 32, 15, 13, 23, 5, 4, 21, 14, 3, 47, 44, 33, 22, 19, 11, 4
- , 3, 2, 41, 32, 3, 23, 10, 4, // x^8640
- 31, 17, 6, 39, 14, 4, 29, 19, 11, 29, 23, 12, 32, 7, 2, 25
- , 20, 7, 25, 20, 6, 39, 20, 2, // x^8704
- 30, 13, 3, 27, 17, 5, 13, 7, 1, 35, 33, 24, 45, 12, 11, 30
- , 29, 11, 27, 9, 4, 27, 10, 8, // x^8768
- 26, 19, 9, 26, 25, 7, 24, 9, 2, 25, 14, 6, 15, 9, 6, 17, 8
- , 6, 19, 14, 6, 15, 9, 6, // x^8832
- 33, 22, 16, 33, 4, 3, 14, 5, 2, 37, 12, 7, 51, 4, 2, 36, 9
- , 6, 43, 13, 9, 41, 10, 6, // x^8896
- 40, 25, 10, 18, 17, 1, 33, 32, 31, 35, 29, 2, 17, 3, 1, 39
- , 34, 1, 27, 14, 2, 12, 7, 5, // x^8960
- 29, 11, 10, 23, 8, 2, 9, 8, 6, 35, 6, 2, 28, 19, 17, 31,
- 17, 7, 23, 21, 8, 32, 29, 11, // x^9024
- 45, 19, 1, 9, 6, 4, 23, 16, 10, 11, 3, 2, 33, 4, 2, 45, 38
- , 6, 17, 10, 7, 33, 31, 1, // x^9088
- 27, 26, 11, 47, 33, 24, 9, 7, 5, 35, 25, 5, 39, 25, 22, 21
- , 14, 1, 35, 25, 4, 33, 29, 7, // x^9152
- 22, 15, 3, 15, 10, 4, 43, 37, 30, 33, 26, 14, 21, 18, 13,
- 31, 24, 2, 35, 10, 9, 21, 14, 8, // x^9216
- 35, 21, 7, 49, 18, 8, 17, 11, 7, 37, 18, 13, 19, 6, 4, 39,
- 17, 14, 13, 4, 3, 23, 7, 2, // x^9280
- 49, 43, 18, 29, 17, 15, 27, 13, 9, 21, 19, 16, 55, 22, 8,
- 21, 14, 8, 17, 5, 3, 51, 44, 5, // x^9344
- 31, 26, 15, 28, 23, 1, 38, 7, 1, 23, 5, 1, 17, 11, 6, 29,
- 24, 11, 18, 13, 1, 28, 15, 6, // x^9408
- 19, 11, 6, 22, 9, 6, 52, 43, 25, 25, 22, 14, 23, 21, 20,
- 35, 19, 5, 37, 18, 13, 45, 40, 15, // x^9472
- 18, 9, 2, 25, 12, 7, 29, 17, 15, 19, 15, 6, 39, 17, 16, 13
- , 5, 2, 37, 33, 22, 31, 26, 6, // x^9536
- 43, 32, 9, 11, 4, 1, 27, 13, 2, 49, 26, 14, 29, 25, 7, 36,
- 29, 27, 15, 8, 1, 19, 6, 4, // x^9600
- 14, 13, 1, 25, 8, 2, 31, 17, 7, 30, 23, 5, 33, 7, 3, 31,
- 24, 21, 19, 16, 2, 35, 21, 1, // x^9664
- 17, 9, 3, 25, 6, 2, 20, 9, 2, 36, 27, 21, 7, 3, 2, 27, 19,
- 17, 37, 4, 2, 30, 5, 2, // x^9728
- 15, 7, 6, 36, 9, 2, 42, 17, 3, 56, 49, 47, 41, 23, 22, 24,
- 19, 1, 38, 37, 9, 27, 26, 21, // x^9792
- 42, 41, 10, 43, 32, 21, 46, 33, 22, 13, 10, 3, 39, 37, 25,
- 49, 47, 13, 25, 23, 10, 36, 15, 1, // x^9856
- 35, 32, 21, 13, 11, 3, 35, 28, 5, 33, 6, 4, 39, 38, 26, 21
- , 10, 2, 42, 35, 15, 49, 18, 14, // x^9920
- 39, 38, 31, 22, 21, 1, 15, 14, 6, 31, 30, 11, 30, 15, 10,
- 36, 3, 2, 21, 19, 5, 27, 10, 7, // x^9984
- 7, 4, 2, 19, 13, 9 // x^10000
- };
-
- public BigInteger PolynomialValue { get; private set; }
-
- public IrreduciblePolynomial(int degreeOfIrreduciblePolynomial)
- {
- if (!IsValidDegree(degreeOfIrreduciblePolynomial))
- {
- throw new ArgumentException();
- }
-
- PolynomialValue = BigInteger.Zero.SetBit(degreeOfIrreduciblePolynomial);
-
- for (int i = 0; i < InnerTermsPerPolynomial; i++)
- {
- PolynomialValue =
- PolynomialValue.SetBit(
- _TermPowers[InnerTermsPerPolynomial * ((degreeOfIrreduciblePolynomial / 8) - 1) + i]);
- }
-
- PolynomialValue = PolynomialValue.SetBit(0);
- Degree = degreeOfIrreduciblePolynomial;
- }
-
- public int Degree { get; private set; }
-
- public int SizeInBytes
- {
- get { return Degree / 8; }
- }
-
- public static IrreduciblePolynomial CreateOfByteSize(int byteSize)
- {
- return new IrreduciblePolynomial(byteSize * 8);
- }
-
- public static int MaxDegree
- {
- get { return (_TermPowers.Length / InnerTermsPerPolynomial) * 8; }
- }
-
- public static bool IsValidDegree(int degree)
- {
- return (8 <= degree) && (degree <= MaxDegree) && ((degree % 8) == 0);
- }
-
- public override string ToString()
- {
- return PolynomialValue.ToPolynomialString();
- }
-
- public override bool Equals(object obj)
- {
- var other = obj as IrreduciblePolynomial;
- if (other == null)
- {
- return base.Equals(obj);
- }
-
- return PolynomialValue.Equals(other.PolynomialValue);
- }
-
- public override int GetHashCode()
- {
- return PolynomialValue.GetHashCode();
- }
- }
-}
diff --git a/Miner/Algebra/LagrangeInterpolator.cs b/Miner/Algebra/LagrangeInterpolator.cs
deleted file mode 100644
index ce3b8659d1..0000000000
--- a/Miner/Algebra/LagrangeInterpolator.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-
-namespace AntShares.Algebra
-{
- ///
- /// Finds the y-intercept of a polynomial in a finite field.
- ///
- public class LagrangeInterpolator
- {
- public static FiniteFieldPolynomial EvaluateAtZero(IEnumerable points)
- {
- var originalPoints = points.ToArray();
-
- if (originalPoints.Length == 0)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- int threshold = originalPoints.Length;
- // We need to "correct" these points by removing the high term monomial
- var adjustedPoints = originalPoints.Select(p => AdjustPoint(threshold, p)).ToArray();
-
- // Use Lagrange interpolating polynomials ( http://en.wikipedia.org/wiki/Lagrange_polynomial )
- // to solve:
-
- // (x-x2)(x-x3)...(x-xn) (x-x1)(x-x3)...(x-xn)
- // P(x) = ------------------------ y1 + -------------------------- y2 + ... +
- // (x1-x2)(x1-x3)...(x1-xn) (x2-x1)(x2-x3)...(x2-xn-1)
-
- // Simplifying things is that x is 0 since we want to find the constant term
-
- var fieldPoly = originalPoints[0].Y;
-
- var total = fieldPoly.Zero;
-
- for (int ixCurrentPoint = 0; ixCurrentPoint < threshold; ixCurrentPoint++)
- {
- var currentNumerator = fieldPoly.One;
- var currentDenominator = fieldPoly.One;
- var currentPoint = adjustedPoints[ixCurrentPoint];
-
- for (int ixOtherPoint = 0; ixOtherPoint < threshold; ixOtherPoint++)
- {
- if (ixCurrentPoint == ixOtherPoint)
- {
- continue;
- }
-
- // numerator needs multiplied by
- // (0-x_i) = -x_i = x_i
- // (since subtraction and addition are the same in GF[2]
- currentNumerator *= adjustedPoints[ixOtherPoint].X;
- currentDenominator *= (currentPoint.X + adjustedPoints[ixOtherPoint].X);
- }
-
- // Dividing is just multiplying by the inverse
- var denominatorInverse = currentDenominator.GetInverse();
-
- var fraction = currentNumerator * denominatorInverse;
-
- // Now, multiply the fraction by the relevant y_i
- var currentTermValue = fraction * currentPoint.Y;
- total += currentTermValue;
- }
-
- return total;
- }
-
- private static FiniteFieldPoint AdjustPoint(int totalPoints, FiniteFieldPoint point)
- {
- var correction = new FiniteFieldPolynomial(point.Y.PrimePolynomial, BigInteger.One);
- var correctionMultiplier = point.X;
-
- for (int i = 1; i <= totalPoints; i++)
- {
- correction = correction * correctionMultiplier;
- }
-
- var newY = point.Y + correction;
- return new FiniteFieldPoint(point.X, newY);
- }
- }
-}
diff --git a/Miner/App.config b/Miner/App.config
deleted file mode 100644
index 2961d5c76b..0000000000
--- a/Miner/App.config
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- .\Chain
-
-
- 10333
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Miner/BigIntegerExtensions.cs b/Miner/BigIntegerExtensions.cs
deleted file mode 100644
index 0e876a8e41..0000000000
--- a/Miner/BigIntegerExtensions.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-
-namespace AntShares
-{
- internal static class BigIntegerExtensions
- {
- public static BigInteger SetBit(this BigInteger n, int bit)
- {
- return n |= BigInteger.One << bit;
- }
-
- public static bool TestBit(this BigInteger n, int bit)
- {
- return (n & (BigInteger.One << bit)) != 0;
- }
-
- public static int GetBitLength(this BigInteger n)
- {
- var remainder = n;
- int bits = 0;
- while (remainder > 0)
- {
- remainder = remainder >> 1;
- bits++;
- }
-
- return bits;
- }
-
- public static string ToPolynomialString(this BigInteger n)
- {
- var sb = new StringBuilder();
- for (int i = n.GetBitLength(); i >= 0; i--)
- {
- if (n.TestBit(i))
- {
- if (sb.Length > 0)
- {
- sb.Append(" + ");
- }
-
- sb.Append((i > 0) ? "x" : "1");
-
- if (i > 1)
- {
- sb.Append("^");
- sb.Append(i);
- }
- }
- }
-
- if (sb.Length == 0)
- {
- sb.Append("0");
- }
-
- return sb.ToString();
- }
-
- public static byte[] ToUnsignedLittleEndianBytes(this BigInteger n)
- {
- var byteArray = n.ToByteArray();
- if ((byteArray.Length > 1) && (byteArray[byteArray.Length - 1] == 0x00))
- {
- var byteArrayMissingEnd = new byte[byteArray.Length - 1];
- Array.Copy(byteArray, byteArrayMissingEnd, byteArrayMissingEnd.Length);
- return byteArrayMissingEnd;
- }
- return byteArray;
- }
-
- public static byte[] ToUnsignedBigEndianBytes(this BigInteger n)
- {
- var bytes = n.ToUnsignedLittleEndianBytes();
- Array.Reverse(bytes);
- return bytes;
- }
-
- public static BigInteger ToBigIntegerFromLittleEndianUnsignedBytes(this byte[] bytes)
- {
- return new BigInteger(bytes.Concat(new byte[1]).ToArray());
- }
-
- public static BigInteger ToBigIntegerFromBigEndianUnsignedBytes(this byte[] bytes)
- {
- byte[] littleEndianBytes = bytes.Reverse().ToArray();
- return littleEndianBytes.ToBigIntegerFromLittleEndianUnsignedBytes();
- }
- }
-}
diff --git a/Miner/Cryptography/Diffuser.cs b/Miner/Cryptography/Diffuser.cs
deleted file mode 100644
index eee7f532fa..0000000000
--- a/Miner/Cryptography/Diffuser.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-using System;
-using System.Numerics;
-
-namespace AntShares.Cryptography
-{
- ///
- /// Diffuses the bits of the number.
- ///
- internal abstract class Diffuser
- {
- public virtual BigInteger Scramble(BigInteger input, int rawByteLength)
- {
- return Scramble(input);
- }
-
- protected virtual BigInteger Scramble(BigInteger input)
- {
- return input;
- }
-
- public virtual BigInteger Unscramble(BigInteger input, int rawByteLength)
- {
- return Unscramble(input);
- }
-
- protected virtual BigInteger Unscramble(BigInteger input)
- {
- return input;
- }
- }
-
- // NOTE: In order to achieve full compatibility with B. Poettering's "ssss-split" and
- // "ssss-combine" programs, I (Jeff) had to look at B. Poettering's source code
- // to see exactly how he diffused data using the XTEA algorithm. I reproduced the
- // effective results using my own code below, but still had to look at his code.
- // I asked for explicit permission from the author (B. Poettering) to release
- // my derived code under the MIT license (instead of GPL) and was generously
- // granted permission by him. For more license details, see License.txt included
- // with this code.
- internal class XteaDiffuser : Diffuser
- {
- private const int InnerRounds = 32;
- private const int OuterRounds = 40;
- private const UInt32 Delta = 0x9E3779B9;
- private const UInt32 DecodeInitialSum = unchecked(InnerRounds * Delta);
-
- protected override BigInteger Scramble(BigInteger input)
- {
- int actualByteSize;
- byte[] integerBytes = GetBigIntegerBytesWithLeastSignificantWordFirstUsing16BitMsbFirstWords(input,
- out actualByteSize);
-
- for (int i = 0; i < (OuterRounds * actualByteSize); i += 2)
- {
- EncodeSlice(integerBytes, i, actualByteSize, EncipherBlock);
- }
-
- return GetBigIntegerFromLeastSignificantWordsFirstWith16BitMsbFirstWords(integerBytes, actualByteSize);
- }
-
- protected override BigInteger Unscramble(BigInteger input)
- {
- int actualByteSize;
- byte[] integerBytes = GetBigIntegerBytesWithLeastSignificantWordFirstUsing16BitMsbFirstWords(input,
- out actualByteSize);
-
- for (int i = (OuterRounds * actualByteSize) - 2; i >= 0; i -= 2)
- {
- EncodeSlice(integerBytes, i, actualByteSize, DecipherBlock);
- }
-
- return GetBigIntegerFromLeastSignificantWordsFirstWith16BitMsbFirstWords(integerBytes, actualByteSize);
- }
-
- // The whole point of the diffuser is to diffuse bits, that's why we'll pick least significant words
- // with most significant word bits. This alone does some diffusion.
- private static byte[] GetBigIntegerBytesWithLeastSignificantWordFirstUsing16BitMsbFirstWords(BigInteger input,
- out int actualBytesWithoutPadding)
- {
- byte[] bigEndianBytes = input.ToUnsignedBigEndianBytes();
- actualBytesWithoutPadding = bigEndianBytes.Length;
- bool isOddNumberOfBytes = bigEndianBytes.Length % 2 != 0;
- if (isOddNumberOfBytes)
- {
- // make sure it's even
- byte[] newBigEndianBytes = new byte[bigEndianBytes.Length + 1];
-
- // Since it's big endian, we need to shift it right by a byte and fill MSB with zeroes.
- Array.Copy(bigEndianBytes, 0, newBigEndianBytes, 1, bigEndianBytes.Length);
- bigEndianBytes = newBigEndianBytes;
- }
-
- byte[] result = new byte[bigEndianBytes.Length];
-
- int ixResultByte = 0;
-
- for (int ixWord = bigEndianBytes.Length - 2; ixWord >= 0; ixWord -= 2)
- {
- for (int wordByteOffset = 0; wordByteOffset < 2; wordByteOffset++)
- {
- // need to flip individual bytes
- result[ixResultByte++] = bigEndianBytes[ixWord + wordByteOffset];
- }
- }
-
- bool hasExtraPaddingByte = bigEndianBytes.Length != actualBytesWithoutPadding;
-
- if (hasExtraPaddingByte)
- {
- result[bigEndianBytes.Length - 2] = result[bigEndianBytes.Length - 1];
- }
-
- return result;
- }
-
- private static BigInteger GetBigIntegerFromLeastSignificantWordsFirstWith16BitMsbFirstWords(byte[] wordBytes,
- int actualBytes)
- {
- bool hasBytePadding = actualBytes % 2 == 1;
- if (hasBytePadding)
- {
- wordBytes[wordBytes.Length - 1] = wordBytes[wordBytes.Length - 2];
- wordBytes[wordBytes.Length - 2] = 0;
- }
-
- byte[] bigEndianBytes = new byte[wordBytes.Length];
-
- int ixResult = 0;
-
- for (int ixWord = wordBytes.Length - 2; ixWord >= 0; ixWord -= 2)
- {
- for (int ixByteInWord = 0; ixByteInWord < 2; ixByteInWord++)
- {
- bigEndianBytes[ixResult++] = wordBytes[ixWord + ixByteInWord];
- }
- }
-
- var result = bigEndianBytes.ToBigIntegerFromBigEndianUnsignedBytes();
- return result;
- }
-
- private static void EncipherBlock(UInt32[] v)
- {
- UInt32 sum = 0;
-
- for (int i = 0; i < InnerRounds; i++)
- {
- v[0] += (((v[1] << 4) ^ (v[1] >> 5)) + v[1]) ^ sum;
- sum += Delta;
- v[1] += (((v[0] << 4) ^ (v[0] >> 5)) + v[0]) ^ sum;
- }
- }
-
- private static void DecipherBlock(UInt32[] v)
- {
- UInt32 sum = DecodeInitialSum;
-
- for (int i = 0; i < InnerRounds; i++)
- {
- v[1] -= (((v[0] << 4) ^ (v[0] >> 5)) + v[0]) ^ sum;
- sum -= Delta;
- v[0] -= (((v[1] << 4) ^ (v[1] >> 5)) + v[1]) ^ sum;
- }
- }
-
- private static void EncodeSlice(byte[] data, int idx, int len, Action processBlock)
- {
- UInt32[] v = new UInt32[2];
- const int wordsPerBlock = 2;
-
- // Pack
- for (int i = 0; i < wordsPerBlock; i++)
- {
- v[i] = ((UInt32)data[(idx + (4 * i)) % len]) << 24 |
- ((UInt32)data[(idx + (4 * i) + 1) % len]) << 16 |
- ((UInt32)data[(idx + (4 * i) + 2) % len]) << 8 |
- ((UInt32)data[(idx + (4 * i) + 3) % len]);
- }
-
- // Process
- processBlock(v);
-
- // Unpack
- for (int i = 0; i < wordsPerBlock; i++)
- {
- data[(idx + (4 * i) + 0) % len] = (byte)(v[i] >> 24);
- data[(idx + (4 * i) + 1) % len] = (byte)((v[i] >> 16) & 0xff);
- data[(idx + (4 * i) + 2) % len] = (byte)((v[i] >> 8) & 0xff);
- data[(idx + (4 * i) + 3) % len] = (byte)(v[i] & 0xff);
- }
- }
- }
-
- // Mimics ssss-split by only diffusing if 64 bits or larger
- internal class SsssDiffuser : Diffuser
- {
- private static readonly XteaDiffuser _XteaDiffuser = new XteaDiffuser();
- private const int _ByteCutoff = 64 / 8;
-
- public override BigInteger Scramble(BigInteger input, int rawByteLength)
- {
- if (rawByteLength < _ByteCutoff)
- {
- return input;
- }
-
- return _XteaDiffuser.Scramble(input, rawByteLength);
- }
-
- public override BigInteger Unscramble(BigInteger input, int rawByteLength)
- {
- if (rawByteLength < _ByteCutoff)
- {
- return input;
- }
-
- return _XteaDiffuser.Unscramble(input, rawByteLength);
- }
- }
-}
diff --git a/Miner/Cryptography/SecretSharing.cs b/Miner/Cryptography/SecretSharing.cs
deleted file mode 100644
index 77562be3ef..0000000000
--- a/Miner/Cryptography/SecretSharing.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using AntShares.Algebra;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography;
-
-namespace AntShares.Cryptography
-{
- public static class SecretSharing
- {
- private static readonly Diffuser DefaultDiffuser = new SsssDiffuser();
-
- public static byte[] Combine(IEnumerable points)
- {
- var allShares = points.ToArray();
-
- if (allShares.Length == 0)
- {
- throw new ArgumentException("You must provide at least one secret share (piece).", nameof(points));
- }
-
- var secretCoefficient = LagrangeInterpolator.EvaluateAtZero(allShares);
- var scrambledValue = secretCoefficient.PolynomialValue;
- var unscrambledValue = DefaultDiffuser.Unscramble(scrambledValue, scrambledValue.ToByteArray().Length);
- return unscrambledValue.ToUnsignedBigEndianBytes();
- }
-
- public static SplitSecret Split(byte[] secret, int threshold)
- {
- var irreduciblePolynomial = IrreduciblePolynomial.CreateOfByteSize(secret.Length);
- var rawSecret = secret.ToBigIntegerFromBigEndianUnsignedBytes();
- var diffusedSecret = DefaultDiffuser.Scramble(rawSecret, secret.Length);
- var secretCoefficient = new FiniteFieldPolynomial(irreduciblePolynomial, diffusedSecret);
-
- var allCoefficients = new[] { secretCoefficient }
- .Concat(
- GetRandomPolynomials(
- irreduciblePolynomial,
- threshold - 1)
- )
- .ToArray();
-
- return new SplitSecret(threshold, irreduciblePolynomial, allCoefficients);
- }
-
- private static IEnumerable GetRandomPolynomials(IrreduciblePolynomial irreduciblePolynomial, int total)
- {
- var rng = RandomNumberGenerator.Create();
-
- for (int i = 0; i < total; i++)
- {
- var randomCoefficientBytes = new byte[irreduciblePolynomial.SizeInBytes];
- rng.GetBytes(randomCoefficientBytes);
- yield return new FiniteFieldPolynomial(irreduciblePolynomial, randomCoefficientBytes.ToBigIntegerFromLittleEndianUnsignedBytes());
- }
- }
- }
-}
diff --git a/Miner/Cryptography/SplitSecret.cs b/Miner/Cryptography/SplitSecret.cs
deleted file mode 100644
index 00a1481b7d..0000000000
--- a/Miner/Cryptography/SplitSecret.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using AntShares.Algebra;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-
-namespace AntShares.Cryptography
-{
- public class SplitSecret
- {
- private readonly IrreduciblePolynomial _IrreduciblePolynomial;
- private readonly FiniteFieldPolynomial[] _AllCoefficients;
-
- public int Threshold { get; private set; }
-
- public SplitSecret(int threshold, IrreduciblePolynomial irreduciblePolynomial, FiniteFieldPolynomial[] allCoefficients)
- {
- Threshold = threshold;
- _IrreduciblePolynomial = irreduciblePolynomial;
- _AllCoefficients = allCoefficients;
- }
-
- public FiniteFieldPoint GetShare(int n)
- {
- var xPoly = new FiniteFieldPolynomial(_IrreduciblePolynomial, new BigInteger(n));
- var y = FiniteFieldPolynomial.EvaluateAt(n, _AllCoefficients);
- return new FiniteFieldPoint(xPoly, y);
- }
-
- public IEnumerable GetShares(int totalShares)
- {
- return Enumerable.Range(1, totalShares).Select(GetShare);
- }
- }
-}
diff --git a/Miner/Miner.csproj b/Miner/Miner.csproj
deleted file mode 100644
index 4338ed7e92..0000000000
--- a/Miner/Miner.csproj
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {58870D2E-9DAE-41EF-9766-17C39238ED0F}
- Exe
- Properties
- AntShares
- Miner
- v4.6.1
- 512
- true
-
-
-
- AntShares.Program
-
-
- true
- bin\Debug\
- TRACE;DEBUG
- full
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
-
-
- bin\Release\
- true
- AnyCPU
- false
- prompt
- MinimumRecommendedRules.ruleset
- false
-
-
-
-
-
-
-
-
-
-
- Network\RPC\RpcException.cs
-
-
- Network\RPC\RpcServer.cs
-
-
- Services\ConsoleServiceBase.cs
-
-
- Services\ServiceProxy.cs
- Component
-
-
- Shell\MainService.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Settings.settings
-
-
-
-
-
- Designer
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
-
-
- {bcd6b896-6cd0-4601-aa13-5672a15e0cad}
- AntSharesCore
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Miner/Program.cs b/Miner/Program.cs
deleted file mode 100644
index 74bcb9ccb8..0000000000
--- a/Miner/Program.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using AntShares.Miner;
-using System;
-using System.IO;
-
-namespace AntShares
-{
- static class Program
- {
- private static readonly object LogSync = new object();
-
- private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
-#if DEBUG
- Exception ex = (Exception)e.ExceptionObject;
- using (FileStream fs = new FileStream("error.log", FileMode.Create, FileAccess.Write, FileShare.None))
- using (StreamWriter w = new StreamWriter(fs))
- {
- w.WriteLine(ex.GetType());
- w.WriteLine(ex.Message);
- w.WriteLine(ex.StackTrace);
- AggregateException ex2 = ex as AggregateException;
- if (ex2 != null)
- {
- foreach (Exception inner in ex2.InnerExceptions)
- {
- w.WriteLine();
- w.WriteLine(inner.Message);
- w.WriteLine(inner.StackTrace);
- }
- }
- }
-#endif
- }
-
- internal static void Log(string message)
- {
- DateTime now = DateTime.Now;
- string line = $"[{now.TimeOfDay:hh\\:mm\\:ss}] {message}";
- Console.WriteLine(line);
- lock (LogSync)
- {
- string path = Path.Combine(AppContext.BaseDirectory, "Logs");
- Directory.CreateDirectory(path);
- path = Path.Combine(path, $"{now:yyyy-MM-dd}.log");
- File.AppendAllLines(path, new[] { line });
- }
- }
-
- static void Main(string[] args)
- {
- AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
- new MinerService().Run(args);
- }
- }
-}
diff --git a/Miner/Properties/AssemblyInfo.cs b/Miner/Properties/AssemblyInfo.cs
deleted file mode 100644
index 81d223f5de..0000000000
--- a/Miner/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// 有关程序集的常规信息通过以下
-// 特性集控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("AntShares")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AntShares")]
-[assembly: AssemblyCopyright("© AntShares Project 2015 Released under the MIT license")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 使此程序集中的类型
-// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
-// 则将该类型上的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("c0331ede-270e-484b-9c21-3f853cf99bb3")]
-
-// 程序集的版本信息由下面四个值组成:
-//
-// 主版本
-// 次版本
-// 生成号
-// 修订号
-//
-// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”:
-[assembly: AssemblyVersion("1.0.*")]
-//[assembly: AssemblyVersion("1.0.0.0")]
-//[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Miner/Properties/Settings.Designer.cs b/Miner/Properties/Settings.Designer.cs
deleted file mode 100644
index 274e126535..0000000000
--- a/Miner/Properties/Settings.Designer.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace AntShares.Properties {
-
-
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
- private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default {
- get {
- return defaultInstance;
- }
- }
-
- [global::System.Configuration.ApplicationScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute(".\\Chain")]
- public string DataDirectoryPath {
- get {
- return ((string)(this["DataDirectoryPath"]));
- }
- }
-
- [global::System.Configuration.ApplicationScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("10333")]
- public ushort NodePort {
- get {
- return ((ushort)(this["NodePort"]));
- }
- }
- }
-}
diff --git a/Miner/Properties/Settings.settings b/Miner/Properties/Settings.settings
deleted file mode 100644
index 3e1b3fec4b..0000000000
--- a/Miner/Properties/Settings.settings
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
- .\Chain
-
-
- 10333
-
-
-
\ No newline at end of file