private void Send_Message(pbft_message Message) { //send the message for all connected client foreach (IPAddress item in Configs.members) { if (!item.Equals(Configs.My_address)) { client.connect(item, 5000, Message); } } }
private bool Verify_Message(pbft_message Message) { bool Signature_Match = false; var data = Encoding.UTF8.GetBytes(Message.ToString()); using (ECDsa Ecc = ECDsa.Create()) { int bytes2; Ecc.ImportSubjectPublicKeyInfo(Message.id, out bytes2); Signature_Match = Ecc.VerifyData(data, Message.digest, HashAlgorithmName.SHA256); } return(Signature_Match); }
public void Add_To_Temp_View(pbft_message Message) { if (!Temporary_View_Change_messages.ContainsKey(Message.view_number)) { Temp_view_Message temp = new Temp_view_Message() { message = Message.message, id = Message.id, seq = Message.seq, view_number = Message.view_number, }; temp.New_Primary_Event += New_Primary; Temporary_View_Change_messages.Add(Message.view_number, temp); } //verify if this has trigered a new primary call already or not Temporary_View_Change_messages[Message.view_number].View_Counter++; }
public void Add_To_Temp(Func <bool> predicate, pbft_message Message, Tuple <int, int> Message_Tuple) { if (!predicate()) { Temp_Message temp = new Temp_Message() { commit_counter = 0, Prepare_counter = 0, message = Message.message, id = Message.id, seq = Message.seq, view_number = Message.view_number, }; Temporary_Messages.Add(Message_Tuple, temp); System.Console.WriteLine("Message with sequence number" + Message.seq + " and viewnumber " + Message.view_number + " added to the temporary pool"); } }
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); }