This commit is contained in:
2026-05-05 05:03:11 +02:00
parent 3e994995d7
commit f2c227e08f
132 changed files with 5767 additions and 4461 deletions

View File

@@ -29,15 +29,12 @@ impl KbPairCandleAggregationService {
/// Creates a new pair-candle aggregation service.
pub fn new(database: std::sync::Arc<crate::KbDatabase>) -> Self {
let persistence = crate::KbDetectionPersistenceService::new(database.clone());
Self {
database,
persistence,
}
return Self { database, persistence };
}
/// Returns the list of materialized timeframes in seconds.
pub fn materialized_timeframes_seconds(&self) -> std::vec::Vec<i64> {
vec![60, 300, 900, 3600]
return vec![60, 300, 900, 3600];
}
/// Rebuilds all impacted materialized candles for one resolved transaction signature.
@@ -58,7 +55,7 @@ impl KbPairCandleAggregationService {
"cannot aggregate pair candles for unknown transaction '{}'",
signature
)));
}
},
};
let transaction_id = match transaction.id {
Some(transaction_id) => transaction_id,
@@ -67,7 +64,7 @@ impl KbPairCandleAggregationService {
"transaction '{}' has no internal id",
signature
)));
}
},
};
let trade_events_result =
crate::list_trade_events_by_transaction_id(self.database.as_ref(), transaction_id)
@@ -149,7 +146,7 @@ impl KbPairCandleAggregationService {
return Err(error);
}
}
Ok(results)
return Ok(results);
}
async fn rebuild_one_candle(
@@ -186,12 +183,12 @@ impl KbPairCandleAggregationService {
Ok(pair_candle_id) => pair_candle_id,
Err(error) => return Err(error),
};
Ok(Some(crate::KbPairCandleAggregationResult {
return Ok(Some(crate::KbPairCandleAggregationResult {
pair_id,
timeframe_seconds,
bucket_start_unix,
pair_candle_id,
}))
}));
}
}
@@ -243,7 +240,7 @@ pub(crate) async fn kb_build_candle_from_trade_events(
if time_compare != std::cmp::Ordering::Equal {
return time_compare;
}
left.decoded_event_id.cmp(&right.decoded_event_id)
return left.decoded_event_id.cmp(&right.decoded_event_id);
});
let open_price_quote_per_base = rows[0].price_quote_per_base;
let close_price_quote_per_base = rows[rows.len() - 1].price_quote_per_base;
@@ -271,7 +268,7 @@ pub(crate) async fn kb_build_candle_from_trade_events(
base_volume_raw = kb_add_raw_amounts(base_volume_raw, row.base_amount_raw.clone());
quote_volume_raw = kb_add_raw_amounts(quote_volume_raw, row.quote_amount_raw.clone());
}
Ok(Some(crate::KbPairCandleDto::new(
return Ok(Some(crate::KbPairCandleDto::new(
pair_id,
timeframe_seconds,
bucket_start_unix,
@@ -287,7 +284,7 @@ pub(crate) async fn kb_build_candle_from_trade_events(
quote_volume_raw,
Some(rows[0].signature.clone()),
Some(rows[rows.len() - 1].signature.clone()),
)))
)));
}
pub(crate) async fn kb_extract_trade_event_unix_time(
@@ -305,8 +302,8 @@ pub(crate) async fn kb_extract_trade_event_unix_time(
None => return Ok(Some(trade_event.created_at.timestamp())),
};
match transaction.block_time_unix {
Some(block_time_unix) => Ok(Some(block_time_unix)),
None => Ok(Some(trade_event.created_at.timestamp())),
Some(block_time_unix) => return Ok(Some(block_time_unix)),
None => return Ok(Some(trade_event.created_at.timestamp())),
}
}
@@ -320,8 +317,7 @@ pub(crate) fn kb_bucket_start_unix(
timeframe_seconds
)));
}
Ok((event_time_unix / timeframe_seconds) * timeframe_seconds)
return Ok((event_time_unix / timeframe_seconds) * timeframe_seconds);
}
fn kb_add_raw_amounts(
@@ -329,9 +325,9 @@ fn kb_add_raw_amounts(
right: std::option::Option<std::string::String>,
) -> std::option::Option<std::string::String> {
match (left, right) {
(None, None) => None,
(Some(left), None) => Some(left),
(None, Some(right)) => Some(right),
(None, None) => return None,
(Some(left), None) => return Some(left),
(None, Some(right)) => return Some(right),
(Some(left), Some(right)) => {
let left_value_result = left.parse::<i128>();
let left_value = match left_value_result {
@@ -343,8 +339,8 @@ fn kb_add_raw_amounts(
Ok(right_value) => right_value,
Err(_) => return Some(left),
};
Some((left_value + right_value).to_string())
}
return Some((left_value + right_value).to_string());
},
}
}
@@ -385,7 +381,7 @@ mod tests {
Ok(database) => database,
Err(error) => panic!("database init must succeed: {}", error),
};
std::sync::Arc::new(database)
return std::sync::Arc::new(database);
}
async fn seed_fluxbeam_swap_transaction(
@@ -457,9 +453,7 @@ mod tests {
if let Err(error) = detect_result {
panic!("dex detect must succeed: {}", error);
}
let trade_result = trade_aggregation
.record_transaction_by_signature(signature)
.await;
let trade_result = trade_aggregation.record_transaction_by_signature(signature).await;
if let Err(error) = trade_result {
panic!("trade aggregation must succeed: {}", error);
}
@@ -493,21 +487,15 @@ mod tests {
)
.await;
let service = crate::KbPairCandleAggregationService::new(database.clone());
let result_1 = service
.record_transaction_by_signature("sig-pair-candle-1")
.await;
let result_1 = service.record_transaction_by_signature("sig-pair-candle-1").await;
if let Err(error) = result_1 {
panic!("candle aggregation 1 must succeed: {}", error);
}
let result_2 = service
.record_transaction_by_signature("sig-pair-candle-2")
.await;
let result_2 = service.record_transaction_by_signature("sig-pair-candle-2").await;
if let Err(error) = result_2 {
panic!("candle aggregation 2 must succeed: {}", error);
}
let result_3 = service
.record_transaction_by_signature("sig-pair-candle-3")
.await;
let result_3 = service.record_transaction_by_signature("sig-pair-candle-3").await;
if let Err(error) = result_3 {
panic!("candle aggregation 3 must succeed: {}", error);
}
@@ -558,17 +546,15 @@ mod tests {
)
.await;
let service = crate::KbPairCandleAggregationService::new(database.clone());
let first_result = service
.record_transaction_by_signature("sig-pair-candle-idempotent")
.await;
let first_result =
service.record_transaction_by_signature("sig-pair-candle-idempotent").await;
let first_results = match first_result {
Ok(first_results) => first_results,
Err(error) => panic!("first candle aggregation must succeed: {}", error),
};
assert!(!first_results.is_empty());
let second_result = service
.record_transaction_by_signature("sig-pair-candle-idempotent")
.await;
let second_result =
service.record_transaction_by_signature("sig-pair-candle-idempotent").await;
let second_results = match second_result {
Ok(second_results) => second_results,
Err(error) => panic!("second candle aggregation must succeed: {}", error),