/* * Algo for synchronising chain with peers most popular chain * References: https://www.dotnetperls.com/common-elements-list */ private void SynchroniseChain() { Dictionary <string, int> hashCount = new Dictionary <string, int>(); RemoteInterface ri = null; foreach (ClientDataStruct c in clientList) { //Console.WriteLine(c.ip + " " + c.port); ri = ConnectToRemote(DecodeFrom64(c.ip), DecodeFrom64(c.port)); string daHash = ri.GetLatestBlock().Hash; if (hashCount.TryGetValue(daHash, out int count)) { hashCount[daHash] = count + 1; } else //if hash not found yet add it to hashCount { if (!daHash.Equals(ourBlockchain.First().Hash)) { hashCount.Add(daHash, 1); } } } //if our latest block hash is not the same as most popular then download the most popular chain if (hashCount.Count > 0) { string maxHash = hashCount.OrderBy(x => x.Value).Last().Key;//find hash with highest population count APIClass.Block currBlock = ourRemoteThread.GetLatestBlock(); List <APIClass.Block> popularChain = null; bool found = false; //if latest block doesn't have the most popular hash and current block prev hash does not match popular hash then download popular chain if (!currBlock.Hash.Equals(maxHash) && !currBlock.PrevHash.Equals(maxHash)) { foreach (ClientDataStruct c in clientList) { ri = ConnectToRemote(DecodeFrom64(c.ip), DecodeFrom64(c.port)); popularChain = ri.GetCurrentChain(); if (ri.GetLatestBlock().Hash.Equals(maxHash)) { found = true; break; } } if (found) { ourRemoteThread.SetChain(popularChain); ourBlockchain = ourRemoteThread.GetCurrentChain(); } } } }
/* * creating blocks */ private void DoMining(MinerUtils minUtils) { string recvTransaction = ourRemoteThread.ReceiveTransaction(null); if (!string.IsNullOrEmpty(recvTransaction)) { //insert transaction details APIClass.Block newBlock = new APIClass.Block(); newBlock.ID = ourBlockchain.Last().ID + 1; newBlock.JsonStrList = DoPython(recvTransaction); newBlock.Hash = ""; newBlock.PrevHash = ourRemoteThread.GetLatestBlock().Hash; newBlock = minUtils.GenerateHash(newBlock); //create valid hash and add it to new block ourRemoteThread.AddBlock(newBlock); ourBlockchain = ourRemoteThread.GetCurrentChain(); } }