In this section we give examples of verification that have been carried out on the implementation. Please use the menu on the right to view the relevant sections.
Overview and Status
In addition to the model source code, you will find a collection of Verification Goals (VGs). VGs are statements in IML expressing properties of the FIX engine model that we wish to verify. It’s important to note that IML is used for both building the model and describing the properties we wish to verify about it.
Consider the following quote from Volume 2 of the FIX 4.4 specification:
When either end of a FIX connection has not sent any data for [HeartBtInt] seconds, it will transmit a Heartbeat message.
One way to formalise that statement is to create two VGs:
VG.1.1 - any outbound message will result in an updated fe_last_time_data_sent field
VG.1.2 - any time update will result in check whether Heartbeat should be sent out
It’s important to note that the ‘translation’ of the English-prose statements into IML (or other mathematically precise formal languages) may not be unique. The inherent ambiguity of natural languages is a major reason why the efforts of formalising protocol specifications must be collaborative and industry-wide.
Notice how this approach differs from traditional ‘testing’. In the statement above, we’re making a high-level claim about the model behaviour, and we can subject this claim to analysis over the entire system state-space. When Imandra analyses the model with respect to such a statement, it works to symbolically verify that the claim holds in all possible scenarios. When such a claim does not hold, Imandra works to construct a precise sequence of events (a “counterexample”) which exhibits a violation of the property.
VG Status
For updates, see the Announcements page.
Status as of May 21st, 2017:
Base
[x] VG.1 :: When in ActiveSession (normal mode) and receiving a non garbled and non session-level rejected message and the application is down. Such message would be sent back with a Business Reject.
[x] VG.2 :: FIX session should be terminated if the incoming sequence number is less than expected and the PossDupFlag is not set.
[x] VG.3 :: Messages that are garbled will be ignored (sequence counter will not be incremented).
[x] VG.4 :: Session rejected messages are rejected with the right reason and counter is incremented
Heartbeat Messages
[x] VG.1 :: “When either end of a FIX connection has not sent any data for [HeartBtInt] seconds, it will transmit a Heartbeat message.”
[x] VG.2 :: Non-garbled message updates the clock.
[x] VG.3 :: “When either end of the connection has not received any data for (HeartBtInt + “some reasonable transmission time”) seconds, it will transmit a Test Request message.”
[x] VG.4 :: “If there is still no Heartbeat message received after (HeartBtInt + ‘some reasonable transmission time’) seconds then the connection should be considered lost and corrective action be initiated.”
Logon Messages
[x] VG.1 :: “The logon message must be the first message sent by the application requesting to initiate a FIX session.”
[x] VG.2 :: *“The session acceptor must be prepared to immediately begin processing messages after receipt of the Logon.”
[x] VG.3 :: “After authentication, the initiator and acceptor must synchronize their messages through interrogation of the MsgSeqNum field before sending any queued or new messages.”
[x] VG.4 :: “If the session acceptor has chosen to change the session encryption key, the session initiator must send a third Logon back to the other side in order to acknowledge the key change request.”
[x] VG.5 :: NextExpectedMsgSeqNum is used correctly.
Logoff Messages
[ ] VG.1 :: * “Disconnection without the exchange of logout messages should be interpreted as an abnormal condition.”*
[ ] VG.2 :: “Before actually closing the session, the logout initiator should wait for the opposite side to respond with a confirming logout message.”
[ ] VG.3 :: “After sending the Logout message, the logout initiator should not send any messages unless requested to do so by the logout acceptor via a ResendRequest.”
Sequence Reset Messages
[x] VG.1 :: “When the incoming sequence number does not match the expected corrective processing is required. Note that the SeqReset-Reset message (used only to recover from a disaster vs. normal resend request processing) is an exception to this rule as it should be processed without regards to its MsgSeqNum.”
[ ] VG.2 :: “The Sequence Reset can only increase the sequence number. If a sequence reset is received attempting to decrease the next expected sequence number the message should be rejected and treated as a serious error.”
Sequence Number Logic
[x] VG.1 :: “Must always be the first message transmitted. Authenticate and accept the connection. After sending a Logon confirmation back, send a ResendRequest if a message gap was detected in the Logon sequence number.”
[x] VG.2 :: Out of sequence message would result in state transitioning into Recovery mode.
[ ] VG.3 :: “Ignore the incoming sequence number. The NewSeqNo field of the SeqReset message will contain the sequence number of the next message to be transmitted.”
[ ] VG.4 :: Application messages that result in a gap, we’ll transition into gap fill state.
Rejection Logic
[x] VG.1 :: * “During the gap fill process, certain administrative messages should not be retransmitted. Instead, a special SeqReset-GapFill message is generated.”*
Heartbeat Messages
This section contains verification goals for Hearbeat messages.
Heartbeat VG.1
“When either end of a FIX connection has not sent any data for [HeartBtInt] seconds, it will transmit a Heartbeat message.”
Notes: we transform this statement into 2 VGs:
VG.1.1 - any outbound message will result in an updated fe_last_time_data_sent field
VG.1.2 - any time update will result in check whether Heartbeat should be sent out
Heartbeat VG.2
Notes: there’s no mention of what constitutes a successful data - i.e. is it a non-garbled (but still rejected message)? We interpret this here as that a Non-garbled message results in update of data received.
Also, it’s important to note that we would not process an incoming message if the engine is in a Retransmit or CacheReplay mode, hence we use let incoming_processed = engine.incoming_fix_msg <> engine'.incoming_fix_msg
Heartbeat VG.3
‘When either end of the connection has not received any data for (HeartBtInt + “some reasonable transmission time”) seconds, it will transmit a Test Request message.’
Notes: ‘reasonable time’ is represented by a ‘duration’ type field fe_testreq_interval.
Heartbeat VG.4
“If there is still no Heartbeat message received after (HeartBtInt + “some reasonable transmission time”) seconds then the connection should be considered lost and corrective action be initiated.”
Notes: note sure what ‘corrective action be initiated’ means, here we interpret it as meaning that a logoff message to be sent out, session closed and ‘status’ of the engine state set to ConnTerminatedWithoutLogoff.
Heartbeat VG.5
“If HeartBtInt is set to zero then no regular heartbeat messages will be generated. Note that a test request message can still be sent independent of the value of the HeartBtInt, which will force a Heartbeat message.”
Notes: We implement ‘test request message can still be sent independent of the value of the HeartBtInt’ as internal message.
Heartbeat VG.6
“Heartbeats issued as the result of Test Request must contain the TestReqID transmitted in the Test Request message. This is useful to verify that the Heartbeat is the result of the Test Request and not as the result of a regular timeout.”
Note: that the sequence number of the TestRequest message must be correct so that the state does not transition into Recovery.
Logon Messages
This section describes verification goals for Logon messages.
Logon VG.1
“The logon message must be the first message sent by the application requesting to initiate a FIX session.”
Note: we augment this with requirement that the engine correctly sets the acceptor/initiator flag.
Logon VG.2
“The session acceptor must be prepared to immediately begin processing messages after receipt of the Logon. The session initiator can choose to begin transmission of FIX messages before receipt of the confirmation Logon, however it is recommended that normal message delivery wait until after the return Logon is received to accommodate encryption key negotiation.”
Logon VG.3
“After authentication, the initiator and acceptor must synchronize their messages through interrogation of the MsgSeqNum field before sending any queued or new messages. A comparison of the MsgSeqNum in the Logon message to the internally monitored next expected sequence number will indicate any message gaps. Likewise, the initiator can detect gaps by comparing the acknowledgment Logon message’s MsgSeqNum to the next expected value. The section on message recovery later in this document deals with message gap handling.”
Logon VG.4
“If the session acceptor has chosen to change the session encryption key, the session initiator must send a third Logon back to the other side in order to acknowledge the key change request. This also allows the session acceptor to know when the session initiator has started to encrypt using the new session key. Both parties are responsible for infinite loop detection and prevention during this phase of the session.”
Notes: we break up the statement into the following VGs:
4.1 - If a confirmation Logon is received with a different encryption key, then another Logon is sent back with the same key. Also, we increment the ‘fe_num_logons_sent’ counter.
4.2 - When the engine attempts to send out a Logon message when the count is violated, it would transition into error mode with status change.
Logon VG.5
“NextExpectedMsgSeqNum (789) is used as follows:In its Logon request the session initiator supplies in NextExpectedMsgSeqNum (789) the value next expected from the session acceptor in MsgSeqNum (34). The outgoing header MsgSeqNum (34) of the Logon request is assigned the next-to-be-assigned sequence number as usual.
The session acceptor validates the Logon request including that NextExpectedMsgSeqNum (789) does not represent a gap. It then constructs its Logon response with NextExpectedMsgSeqNum (789) containing the value next expected from the session initiator in MsgSeqNum (34) having incremented the number above the Logon request if that was the sequence expected. The outgoing header MsgSeqNum (34) is constructed as usual. The session initiator waits to begin sending application messages until it receives the Logon response. When it is received the initiator validates the response including that NextExpectedMsgSeqNum (789) does not represent a gap.
Both sides react to NextExpectedMsgSeqNum (789) from its counterparty thus:
If equal to the next-to-be-assigned sequence, proceed sending new messages beginning with that number.
If lower than the next-to-be-assigned sequence, ‘recover’ (see ‘Message Recovery’) all messages from the the last message delivered prior to this Logon through the specified NextExpectedMsgSeqNum (789) sending them in order; then Gap Fill over the sequence number used in Logon and proceed sending newly queued messages with a sequence number one higher than the original Logon.
If higher than the next-to-be-assigned sequence, send Logout to abort the session.
Neither side should generate a ResendRequest based on MsgSeqNum (34) of the incoming Logon message but should expect any gaps to be filled automatically. If a gap is produced by the Logon message MsgSeqNum (34), the receive logic should expect the gap to be filled automatically prior to receiving any messages with sequences above the gap.”
Base
Base VG.1
When in ActiveSession (normal mode) and receiving a non grabled and non session-levelrejected message and the application is down. Such message would be sent back with aBusiness Reject.
Base VG.2
From Vol 2. Page 9:
In *ALL cases except the Sequence Reset - message, the FIX session*
should be terminated if the incoming sequence number is less than expected and thePossDupFlag is not set. A Logout message with some descriptive text should be sent to theother side before closing the session.
Base VG.3
Messages that are garbled will be ignored (sequence counter will not be incremented).
Base VG.4
Session rejected messages are rejected with the right reason and counter is incremented.
Rejection Logic
Sequence Number Logic
Sequence Reset Messages
Seq_Reset VG.1
“When the incoming sequence number does not match the expected corrective processing is required. Note that the SeqReset-Reset message (used only to recover from a disaster vs. normal resend request processing) is an exception to this rule as it should be processed without regards to its MsgSeqNum.”