|
| 1 | +------------------------ MODULE ByzantineGenerals --------------------------- |
| 2 | +CONSTANTS Generals |
| 3 | + |
| 4 | +VARIABLES network, confirmations |
| 5 | + |
| 6 | +Vars ≜ ⟨network, connection⟩ |
| 7 | + |
| 8 | +CommandMessageType ≜ "Command" |
| 9 | +CommandMessage ≜ [ |
| 10 | + type : {CommandMessageType}, |
| 11 | + sender : Node |
| 12 | +] |
| 13 | + |
| 14 | +ConfirmMessageType ≜ "Confirm" |
| 15 | +ConfirmMessage ≜ [ |
| 16 | + type : {ConfirmMessageType}, |
| 17 | + sender : Node |
| 18 | +] |
| 19 | + |
| 20 | +MessageType ≜ {CommandMessageType, ConfirmMessageType} |
| 21 | +Message ≜ CommandMessage ∪ ConfirmMessage |
| 22 | + |
| 23 | +INSTANCE Network WITH Ordered ← FALSE, Duplicates ← TRUE, Loss ← TRUE |
| 24 | + |
| 25 | +TypeOK ≜ |
| 26 | + ∧ network ∈ [Node → PendingMessage] |
| 27 | + ∧ connection ∈ [Node → SUBSET Node] |
| 28 | + |
| 29 | +Termination ≜ ∀ src, dst ∈ Node : dst ∈ connection[src] |
| 30 | + |
| 31 | +Liveness ≜ □◇Termination |
| 32 | + |
| 33 | +SendSynMessage(src, dst) ≜ |
| 34 | + ∧ dst ∉ connection[src] |
| 35 | + ∧ ∃ success ∈ BOOLEAN : |
| 36 | + network' = [ |
| 37 | + network EXCEPT |
| 38 | + ![dst] = SendMessage(@, src, success, [ |
| 39 | + type ↦ SynMessageType, |
| 40 | + sender ↦ src |
| 41 | + ]) |
| 42 | + ] |
| 43 | + ∧ UNCHANGED connection |
| 44 | + |
| 45 | +ProcessSynMessage(recipient, sender, msg, success) ≜ |
| 46 | + ∧ msg.type = SynMessageType |
| 47 | + ∧ ∃ duplicate ∈ BOOLEAN : |
| 48 | + network' = [ |
| 49 | + network EXCEPT |
| 50 | + ![recipient] = ReceiveMessage(@, sender, duplicate, msg), |
| 51 | + ![sender] = SendMessage(@, recipient, success, [ |
| 52 | + type ↦ AckMessageType, |
| 53 | + sender ↦ recipient |
| 54 | + ]) |
| 55 | + ] |
| 56 | + ∧ UNCHANGED connection |
| 57 | + |
| 58 | +ProcessAckMessage(recipient, sender, msg) ≜ |
| 59 | + ∧ msg.type = AckMessageType |
| 60 | + ∧ ∃ duplicate ∈ BOOLEAN : |
| 61 | + network' = [ |
| 62 | + network EXCEPT |
| 63 | + ![recipient] = ReceiveMessage(@, sender, duplicate, msg) |
| 64 | + ] |
| 65 | + ∧ connection' = [connection EXCEPT ![recipient] = @ ∪ {sender}] |
| 66 | + |
| 67 | +ProcessMessage(recipient, sender, message_type, success) ≜ |
| 68 | + ∃ msg ∈ PeekMessage(network[recipient]) : |
| 69 | + ∧ msg.type = message_type |
| 70 | + ∧ msg.sender = sender |
| 71 | + ∧ ∨ ProcessSynMessage(recipient, sender, msg, success) |
| 72 | + ∨ ProcessAckMessage(recipient, sender, msg) |
| 73 | + |
| 74 | +Terminate ≜ |
| 75 | + ∧ Termination |
| 76 | + ∧ UNCHANGED ⟨network, connection⟩ |
| 77 | + |
| 78 | +Init ≜ |
| 79 | + ∧ network = [n ∈ Node ↦ NoPendingMessages] |
| 80 | + ∧ connection = [n ∈ Node ↦ {}] |
| 81 | + |
| 82 | +Next ≜ |
| 83 | + ∨ ∃ src, dst ∈ Node : SendSynMessage(src, dst) |
| 84 | + ∨ ∃ recipient, sender ∈ Node : |
| 85 | + ∃ message_type ∈ MessageType : |
| 86 | + ∃ success ∈ BOOLEAN : |
| 87 | + ProcessMessage(recipient, sender, message_type, success) |
| 88 | + ∨ Terminate |
| 89 | + |
| 90 | +Fairness ≜ |
| 91 | + ∧ ∀ src, dst ∈ Node : WF_Vars(SendSynMessage(src, dst)) |
| 92 | + ∧ ∀ recipient, sender ∈ Node : |
| 93 | + SF_Vars(ProcessMessage(recipient, sender, SynMessageType, TRUE)) |
| 94 | + ∧ ∀ recipient, sender ∈ Node : |
| 95 | + ∀ success ∈ BOOLEAN : |
| 96 | + WF_Vars(ProcessMessage(recipient, sender, AckMessageType, success)) |
| 97 | + |
| 98 | +Spec ≜ |
| 99 | + ∧ Init |
| 100 | + ∧ □[Next]_Vars |
| 101 | + ∧ Fairness |
| 102 | + |
| 103 | +============================================================================= |
| 104 | + |
0 commit comments