250 lines
7.8 KiB
C#
250 lines
7.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Navigation;
|
|
using System.Windows.Shapes;
|
|
using System.Threading;
|
|
using System.Windows.Threading;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections;
|
|
using System.Data;
|
|
using System.Net.Sockets;
|
|
using System.Net;
|
|
using System.Windows.Media.Media3D;
|
|
using System.Text.Json;
|
|
using System.Security.Claims;
|
|
|
|
namespace WpfBlockChanApp
|
|
{
|
|
public partial class MainWindow : Window
|
|
{
|
|
|
|
DispatcherTimer timer1s;
|
|
DispatcherTimer timer1m;
|
|
|
|
ObservableCollection<Block> observableBlockChain = new ObservableCollection<Block>();
|
|
ObservableCollection<int> observableString = new ObservableCollection<int>();
|
|
//static List<string> strings = new List<string>();
|
|
static List<int> clients = new List<int>();
|
|
|
|
const string STD_IP = "127.0.0.1";
|
|
static string data;
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
this.DataContext = this;
|
|
ChainView.ItemsSource = observableBlockChain;
|
|
LogView.ItemsSource = observableString;
|
|
|
|
timer1s = new DispatcherTimer();
|
|
timer1s.Interval = TimeSpan.FromSeconds(1);
|
|
timer1s.Tick += UpdateData;
|
|
timer1s.Start();
|
|
|
|
timer1m = new DispatcherTimer();
|
|
timer1m.Interval = TimeSpan.FromSeconds(30);
|
|
timer1m.Tick += Timer1m_Tick;
|
|
timer1m.Start();
|
|
|
|
|
|
|
|
tcpListener = new TcpListener(IPAddress.Parse(STD_IP), 0);
|
|
tcpListener.Start();
|
|
data = ((IPEndPoint)tcpListener.LocalEndpoint).Port.ToString();
|
|
MyPort.Content = data;
|
|
|
|
Blockchain.Chain = new List<Block>();
|
|
Blockchain.Compute = true;
|
|
Block tmpBlock = new Block(0, "", "", 0, 0);
|
|
tmpBlock.Hash = "";
|
|
Blockchain.Chain.Add(tmpBlock);
|
|
|
|
stopNetwork = false;
|
|
listenThread = new Thread(() => listenerThredFunction());
|
|
listenThread.Start();
|
|
}
|
|
|
|
private void Timer1m_Tick(object? sender, EventArgs e)
|
|
{
|
|
UpdateClients();
|
|
}
|
|
void UpdateData(object? sender, EventArgs e)
|
|
{
|
|
for (int i = observableBlockChain.Count; i < Blockchain.Chain.Count; i++)
|
|
observableBlockChain.Add(Blockchain.Chain[i]);
|
|
|
|
for (int i = observableString.Count; i < clients.Count; i++)
|
|
observableString.Add(clients[i]);
|
|
}
|
|
|
|
|
|
|
|
Thread calcualteBlockThread;
|
|
static bool stopNetwork = false;
|
|
static bool stopMiner = false;
|
|
static void ComputeBlockThreadFunction()
|
|
{
|
|
while (true)
|
|
{
|
|
if (stopMiner) break;
|
|
Blockchain.Compute = true;
|
|
ReturnOption option = Blockchain.ComputeBlock(data);
|
|
|
|
if (!option.isValid) { continue; }
|
|
|
|
if (Blockchain.AddBlock(option.value))
|
|
{
|
|
UpdateClients(option.value);
|
|
//UpdateClients();
|
|
}
|
|
}
|
|
}
|
|
|
|
static TcpListener tcpListener;
|
|
Thread listenThread;
|
|
|
|
static void listenerThredFunction()
|
|
{
|
|
while (true)
|
|
{
|
|
if (stopNetwork) break;
|
|
listen();
|
|
}
|
|
}
|
|
static void listen()
|
|
{
|
|
try
|
|
{
|
|
using TcpClient tcpClient = tcpListener.AcceptTcpClient();
|
|
using NetworkStream networkStream = tcpClient.GetStream();
|
|
|
|
byte[] buffer = new byte[4];
|
|
int readByts = networkStream.Read(buffer, 0, buffer.Length);
|
|
if (readByts <= 0) return;
|
|
int sizeOfStruct = BitConverter.ToInt32(buffer);
|
|
|
|
byte[] isListBuffer = new byte[1];
|
|
readByts = networkStream.Read(isListBuffer, 0, isListBuffer.Length);
|
|
if(readByts <= 0) return;
|
|
bool isList = BitConverter.ToBoolean(isListBuffer);
|
|
|
|
byte[] data = new byte[sizeOfStruct];
|
|
int messageSize = networkStream.Read(data, 0, data.Length);
|
|
if (messageSize <= 0) return;
|
|
|
|
string messageString = Encoding.UTF8.GetString(data, 0, messageSize);
|
|
|
|
if (isList)
|
|
{
|
|
List<Block> chain = JsonSerializer.Deserialize<List<Block>>(messageString);
|
|
if (!Blockchain.IsValid(chain)) return;
|
|
bool update = Blockchain.Evaluete(chain, Blockchain.Chain);
|
|
if (update)
|
|
{
|
|
Blockchain.Chain = chain;
|
|
Blockchain.Compute = false;
|
|
UpdateClients();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Block block = JsonSerializer.Deserialize<Block>(messageString);
|
|
if (Blockchain.AddBlock(block))
|
|
{
|
|
Blockchain.Compute = false;
|
|
UpdateClients(block);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
static void UpdateClients()
|
|
{
|
|
string chainString = JsonSerializer.Serialize(Blockchain.Chain);
|
|
|
|
foreach (var clien in clients)
|
|
{
|
|
UpdateClient(clien, chainString, true);
|
|
}
|
|
}
|
|
|
|
static void UpdateClients(Block block)
|
|
{
|
|
string blockString = JsonSerializer.Serialize(block);
|
|
|
|
foreach (var clien in clients)
|
|
{
|
|
UpdateClient(clien, blockString, false);
|
|
}
|
|
}
|
|
|
|
static void UpdateClient(int port, string data, bool isListBool)
|
|
{
|
|
try
|
|
{
|
|
using TcpClient tcpClient = new TcpClient();
|
|
tcpClient.Connect(IPAddress.Parse(STD_IP), port);
|
|
using NetworkStream networkStream = tcpClient.GetStream();
|
|
|
|
|
|
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
|
|
byte[] isList = BitConverter.GetBytes(isListBool);
|
|
byte[] size = BitConverter.GetBytes(dataBytes.Length);
|
|
|
|
networkStream.Write(size, 0, size.Length);
|
|
networkStream.Write(isList, 0, isList.Length);
|
|
networkStream.Write(dataBytes, 0, dataBytes.Length);
|
|
|
|
|
|
}catch(Exception e)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
}
|
|
private void Start_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Blockchain.Compute = true;
|
|
stopMiner = false;
|
|
calcualteBlockThread = new Thread(() => ComputeBlockThreadFunction());
|
|
calcualteBlockThread.Start();
|
|
}
|
|
private void Stop_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
|
|
Blockchain.Compute = false;
|
|
stopMiner = true;
|
|
}
|
|
private void Connect_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
int i = 0;
|
|
if(int.TryParse(ConnectBox.Text, out i))
|
|
{
|
|
clients.Add(i);
|
|
ConnectBox.Text = "";
|
|
}
|
|
}
|
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
stopNetwork = true;
|
|
stopMiner = true;
|
|
tcpListener.Stop();
|
|
Blockchain.Compute = false;
|
|
}
|
|
}
|
|
}
|