public void AddInitTransactions() { state.OutputLog.Add($"{DateTime.Now} - Adding mined transactions.."); if (!state.Balances.ContainsKey(state.Username)) { state.Balances.Add(state.Username, 0); } int maxTxNumber = state.Transactions.Count == 0 ? 1 : state.Transactions.Last().Number + 1; for (int i = 0; i < 10; i++) { System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); Transaction transaction = new Transaction(maxTxNumber, "00", state.Username, (int)(DateTime.UtcNow - dtDateTime).TotalSeconds); state.Transactions.Add(transaction); state.Balances[state.Username] += 1; maxTxNumber++; foreach (var node in seedNodes) { byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.NEW_TRANS, new string[] { transaction.Number.ToString(), transaction.From, transaction.To, transaction.Timestamp.ToString() }); NodeBroadcasting.BroadcastToSeedNode(message, node); } } state.OutputLog.Add($"{DateTime.Now} - Mined transactions added."); }
public static State PerformSyncing(State state, UdpClient udpServer, int sourcePort, List <NodeDetails> seedNodes) { state.OutputLog.Add($"{DateTime.Now} - Syncing.."); int highestTransaction = 1; NodeDetails highestTransactionNode = null; string[] messageParams = new string[] { }; byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.HIGHEST_TRN, messageParams); foreach (var node in seedNodes) { NodeBroadcasting.BroadcastToSeedNode(message, node); var command = SyncingOperations.ReceiveMessage(state, udpServer, node, BlockchainCommands.HIGHEST_TRN_RES, sourcePort); if (command.CommandType != BlockchainCommands.NO_RESPONSE) { var highestTransactionResultCommand = (HighestTransactionResultCommand)command; if (highestTransaction < highestTransactionResultCommand.TransactionNumber) { state.OutputLog.Add($"{DateTime.Now} - Highest Transaction Updated."); highestTransaction = highestTransactionResultCommand.TransactionNumber; highestTransactionNode = node; } } } int currentTxNumber = state.Transactions.Count == 0 ? 1 : state.Transactions.Max(p => p.Number); if (currentTxNumber < highestTransaction) { UpdateState(udpServer, state, highestTransactionNode, sourcePort, highestTransaction, currentTxNumber); state.Transactions.OrderBy(p => p.Number); } state.OutputLog.Add($"{DateTime.Now} - Syncing Finished."); return(state); }
public static State ProcessNewTransactionReceived(State state, Command command, NodeDetails node) { var newTransactionCommand = (NewTransactionCommand)command; var existingTransaction = state.Transactions.FirstOrDefault(p => p.Number == newTransactionCommand.TransactionNumber); if (existingTransaction == null) { state.Transactions.Add(new Transaction(newTransactionCommand.TransactionNumber, newTransactionCommand.FromUser, newTransactionCommand.ToUser, newTransactionCommand.Timestamp)); } else { int index = state.Transactions.FindIndex(p => p.Number == newTransactionCommand.TransactionNumber); if (existingTransaction.Timestamp > newTransactionCommand.Timestamp) { //Replace transaction state.Balances[state.Transactions[index].To] -= 1; state.Transactions[index] = new Transaction(newTransactionCommand.TransactionNumber, newTransactionCommand.FromUser, newTransactionCommand.ToUser, newTransactionCommand.Timestamp); if (!state.Balances.ContainsKey(newTransactionCommand.ToUser)) { state.Balances.Add(newTransactionCommand.ToUser, 0); } state.Balances[newTransactionCommand.ToUser] += 1; } } NodeBroadcasting.SendOkMessage(node); return(state); }
public static void ProcessHighestTransactionRequest(State state, Command command, NodeDetails node) { int transactionNumber = state.Transactions.Count == 0 ? 0 : state.Transactions.Max(p => p.Number); byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.HIGHEST_TRN_RES, new string[] { transactionNumber.ToString() }); NodeBroadcasting.BroadcastToSeedNode(message, node); }
public static void ProcessGetTransactionRequest(State state, Command command, NodeDetails node) { var getTransactionCommand = (GetTransactionCommand)command; var transaction = state.Transactions.FirstOrDefault(p => p.Number == getTransactionCommand.TransactionNumber); if (transaction == null) { NodeBroadcasting.SendNotOkMessage(node); } else { byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.NEW_TRANS, new string[] { transaction.Number.ToString(), transaction.From, transaction.To, transaction.Timestamp.ToString() }); NodeBroadcasting.BroadcastToSeedNode(message, node); } }
private Transaction AddNewTransaction(string to) { int transactionNumber = state.Transactions.Max(p => p.Number) + 1; if (!state.Balances.ContainsKey(to)) { Console.WriteLine($"User {to} does not exist."); return(null); } else if (state.Balances[state.Username] == 0) { Console.WriteLine($"Not enough balance for user {state.Username}."); return(null); } while (!state.NodeState.Equals(NodeState.AVAILABLE)) { } state.NodeState = NodeState.SENDING; Transaction transaction = new Transaction(transactionNumber, state.Username, to, (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds); state.Transactions.Add(transaction); state.Balances[state.Username] -= 1; if (!state.Balances.ContainsKey(to)) { state.Balances.Add(to, 0); } state.Balances[to] += 1; foreach (var node in seedNodes) { byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.NEW_TRANS, new string[] { transaction.Number.ToString(), transaction.From, transaction.To, transaction.Timestamp.ToString() }); NodeBroadcasting.BroadcastToSeedNode(message, node); } state.NodeState = NodeState.AVAILABLE; return(transaction); }
private static State UpdateState(UdpClient udpServer, State state, NodeDetails node, int sourcePort, int highestTransaction, int currentTransaction) { for (int i = currentTransaction; i <= highestTransaction; i++) { state.OutputLog.Add($"{DateTime.Now} - Getting Transaction {i}.."); byte[] message = MessageProcessor.ProcessMessage(BlockchainCommands.GET_TRANS, new string[] { i.ToString() }); int retry = 0; var command = new NewTransactionCommand(); while (retry < 5) { NodeBroadcasting.BroadcastToSeedNode(message, node); var newCommand = ReceiveNewTransaction(udpServer, node, i, sourcePort); if (newCommand.CommandType.Equals(BlockchainCommands.NEW_TRANS)) { command = (NewTransactionCommand)newCommand; break; } retry++; } if (retry >= 5) { state.OutputLog.Add($"{DateTime.Now} - Failed to get transaction {i}"); return(state); } state.Transactions.Add(new Transaction(command.TransactionNumber, command.FromUser, command.ToUser, command.Timestamp)); if (!state.Balances.ContainsKey(command.ToUser)) { state.Balances.Add(command.ToUser, 0); } state.Balances[command.ToUser] += 1; if (state.Balances.ContainsKey(command.FromUser)) { state.Balances[command.FromUser] -= 1; } } return(state); }