private void RegisterLoginForm_Shown(object sender, EventArgs e) { Task.Run(() => CommonHelpers.GetTime()); Task.Run(() => { try { if (!System.IO.File.Exists("Community.CsharpSqlite.dll") || !System.IO.File.Exists("Community.CsharpSqlite.SQLiteClient.dll") || !System.IO.File.Exists("NetworkCommsDotNetComplete.dll") || !System.IO.File.Exists("Virgil.Crypto.dll") || !System.IO.File.Exists("MaterialSkin.dll")) { throw new Exception(); } CryptoHelper.GenerateKeyPair(); } catch { this.Invoke(new Action(() => { MessageBox.Show(Properties.Resources.libsError, "", MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); } )); } }); }
private void CheckDeleteOldPendingItems(object sender, ElapsedEventArgs e) { var pendingBlocksCopy = new Dictionary <Block, DateTime>(pendingBlocks); foreach (var item in pendingBlocksCopy) { //если ожидающий блок старее 10 минут - проверяем, затем удаляем его if ((CommonHelpers.GetTime() - item.Value) > TimeSpan.FromMilliseconds(CommonHelpers.PeersCheckInterval * 10)) { CheckBlock(GetLastBlockFromPending(item.Key)); pendingBlocks.Remove(item.Key); //отмечаем ожидающие транзакции из базы как свободные db.MarkAsFreePendingTransactions(false, item.Key.Transactions); } } var pendingTransactionsCopy = new Dictionary <Transaction, DateTime>(pendingTransactions); foreach (var item in pendingTransactionsCopy) { //если ожидающая транзакция старее 10 минут - проверяем, затем удаляем ее if ((CommonHelpers.GetTime() - item.Value) > TimeSpan.FromMilliseconds(CommonHelpers.PeersCheckInterval * 10)) { CheckTransaction(item.Key); pendingTransactions.Remove(item.Key); } } }
public static Transaction VoteTransaction(string candidateHash, string votingHash, int votingNumber) { var tr = new Transaction(); tr.Type = TransactionType.Vote; tr.Date0 = CommonHelpers.GetTime(); tr.SenderHash = VotingsUser.PublicKey; tr.RecieverHash = candidateHash; tr.VotingNumber = votingNumber; tr.PreviousHash = votingHash; tr.Hash = tr.CalcHash(); tr.Signature = tr.CalcSignature(); return(tr); }
public static Transaction BanUserTransaction(string cause, string publicHash, string previousHash) { var tr = new Transaction(); tr.Type = TransactionType.BanUser; tr.Date0 = CommonHelpers.GetTime(); tr.SenderHash = VotingsUser.PublicKey; tr.RecieverHash = publicHash; tr.PreviousHash = previousHash; JObject info = new JObject(); info["cause"] = cause; tr.Info = info.ToString(); tr.Hash = tr.CalcHash(); tr.Signature = tr.CalcSignature(); return(tr); }
public Block(List <Transaction> transactions, Block previousBlock) { Date0 = CommonHelpers.GetTime(); PreviousHash = previousBlock.Hash; Number = previousBlock.Number + 1; CreatorHash = VotingsUser.PublicKey; List <string> transactionsHashes = new List <string>(); foreach (var tr in transactions) { transactionsHashes.Add(tr.Hash); } Transactions = transactionsHashes; Hash = CalcHash(); Signature = CalcSignature(); }
public static Transaction StartVotingTransation(List <string> candidatesHashes, string nameOfVoting, int votingNumber, string previousVotingHash) { var tr = new Transaction(); tr.Type = TransactionType.StartVoting; tr.Date0 = CommonHelpers.GetTime(); tr.SenderHash = VotingsUser.PublicKey; tr.VotingNumber = votingNumber; JObject info = new JObject(); JArray candidates = new JArray(candidatesHashes.ToArray()); info["candidates"] = candidates; info["name"] = nameOfVoting; tr.Info = info.ToString(); tr.PreviousHash = previousVotingHash; tr.Hash = tr.CalcHash(); tr.Signature = tr.CalcSignature(); return(tr); }
bool CheckStartVotingTransaction(Transaction transaction) { //проверка хеша и подписи if (!(transaction.CheckHash() && transaction.CheckSignature())) { return(false); } var prevVoting = db.GetTransaction(transaction.PreviousHash); //проверка номера голосования if (transaction.VotingNumber != (prevVoting.VotingNumber + 1)) { return(false); } //проверка даты транзакции if (!(transaction.Date0 >= prevVoting.Date0 && transaction.Date0 <= CommonHelpers.GetTime())) { return(false); } //проверка, что транзакцию создал корневой клиент if (transaction.SenderHash != VotingsUser.RootPublicKey) { return(false); } var existsVoting = db.GetVoting(transaction.VotingNumber); //проверка существования копий транзакции if (existsVoting != null) { //если копия уже в блоке то выход if (existsVoting.Status == TransactionStatus.InBlock) { return(false); } //если копия транзакции старее и при этом свободна, то выход else if (existsVoting.Date0 <= transaction.Date0 && existsVoting.Status == TransactionStatus.Free) { return(false); } //иначе удаляем существующую транзакцию из базы else { db.DeleteTransaction(existsVoting); NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount())); } } try { var info = JObject.Parse(transaction.Info); if (!(info["name"].Value <string>() != "")) { return(false); } if (info["candidates"].Count() == 0) { return(false); } foreach (JToken item in info["candidates"]) { if (item.Value <string>() == "") { return(false); } } } catch { return(false); } return(true); }
bool CheckBanUserTransaction(Transaction transaction) { //проверка хеша и подписи if (!(transaction.CheckHash() && transaction.CheckSignature())) { return(false); } //проверка даты транзакции if (!(transaction.Date0 >= VotingsUser.RootUserDate && transaction.Date0 <= CommonHelpers.GetTime())) { return(false); } //проверка, что транзакцию создал корневой клиент if (transaction.SenderHash != VotingsUser.RootPublicKey) { return(false); } var recieverCreation = db.GetUserCreation(transaction.RecieverHash); //проверка на существование пользователя на заданную дату if (recieverCreation.Date0 > transaction.Date0) { return(false); } var prevTransaction = db.GetTransaction(transaction.PreviousHash); //предыдущая транзакция и транзакция создания пользователя - одно и то же if (prevTransaction.Hash != recieverCreation.Hash) { return(false); } //проверка чтобы предыдущая транзакция не была новее if (transaction.Date0 < prevTransaction.Date0) { return(false); } var existsBan = db.GetUserBan(transaction.RecieverHash); //проверка существования копий транзакции if (existsBan != null) { //если копия уже в блоке то выход if (existsBan.Status == TransactionStatus.InBlock) { return(false); } //если копия транзакции старее и при этом свободна, то выход else if (existsBan.Date0 <= transaction.Date0 && existsBan.Status == TransactionStatus.Free) { return(false); } //иначе удаляем существующую транзакцию из базы else { db.DeleteTransaction(existsBan); NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount())); } } try { var info = JObject.Parse(transaction.Info); if (!(info["cause"].Value <string>() != "")) { return(false); } } catch { return(false); } return(true); }
bool CheckVoteTransaction(Transaction transaction) { var voting = db.GetTransaction(transaction.PreviousHash); //проверка хеша и подписи if (!(transaction.CheckHash() && transaction.CheckSignature())) { return(false); } //проверка даты транзакции if (!(transaction.Date0 >= voting.Date0 && transaction.Date0 <= CommonHelpers.GetTime())) { return(false); } var senderCreation = db.GetUserCreation(transaction.SenderHash); var senderBan = db.GetUserBan(transaction.SenderHash); ////проверка создателя транзакции //if (senderCreation == null) return false; //проверка даты создателя транзакции if (!(senderCreation.Date0 <= voting.Date0 && (senderBan == null || senderBan.Date0 > voting.Date0))) { return(false); } var recieverCreation = db.GetUserCreation(transaction.RecieverHash); var recieverBan = db.GetUserBan(transaction.RecieverHash); ////проверка получателя транзакции //if (recieverCreation == null) return false; //проверка даты получателя транзакции if (!(recieverCreation.Date0 <= voting.Date0 && (recieverBan == null || recieverBan.Date0 > voting.Date0))) { return(false); } var existsVote = db.GetUserVote(transaction.SenderHash, transaction.VotingNumber); //проверка существования копий транзакции if (existsVote != null) { //если копия уже в блоке то выход if (existsVote.Status == TransactionStatus.InBlock) { return(false); } //если копия транзакции старее и при этом свободна, то выход else if (existsVote.Date0 <= transaction.Date0 && existsVote.Status == TransactionStatus.Free) { return(false); } //иначе удаляем существующую транзакцию из базы else { db.DeleteTransaction(existsVote); NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount())); } } return(true); }
private bool CheckTransaction(Transaction transaction, EndPoint peerAddress = null) { if (db.GetTransaction(transaction.Hash) != null) { return(false); } bool needWait = false; //проверка существования транзакции создания пользователя //если ее нет, то транзакция создания и бана пользователя запрашиваются if (db.GetUserCreation(transaction.SenderHash) == null) { //если ее нет и в ожидающих - запрашиваем от пиров if (!pendingTransactions.Keys.Any(tr => tr.RecieverHash == transaction.PreviousHash)) { RequestTransaction(transaction.SenderHash, peerAddress); } needWait = true; } //проверяем получателя транзакции только для транзакций бана и посылки голоса if ((transaction.Type == TransactionType.BanUser || transaction.Type == TransactionType.Vote) && (db.GetUserCreation(transaction.RecieverHash) == null)) { if (!pendingTransactions.Keys.Any(tr => tr.RecieverHash == transaction.RecieverHash)) { RequestTransaction(transaction.RecieverHash, peerAddress); } needWait = true; } //проверка существования предыдущей транзакции if (db.GetTransaction(transaction.PreviousHash) == null) { if (!pendingTransactions.Keys.Any(tr => tr.Hash == transaction.PreviousHash)) { RequestTransaction(transaction.PreviousHash, peerAddress); } needWait = true; } //если транзакция не в списке ожидающих и запросили инфу, то отправляем ее в список ожидающих if (needWait == true) { if (!pendingTransactions.ContainsKey(transaction)) { pendingTransactions.Add(transaction, CommonHelpers.GetTime()); } return(false); } ////проверка транзакции //удаляем из ожидающих pendingTransactions.Remove(transaction); var checkPassed = true; switch (transaction.Type) { case TransactionType.CreateUser: checkPassed = CheckCreateUserTransaction(transaction); break; case TransactionType.BanUser: checkPassed = CheckBanUserTransaction(transaction); break; case TransactionType.Vote: checkPassed = CheckVoteTransaction(transaction); break; case TransactionType.StartVoting: checkPassed = CheckStartVotingTransaction(transaction); break; default: checkPassed = false; break; } ////если транзакция проверена успешно if (checkPassed) { //добавляем транзакцию в базу db.PutTransaction(transaction); NetworkComms.Logger.Warn("Added transaction " + transaction.Type.ToString() + " " + transaction.Hash); NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount())); //если добавили новую транзакцию голосования, то вызываем событие if (transaction.Type == TransactionType.StartVoting) { NewVoting?.Invoke(this, new IntEventArgs(transaction.VotingNumber)); } else if (transaction.Type == TransactionType.CreateUser) { NewUser?.Invoke(this, new IntEventArgs(db.UsersCount())); } //проверяем нужно ли создавать новый блок MakeBlock(); //ищем в ожидающих транзакции связанные с этой и проверяем их var pending = pendingTransactions.Keys.Where(tr => { return(tr.PreviousHash == transaction.Hash || tr.SenderHash == transaction.RecieverHash || tr.RecieverHash == transaction.RecieverHash); }).ToList(); foreach (var item in pending) { CheckTransaction(item); } //ищем в ожидающих блоках связанные с этим и проверяем их var pending2 = pendingBlocks.Keys.Where(bl => { return(bl.TransactionsBlob.Contains(transaction.Hash) || bl.CreatorHash == transaction.RecieverHash); }).ToList(); foreach (var item in pending2) { CheckBlock(item); } return(true); } else { return(false); } }
private bool CheckBlock(Block block, EndPoint peerAddress = null) { if (db.GetBlock(block.Hash) != null) { return(false); } var prevBlock = db.GetBlock(block.PreviousHash); var creator = db.GetUserCreation(block.CreatorHash); bool needWait = false; //проверка существования предыдущего блока if (prevBlock == null) { //если ее нет и в ожидающих - запрашиваем от пиров if (!pendingBlocks.Keys.Any(bl => bl.Hash == block.PreviousHash)) { RequestBlock(block.PreviousHash, peerAddress); } needWait = true; } //проверка существования создателя блока if (creator == null) { if (!pendingTransactions.Keys.Any(tr => tr.RecieverHash == block.CreatorHash)) { RequestTransaction(block.CreatorHash, peerAddress); } needWait = true; } if (block.Transactions == null) { return(false); } //проверка существования транзакций foreach (var itemHash in block.Transactions) { if (db.GetTransaction(itemHash) == null) { if (!pendingTransactions.Keys.Any(tr => tr.Hash == itemHash)) { RequestTransaction(itemHash, peerAddress); } needWait = true; } } //если блок не в списке ожидающих и запросили инфу, то отправляем ее в список ожидающих if (needWait == true) { if (!pendingBlocks.ContainsKey(block)) { pendingBlocks.Add(block, CommonHelpers.GetTime()); } return(false); } ////если все данные есть, начинаем проверку блока //удаляем его из ожидающих pendingBlocks.Remove(block); //проверка хеша и подписи if (!(block.CheckHash() && block.CheckSignature())) { return(false); } //проверка даты if (!(block.Date0 >= prevBlock.Date0 && block.Date0 <= CommonHelpers.GetTime())) { return(false); } //проверка создателя блока //var senderCreation = db.GetUserCreation(block.CreatorHash); var senderBan = db.GetUserBan(block.CreatorHash); if (!(creator.Date0 <= block.Date0 && (senderBan == null || senderBan.Date0 > block.Date0))) { return(false); } //сравнение длины цепочки этого блока с длиной цепочки в базе var blockCopyInDB = db.GetBlock(block.Number); if (blockCopyInDB != null) { var lastBlockInChain = GetLastBlockFromPending(block); var lastBlockInDB = db.GetLastBlock(); //если цепочка нового блока длиннее или цепочки равны, но дата нового блока раньше if ((lastBlockInChain.Number > lastBlockInDB.Number) || (lastBlockInChain.Number == lastBlockInDB.Number && block.Date0 < blockCopyInDB.Date0)) { //удаляем из базы все блоки начиная с этого for (int i = blockCopyInDB.Number; i <= lastBlockInDB.Number; i++) { var blockToRemove = db.GetBlock(i); db.DeleteBlock(blockToRemove); //СПОРНЫЙ МОМЕНТ //отмечаем транзакции из блока как свободные db.MarkAsFreePendingTransactions(true, blockToRemove.Transactions); } //добавляем блок обратно в ожидающие pendingBlocks.Add(block, CommonHelpers.GetTime()); //запускаем проверку последнего ожидающего блока из цепочки (он снова загрузит нужные транзакции) CheckBlock(lastBlockInChain); } else { //СПОРНЫЙ МОМЕНТ //если не приняли новый блок, то освобождаем полученные для него транзакции db.MarkAsFreePendingTransactions(false, block.Transactions); } NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount())); NewBlock?.Invoke(this, new IntEventArgs(db.BlocksCount())); return(false); } //проверка транзакций foreach (var itemHash in block.Transactions) { var tr = db.GetTransaction(itemHash); if (tr.Status == TransactionStatus.InBlock || tr.Date0 > block.Date0) { return(false); } } ////если все хорошо, добавляем блок в базу db.PutBlock(block); NetworkComms.Logger.Warn("Added block " + block.Hash); NewBlock?.Invoke(this, new IntEventArgs(db.BlocksCount())); //помечаем транзакции, что они в блоке foreach (var itemHash in block.Transactions) { var tr = db.GetTransaction(itemHash); db.MarkTransaction(tr, TransactionStatus.InBlock); } //ищем в ожидающих блоках связанные с этим и проверяем их var pending = pendingBlocks.Keys.Where(bl => bl.PreviousHash == block.Hash).ToList(); foreach (var item in pending) { CheckBlock(item); } return(true); }