private pbft_message Create_Block() { /*the client should send a message from the network and the On_Message_Received will be excuted this must be changed * THE primary should contact the client and request for a message and then fom that message create a new block*/ Console.WriteLine("waiting for the clinet to send A message"); System.Console.WriteLine(); string Block = Console.ReadLine(); /* create a new block and this should be in a function with */ PBFT_Messages.pbft_message new_block = new PBFT_Messages.pbft_message() { message = Block, id = configs.PublicKey, message_Type = Message_Type.preprepare, seq = state.Confirmed_messages.Count + 1, view_number = state.view_number, }; Temp_Message temp = new Temp_Message() { commit_counter = 0, Prepare_counter = 0, message = new_block.message, id = new_block.id, seq = new_block.seq, view_number = new_block.view_number, }; Temporary_Messages.Add(Tuple.Create(new_block.seq, new_block.view_number), temp); return(new_block); }
public pbft_message Sign_Message(PBFT_Messages.pbft_message message) { byte[] data = Encoding.UTF8.GetBytes(message.ToString()); byte[] digest = configs.Ecc.SignData(data, 0, data.Length, HashAlgorithmName.SHA256); message.digest = digest; return(message); }
public void On_Message_Received(object source, string message, IPAddress ip) { lock (_locker) { PBFT_Messages.pbft_message Message = Newtonsoft.Json.JsonConvert.DeserializeObject <PBFT_Messages.pbft_message>(message); System.Console.WriteLine("received a " + Message.message_Type + " message from node :" + ip + "\n message content is : " + Message.message + "with seq number : " + Message.seq); // verify the validity of the message and proceed Process_Message(Message, ip); } }
public bool Process_Message(PBFT_Messages.pbft_message Message, IPAddress Sender_Ip) { if (Verify_Message(Message)) { Tuple <int, int> Message_Tuple = Tuple.Create(Message.seq, Message.view_number); switch (Message.message_Type) { case Message_Type.preprepare: //verify if the preprepare message came from the primary //send a prepare block to everyone System.Console.WriteLine("primary is at index " + state.Primary_Index); if (Configs.members[state.Primary_Index].Equals(Sender_Ip)) { // add the received message to the temporary pool if it doesn't exist Add_To_Temp(() => Temporary_Messages.ContainsKey(Message_Tuple), Message, Message_Tuple); timeout.Idle_Timeout.Close(); var prepare = new pbft_message() { message = Message.message, id = configs.PublicKey, message_Type = Message_Type.prepare, seq = Message.seq, view_number = state.view_number, }; state.phase = Phase.prepare; Temporary_Messages[Message_Tuple].Prepare_counter++; Send_Message(Sign_Message(prepare)); Console.WriteLine(Message.message_Type + " message from node " + Sender_Ip + " processed succesfully "); return(true); } else { System.Console.WriteLine(Message.message_Type + " message rejected from node " + Sender_Ip); return(false); } case Message_Type.prepare: //check if there is 2f+1 prepare messages in the pool and store the prepare message //check if it is the same message of that in the transaction pool //if true create a commit block if not increment the counter Add_To_Temp(() => Temporary_Messages.ContainsKey(Message_Tuple), Message, Message_Tuple); //this verification is useless and must be changed if (Temporary_Messages[Message_Tuple].message == Message.message) { Temporary_Messages[Message_Tuple].Prepare_counter++; System.Console.WriteLine("prepare counter of message with seq:" + Message.seq + " is : " + Temporary_Messages[Message_Tuple].Prepare_counter); } if (Temporary_Messages[Message_Tuple].Prepare_counter == 2) { System.Console.WriteLine("Received 2f+1 prepare message "); state.phase = Phase.commit; timeout.Commit_Timeout.Start(); //send a commit block var commit = new pbft_message() { message = Message.message, id = configs.PublicKey, message_Type = Message_Type.commit, seq = Message.seq, view_number = state.view_number, }; ; Send_Message(Sign_Message(commit)); } break; case Message_Type.commit: Add_To_Temp(() => Temporary_Messages.ContainsKey(Message_Tuple), Message, Message_Tuple); timeout.Set_Commit_Timeout(); if (Temporary_Messages[Message_Tuple].message == Message.message) { Temporary_Messages[Message_Tuple].commit_counter++; } // check if there is 2f+1 commit meessage in the pool and store if (Temporary_Messages[Message_Tuple].commit_counter == 3) { //store the Message and send a validation to the client ,for now just simulate it timeout.Commit_Timeout.Stop(); // this should be in a new view in the case of pbft timeout.Set_Idle_Timeout(); state.Confirmed_messages.Add(Message.message); Console.WriteLine("message added to the blockchain" + Message.message); System.Console.WriteLine(); //if primary create another block if (state.Is_Primary) { state.phase = Phase.Preprepare; System.Console.WriteLine("seq num : " + state.Seq); Create_Block_Task = Task.Run(() => Send_Message(Sign_Message(Create_Block()))); } Console.WriteLine(Message.message_Type + " message from node " + Sender_Ip + " processed succesfully "); return(true); } break; case Message_Type.view_change: if (Message.view_number >= state.view_number) { Add_To_Temp_View(Message); } else { return(false); } break; } Console.WriteLine(Message.message_Type + " message from node processed succesfully "); return(true); } System.Console.WriteLine("message rejected"); return(false); }