コード例 #1
0
ファイル: Node.cs プロジェクト: migiright/Matcha
 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();
     }));
 }