Skip to content

Commit 3235da4

Browse files
authored
Merge pull request #5 from Boku-Labs/skip_check_for_sequence_reset
Remove config and just skip verififcation for reset messages
2 parents 9b2ff55 + 808f90c commit 3235da4

10 files changed

Lines changed: 40 additions & 193 deletions

File tree

crates/hotfix/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11-
- possibility to disalbe original sending time(tag 122) for admin messages ([#322](https://github.com/Validus-Risk-Management/hotfix/pull/334))
11+
- skip check for original sending time(tag 122) in sequence reset messages ([#322](https://github.com/Validus-Risk-Management/hotfix/pull/334))
1212

1313
## [0.11.0](https://github.com/Validus-Risk-Management/hotfix/compare/hotfix-v0.10.0...hotfix-v0.11.0) - 2026-03-25
1414

crates/hotfix/src/config.rs

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -114,63 +114,6 @@ pub struct SessionConfig {
114114

115115
/// The schedule configuration for the session
116116
pub schedule: Option<ScheduleConfig>,
117-
118-
/// The validation configuration for the session
119-
#[serde(default)]
120-
pub verification: VerificationConfig,
121-
}
122-
123-
#[derive(Clone, Debug, Deserialize)]
124-
/// The configuration of validation rules.
125-
pub struct VerificationConfig {
126-
/// Specifies whether we should check the original sending time for admin messages.
127-
#[serde(default = "default_true")]
128-
pub check_orig_sending_time_for_admin: bool,
129-
}
130-
131-
impl VerificationConfig {
132-
pub fn builder() -> VerificationConfigBuilder {
133-
VerificationConfigBuilder::default()
134-
}
135-
}
136-
137-
impl Default for VerificationConfig {
138-
fn default() -> Self {
139-
VerificationConfigBuilder::default().build()
140-
}
141-
}
142-
143-
pub struct VerificationConfigBuilder {
144-
check_orig_sending_time_for_admin: bool,
145-
}
146-
147-
impl Default for VerificationConfigBuilder {
148-
fn default() -> Self {
149-
Self {
150-
check_orig_sending_time_for_admin: true,
151-
}
152-
}
153-
}
154-
155-
impl VerificationConfigBuilder {
156-
pub fn new() -> Self {
157-
Self::default()
158-
}
159-
160-
pub fn check_orig_sending_time_for_admin(mut self, value: bool) -> Self {
161-
self.check_orig_sending_time_for_admin = value;
162-
self
163-
}
164-
165-
pub fn build(self) -> VerificationConfig {
166-
VerificationConfig {
167-
check_orig_sending_time_for_admin: self.check_orig_sending_time_for_admin,
168-
}
169-
}
170-
}
171-
172-
fn default_true() -> bool {
173-
true
174117
}
175118

176119
/// Errors that may occur when loading configuration.
@@ -227,11 +170,6 @@ reset_on_logon = false
227170
assert_eq!(session_config.tls_config, Some(expected_tls_config));
228171
assert_eq!(session_config.reconnect_interval, 30);
229172
assert_eq!(session_config.logon_timeout, 10);
230-
assert!(
231-
session_config
232-
.verification
233-
.check_orig_sending_time_for_admin
234-
);
235173
}
236174

237175
#[test]
@@ -501,53 +439,6 @@ end_day = "Friday"
501439
assert_eq!(session_config.reconnect_interval, 15);
502440
}
503441

504-
#[test]
505-
fn test_verification_config_defaults_when_omitted() {
506-
let config_contents = r#"
507-
[[sessions]]
508-
begin_string = "FIX.4.4"
509-
sender_comp_id = "send-comp-id"
510-
target_comp_id = "target-comp-id"
511-
connection_port = 443
512-
connection_host = "127.0.0.1"
513-
heartbeat_interval = 30
514-
"#;
515-
516-
let config: Config = toml::from_str(config_contents).unwrap();
517-
let session_config = config.sessions.first().unwrap();
518-
519-
assert!(
520-
session_config
521-
.verification
522-
.check_orig_sending_time_for_admin
523-
);
524-
}
525-
526-
#[test]
527-
fn test_verification_config_can_disable_admin_orig_sending_time_check() {
528-
let config_contents = r#"
529-
[[sessions]]
530-
begin_string = "FIX.4.4"
531-
sender_comp_id = "send-comp-id"
532-
target_comp_id = "target-comp-id"
533-
connection_port = 443
534-
connection_host = "127.0.0.1"
535-
heartbeat_interval = 30
536-
537-
[sessions.verification]
538-
check_orig_sending_time_for_admin = false
539-
"#;
540-
541-
let config: Config = toml::from_str(config_contents).unwrap();
542-
let session_config = config.sessions.first().unwrap();
543-
544-
assert!(
545-
!session_config
546-
.verification
547-
.check_orig_sending_time_for_admin
548-
);
549-
}
550-
551442
#[test]
552443
fn test_load_from_path_success() {
553444
let config_contents = r#"

crates/hotfix/src/initiator.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ async fn establish_connection<Outbound: OutboundMessage>(
157157
mod tests {
158158
use super::*;
159159
use crate::application::{Application, InboundDecision, OutboundDecision};
160-
use crate::config::VerificationConfig;
161160
use crate::message::generate_message;
162161
use crate::message::logon::{Logon, ResetSeqNumConfig};
163162
use crate::message::logout::Logout;
@@ -300,7 +299,6 @@ mod tests {
300299
reconnect_interval: 1, // Short for tests
301300
reset_on_logon: false,
302301
schedule: None,
303-
verification: VerificationConfig::default(),
304302
}
305303
}
306304

crates/hotfix/src/message/verification.rs

Lines changed: 34 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::config::{SessionConfig, VerificationConfig};
1+
use crate::config::SessionConfig;
2+
use crate::message::ResendRequest;
23
use crate::message::logout::Logout;
34
use crate::message::reject::Reject;
45
use crate::message::sequence_reset::SequenceReset;
56
use crate::message::verification_issue::{CompIdType, MessageError, VerificationIssue};
6-
use crate::message::{ResendRequest, is_admin};
77
use crate::session::error::SessionOperationError;
88
use hotfix_message::Part;
99
use hotfix_message::field_types::Timestamp;
@@ -22,7 +22,6 @@ const SENDING_TIME_THRESHOLD: u64 = 120;
2222
pub(crate) struct VerificationFlags {
2323
pub(crate) check_too_high: bool,
2424
pub(crate) check_too_low: bool,
25-
#[allow(dead_code)]
2625
pub(crate) check_orig_sending_time: bool,
2726
}
2827

@@ -43,36 +42,28 @@ impl VerificationFlags {
4342
self.check_too_high || self.check_too_low
4443
}
4544

46-
pub(crate) fn for_message(
47-
message: &Message,
48-
user_config: &VerificationConfig,
49-
) -> Result<Self, SessionOperationError> {
45+
pub(crate) fn for_message(message: &Message) -> Result<Self, SessionOperationError> {
5046
let message_type: &str = message
5147
.header()
5248
.get(MSG_TYPE)
5349
.map_err(|_| SessionOperationError::MissingField("MSG_TYPE"))?;
5450

5551
let possible_duplicate = message.header().get::<bool>(POSS_DUP_FLAG).unwrap_or(false);
56-
let check_orig_sending_time = if is_admin(message_type) {
57-
possible_duplicate && user_config.check_orig_sending_time_for_admin
58-
} else {
59-
possible_duplicate
60-
};
6152

6253
let flags = match message_type {
6354
// check_too_high=false: QFJ-673 deadlock fix. When both sides send
6455
// ResendRequest simultaneously, each side's ResendRequest will have a seq
6556
// number higher than expected. By not treating that as an error, we allow
6657
// the ResendRequest to be processed.
6758
ResendRequest::MSG_TYPE | Reject::MSG_TYPE => {
68-
Self::new(false, true, check_orig_sending_time)
59+
Self::new(false, true, possible_duplicate)
6960
}
70-
Logout::MSG_TYPE => Self::new(false, false, check_orig_sending_time),
61+
Logout::MSG_TYPE => Self::new(false, false, possible_duplicate),
7162
SequenceReset::MSG_TYPE => {
7263
let is_gap_fill: bool = message.get(GAP_FILL_FLAG).unwrap_or(false);
73-
Self::new(is_gap_fill, is_gap_fill, check_orig_sending_time)
64+
Self::new(is_gap_fill, is_gap_fill, false)
7465
}
75-
_ => Self::new(true, true, check_orig_sending_time),
66+
_ => Self::new(true, true, possible_duplicate),
7667
};
7768

7869
Ok(flags)
@@ -246,8 +237,8 @@ fn check_target_comp_id(
246237

247238
#[cfg(test)]
248239
mod tests {
249-
use super::{Message, SessionConfig, VerificationConfig, VerificationFlags, verify_message};
250-
use crate::message::heartbeat::Heartbeat;
240+
use super::{Message, SessionConfig, VerificationFlags, verify_message};
241+
use crate::message::sequence_reset::SequenceReset;
251242
use crate::message::verification_issue::{CompIdType, MessageError, VerificationIssue};
252243
use hotfix_message::field_types::Timestamp;
253244
use hotfix_message::{Part, fix44};
@@ -267,7 +258,6 @@ mod tests {
267258
reconnect_interval: 0,
268259
reset_on_logon: false,
269260
schedule: None,
270-
verification: VerificationConfig::default(),
271261
}
272262
}
273263

@@ -296,62 +286,47 @@ mod tests {
296286
}
297287

298288
#[test]
299-
fn test_creating_flags_for_admin_message_should_check_orig_sending_time_when_enabled() {
300-
let mut msg =
301-
build_test_message_with_type("FIX.4.4", Heartbeat::MSG_TYPE, "TARGET", "SENDER", 42);
302-
msg.header_mut().set(fix44::POSS_DUP_FLAG, true);
303-
304-
let flags = VerificationFlags::for_message(&msg, &VerificationConfig::default()).unwrap();
305-
306-
assert!(flags.check_orig_sending_time);
307-
assert!(flags.check_too_high);
308-
assert!(flags.check_too_low);
309-
}
310-
311-
#[test]
312-
fn test_creating_flags_for_admin_message_should_skip_check_orig_sending_time_when_not_poss_dup()
313-
{
314-
let msg =
315-
build_test_message_with_type("FIX.4.4", Heartbeat::MSG_TYPE, "TARGET", "SENDER", 42);
289+
fn test_creating_flags_for_gap_fill_message_should_skip_check_orig_sending_time() {
290+
let msg = build_test_message_with_type(
291+
"FIX.4.4",
292+
SequenceReset::MSG_TYPE,
293+
"TARGET",
294+
"SENDER",
295+
42,
296+
);
316297

317-
let flags = VerificationFlags::for_message(&msg, &VerificationConfig::default()).unwrap();
298+
let flags = VerificationFlags::for_message(&msg).unwrap();
318299

319300
assert!(!flags.check_orig_sending_time);
320-
assert!(flags.check_too_high);
321-
assert!(flags.check_too_low);
301+
assert!(!flags.check_too_high);
302+
assert!(!flags.check_too_low);
322303
}
323304

324305
#[test]
325-
fn test_creating_flags_for_admin_message_should_skip_check_orig_sending_time_when_disabled() {
326-
let mut msg =
327-
build_test_message_with_type("FIX.4.4", Heartbeat::MSG_TYPE, "TARGET", "SENDER", 42);
306+
fn test_creating_flags_for_gap_fill_message_should_skip_check_orig_sending_time_even_for_poss_duplicate()
307+
{
308+
let mut msg = build_test_message_with_type(
309+
"FIX.4.4",
310+
SequenceReset::MSG_TYPE,
311+
"TARGET",
312+
"SENDER",
313+
42,
314+
);
328315
msg.header_mut().set(fix44::POSS_DUP_FLAG, true);
329316

330-
let flags = VerificationFlags::for_message(
331-
&msg,
332-
&VerificationConfig {
333-
check_orig_sending_time_for_admin: false,
334-
},
335-
)
336-
.unwrap();
317+
let flags = VerificationFlags::for_message(&msg).unwrap();
337318

338319
assert!(!flags.check_orig_sending_time);
339-
assert!(flags.check_too_high);
340-
assert!(flags.check_too_low);
320+
assert!(!flags.check_too_high);
321+
assert!(!flags.check_too_low);
341322
}
342323

343324
#[test]
344325
fn test_creating_flags_for_app_messages_does_not_skip_orig_sending_time() {
345326
let mut msg = build_test_message("FIX.4.4", "TARGET", "SENDER", 42);
346327
msg.header_mut().set(fix44::POSS_DUP_FLAG, true);
347328

348-
let flags = VerificationFlags::for_message(
349-
&msg,
350-
&VerificationConfig {
351-
check_orig_sending_time_for_admin: false,
352-
},
353-
)
354-
.unwrap();
329+
let flags = VerificationFlags::for_message(&msg).unwrap();
355330

356331
assert!(flags.check_orig_sending_time);
357332
assert!(flags.check_too_high);
@@ -362,13 +337,7 @@ mod tests {
362337
fn test_creating_flags_for_app_messages_skip_orig_sending_time_when_it_is_not_poss_dup() {
363338
let msg = build_test_message("FIX.4.4", "TARGET", "SENDER", 42);
364339

365-
let flags = VerificationFlags::for_message(
366-
&msg,
367-
&VerificationConfig {
368-
check_orig_sending_time_for_admin: true,
369-
},
370-
)
371-
.unwrap();
340+
let flags = VerificationFlags::for_message(&msg).unwrap();
372341

373342
assert!(!flags.check_orig_sending_time);
374343
assert!(flags.check_too_high);

crates/hotfix/src/session.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ where
208208
.get(MSG_TYPE)
209209
.map_err(|_| SessionOperationError::MissingField("MSG_TYPE"))?;
210210

211-
let flags = VerificationFlags::for_message(&message, self.ctx.verification_config())?;
211+
let flags = VerificationFlags::for_message(&message)?;
212212
if let VerificationResult::Issue(result) = self
213213
.state
214214
.handle_verification_issue(&mut self.ctx, &message, flags)
@@ -755,7 +755,6 @@ async fn run_session<App, Store>(
755755
mod tests {
756756
use super::*;
757757
use crate::application::{InboundDecision, OutboundDecision};
758-
use crate::config::VerificationConfig;
759758
use crate::message::OutboundMessage;
760759
use crate::store::{Result as StoreResult, StoreError};
761760
use chrono::{DateTime, Datelike, NaiveDate, NaiveTime, TimeDelta, Timelike};
@@ -892,7 +891,6 @@ mod tests {
892891
reconnect_interval: 30,
893892
reset_on_logon: false,
894893
schedule: None,
895-
verification: VerificationConfig::default(),
896894
}
897895
}
898896

crates/hotfix/src/session/ctx.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use hotfix_message::message::Config as MessageConfig;
33
use hotfix_store::MessageStore;
44

55
use crate::config::SessionConfig;
6-
use crate::config::VerificationConfig;
76
use crate::message::OutboundMessage;
87
use crate::message::generate_message;
98
use crate::message::parser::RawFixMessage;
@@ -89,8 +88,4 @@ impl<A, S: MessageStore> SessionCtx<A, S> {
8988
raw: RawFixMessage::new(msg),
9089
})
9190
}
92-
93-
pub fn verification_config(&self) -> &VerificationConfig {
94-
&self.config.verification
95-
}
9691
}

crates/hotfix/src/session/test_utils.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::config::{SessionConfig, VerificationConfig};
1+
use crate::config::SessionConfig;
22
use crate::session::ctx::SessionCtx;
33
use crate::store::{MessageStore, Result as StoreResult};
44
use crate::transport::writer::{WriterMessage, WriterRef};
@@ -87,7 +87,6 @@ pub(crate) fn create_test_ctx(store: FakeMessageStore) -> SessionCtx<(), FakeMes
8787
reconnect_interval: 30,
8888
reset_on_logon: false,
8989
schedule: None,
90-
verification: VerificationConfig::default(),
9190
},
9291
store,
9392
application: (),

0 commit comments

Comments
 (0)