Esempio n. 1
0
        public static async Task Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("User Mode");
                CreateHostBuilder(args).Build().Run();
            }
            else
            {
                if (args.Length >= 1)
                {
                    Port = int.Parse(args[0]);
                }

                if (Port > 0)
                {
                    // inject DbContext and HashProvider to Program.cs
                    var services = new ServiceCollection();

                    services.AddTransient <IHashProvider, HashProvider>();
                    services.AddTransient <IBlockchainProvider, BlockchainProvider>();
                    services.AddDbContext <ApplicationDbContext>(options =>
                                                                 options.UseSqlServer("Server=localhost; Database=BlockchainCharity; Trusted_Connection=True; MultipleActiveResultSets=True;")
                                                                 , ServiceLifetime.Transient);

                    var serviceProvider = services.BuildServiceProvider();
                    _dbContext  = serviceProvider.GetService <ApplicationDbContext>();
                    _hash       = serviceProvider.GetService <IHashProvider>();
                    _blockchain = serviceProvider.GetService <IBlockchainProvider>();

                    Client = new Client(_blockchain, _hash);
                    Server = new Server();
                    Server.Start();

                    // construct signalr connection
                    SignalRConnection = new HubConnectionBuilder()
                                        .WithUrl(new Uri("https://127.0.0.1:5001/donateHub"), options =>
                    {
                        //bypass SSL on SignalR Client
                        var handler = new HttpClientHandler
                        {
                            ClientCertificateOptions = ClientCertificateOption.Manual,
                            ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
                        };
                        options.HttpMessageHandlerFactory = _ => handler;
                        options.WebSocketConfiguration    = sockets =>
                        {
                            sockets.RemoteCertificateValidationCallback = (sender, certificate, chain, policyErrors) => true;
                        };
                    })
                                        .Build();


                    // subscribe on method SendTransaction
                    SignalRConnection.On <Transaction>("SendTransaction", async transaction =>
                    {
                        await Validate(transaction);
                        // await ChangeLeader();
                        Client.Broadcast($"Decrease Cooldown");
                        Client.InvokeVote();
                        await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate");
                    });

                    await SignalRConnection.StartAsync();
                }

                await LoadChain();

                Console.WriteLine("=========================");
                Console.WriteLine("1. Connect to a node");
                Console.WriteLine("2. Be A Leader");
                Console.WriteLine("3. Sync Number of Node");
                Console.WriteLine("4. Vote for New Leader");
                Console.WriteLine("5. Get All nodes that this node connects to");
                Console.WriteLine("6. Get Current Leader");
                Console.WriteLine("7. Get Cooldown");
                Console.WriteLine("8. Search Transaction");
                Console.WriteLine("9. Edit Transaction (For malicious node)");
                Console.WriteLine("10. Get Chains");
                Console.WriteLine("999. Exit");
                Console.WriteLine("=========================");

                int selection = 0;
                while (selection != 999)
                {
                    switch (selection)
                    {
                    case 1:
                        Console.WriteLine("Please enter the port");
                        string port = Console.ReadLine();
                        Client.Connect($"{SocketUrl}{port}/Blockchain");
                        break;

                    case 2:
                        if (IsChainValid)
                        {
                            await Coup();
                        }
                        else
                        {
                            Console.WriteLine("The chain is invalid....");
                        }
                        break;

                    case 3:
                        NumNode = Client.GetServers().Count + 1;
                        Console.WriteLine("Current Nodes are : " + NumNode);
                        Client.Broadcast($"NumNode : {NumNode}");
                        DoneConnecting = true;
                        break;

                    case 4:
                        Client.Broadcast($"Decrease Cooldown");
                        Client.InvokeVote();
                        await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate");

                        break;

                    case 5:
                        Console.WriteLine(JsonConvert.SerializeObject(Client.GetServers(), Formatting.Indented));
                        break;

                    case 6:
                        Console.WriteLine($"CurrentLeader : {CurrentLeader}");
                        break;

                    case 7:
                        Console.WriteLine($"CoolDown : {CoolDown}");
                        Console.WriteLine($"Penalty : {Penalty()}");
                        Console.WriteLine($"NumNode : {NumNode}");
                        break;

                    case 8:
                        Console.WriteLine("Please enter the transactionId");
                        string transactionId       = Console.ReadLine();
                        var    searchedTransaction = _dbContext.Transactions
                                                     .FirstOrDefault(x => x.HashedTransactionId == transactionId);

                        if (searchedTransaction == null)
                        {
                            Console.WriteLine("Transaction not found!");
                        }
                        else
                        {
                            Console.WriteLine(JsonConvert.SerializeObject(searchedTransaction));
                        }
                        break;

                    case 9:
                        Console.WriteLine("Please enter the transactionId");
                        string editedTransactionId = Console.ReadLine();
                        var    transaction         = _dbContext.Transactions
                                                     .AsNoTracking()
                                                     .FirstOrDefault(x => x.HashedTransactionId == editedTransactionId);

                        if (transaction == null)
                        {
                            Console.WriteLine("Transaction not found!");
                        }
                        else
                        {
                            var allTransactions = _dbContext.Transactions
                                                  .Where(x => x.BlockHeight == transaction.BlockHeight)
                                                  .AsNoTracking()
                                                  .ToList();

                            transaction.Amount = 5000;
                            transaction.HashedTransactionId = _hash.HashTransaction(transaction);

                            foreach (var item in allTransactions)
                            {
                                if (item.id == transaction.id)
                                {
                                    item.HashedTransactionId = transaction.HashedTransactionId;
                                    item.Amount = transaction.Amount;
                                }
                            }

                            if (Program.Port == 2222)
                            {
                                var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight);
                                var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId));
                                block.HashedTransactionIds = hashedTransactions;
                                block.Hash = _hash.HashBlock(block);
                            }
                            else if (Program.Port == 2223)
                            {
                                var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight);
                                var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId));
                                block.HashedTransactionIds = hashedTransactions;
                                block.Hash = _hash.HashBlock(block);
                            }
                            else
                            {
                                var block = _dbContext.Blockchains1.FirstOrDefault(x => x.Height == transaction.BlockHeight);
                                var hashedTransactions = String.Join('-', allTransactions.Select(x => x.HashedTransactionId));
                                block.HashedTransactionIds = hashedTransactions;
                                block.Hash = _hash.HashBlock(block);
                            }

                            await _dbContext.SaveChangesAsync();

                            Console.WriteLine("Done Changing Transaction.....");
                        }
                        break;

                    case 10:
                        Console.WriteLine(JsonConvert.SerializeObject(Chain, Formatting.Indented));
                        break;
                    }
                    Console.WriteLine("Please select an action");
                    string action = Console.ReadLine();
                    await LoadChain();

                    selection = int.Parse(action);

                    // if (DoneConnecting)
                    // {
                    // await Task.Delay(5000);
                    if (IsDonatable)
                    {
                        await DonateToFoundationIfAble();
                    }
                    //     Console.WriteLine("FCK ASYNC");
                    // }
                }

                Client.Close();
                await SignalRConnection.InvokeAsync("RemoveFromGroup", "Donate");
            }
            // CreateHostBuilder(args).Build().Run();
        }