public Task Sync() { return(Task.Run(async() => { Log += "syncing..." + Environment.NewLine; OnLogChanged(); while (true) { var(index, node) = Nodes.Aggregate((index: BlockChain.Last().Index, node: (Uri)null), (m, n) => Task.Run(async() => { HttpResponseMessage response; try { response = await httpClient_.PostAsync(n, new StringContent(JsonConvert.SerializeObject( new GetCurrentIndex { PortNumber = PortNumber }))); } catch (HttpRequestException) { return m; } if (!response.IsSuccessStatusCode) { return m; } var res = JsonConvert.DeserializeObject <GetCurrentIndexResponse>(await response.Content.ReadAsStringAsync()); if (res.CurrentIndex <= m.index) { return m; } return (index: res.CurrentIndex, node: n); }).Result); if (node == null) { break; } if (index > BlockChain.Last().Index) { IList <Block> branch; var currentIndex = BlockChain.Last().Index; { HttpResponseMessage response; try { response = await httpClient_.PostAsync(node, new StringContent(JsonConvert.SerializeObject( new GetBlocks { Index = currentIndex + 1, NumBlocks = index - currentIndex }))); } catch (HttpRequestException) { continue; } if (!response.IsSuccessStatusCode) { continue; } var res = JsonConvert.DeserializeObject <GetBlocksResponse>(await response.Content.ReadAsStringAsync()); branch = res.Blocks; } if (branch.First().PreviousHash == LastHash) { var removed = false; foreach (var block in branch) { foreach (var transaction in block.Transactions) { if (TransactionPool.Contains(transaction)) { TransactionPool.Remove(transaction); removed = true; } } } if (removed) { OnTransactionPoolChanged(); } BlockChain.AddRange(branch); break; } while (true) { HttpResponseMessage response; try { response = await httpClient_.PostAsync(node, new StringContent(JsonConvert.SerializeObject( new GetBlocks { Index = currentIndex, NumBlocks = 1 }))); } catch (HttpRequestException) { goto con; } if (!response.IsSuccessStatusCode) { goto con; } var res = JsonConvert.DeserializeObject <GetBlocksResponse>(await response.Content.ReadAsStringAsync()); branch.Insert(0, res.Blocks.First()); if (BlockChain[currentIndex].PreviousHash == branch.First().PreviousHash) { break; } --currentIndex; } BlockChain.RemoveRange(currentIndex, BlockChain.Count - currentIndex); var removed2 = false; foreach (var block in branch) { foreach (var transaction in block.Transactions) { if (TransactionPool.Contains(transaction)) { TransactionPool.Remove(transaction); removed2 = true; } } } if (removed2) { OnTransactionPoolChanged(); } BlockChain.AddRange(branch); break; } con:; } LastHash = SerializeHash(GetHash(BlockChain.Last())); OnBlockChainChanged(); Log += "sync completed." + Environment.NewLine; OnLogChanged(); })); }