This commit is contained in:
2026-05-13 09:39:50 +02:00
parent aa19ca9c18
commit 69385094ff
16 changed files with 293 additions and 36 deletions

View File

@@ -47,6 +47,13 @@ impl TradeAggregationService {
Err(error) => return Err(error),
};
let transaction = transaction_context.transaction;
if transaction.err_json.is_some() {
tracing::debug!(
signature = %transaction.signature,
"skipping trade aggregation for failed transaction"
);
return Ok(std::vec::Vec::new());
}
let transaction_id = transaction_context.transaction_id;
let decoded_events = transaction_context.decoded_events;
let mut results = std::vec::Vec::new();
@@ -221,11 +228,12 @@ mod tests {
return std::sync::Arc::new(database);
}
async fn seed_fluxbeam_swap_transaction(
async fn seed_fluxbeam_swap_transaction_with_err(
database: std::sync::Arc<crate::Database>,
signature: &str,
base_amount_raw: &str,
quote_amount_raw: &str,
meta_err: serde_json::Value,
) {
let transaction_model = crate::TransactionModelService::new(database.clone());
let dex_decode = crate::DexDecodeService::new(database.clone());
@@ -263,7 +271,7 @@ mod tests {
}
},
"meta": {
"err": null,
"err": meta_err,
"logMessages": [
"Program log: Instruction: Swap",
"Program log: buy"
@@ -290,6 +298,38 @@ mod tests {
}
}
async fn seed_fluxbeam_swap_transaction(
database: std::sync::Arc<crate::Database>,
signature: &str,
base_amount_raw: &str,
quote_amount_raw: &str,
) {
seed_fluxbeam_swap_transaction_with_err(
database,
signature,
base_amount_raw,
quote_amount_raw,
serde_json::Value::Null,
)
.await;
}
async fn seed_failed_fluxbeam_swap_transaction(
database: std::sync::Arc<crate::Database>,
signature: &str,
base_amount_raw: &str,
quote_amount_raw: &str,
) {
seed_fluxbeam_swap_transaction_with_err(
database,
signature,
base_amount_raw,
quote_amount_raw,
serde_json::json!({ "InstructionError": [0, { "Custom": 1 }] }),
)
.await;
}
#[tokio::test]
async fn record_transaction_by_signature_creates_trade_event_and_pair_metric() {
let database = make_database().await;
@@ -375,4 +415,49 @@ mod tests {
};
assert_eq!(pair_metric.trade_count, 1);
}
#[tokio::test]
async fn record_transaction_by_signature_skips_failed_transaction() {
let database = make_database().await;
seed_failed_fluxbeam_swap_transaction(
database.clone(),
"sig-trade-aggregation-failed-1",
"1000",
"2500",
)
.await;
let transaction_result = crate::query_chain_transactions_get_by_signature(
database.as_ref(),
"sig-trade-aggregation-failed-1",
)
.await;
let transaction_option = match transaction_result {
Ok(transaction_option) => transaction_option,
Err(error) => panic!("transaction fetch must succeed: {}", error),
};
let transaction = match transaction_option {
Some(transaction) => transaction,
None => panic!("transaction must exist"),
};
let transaction_id = match transaction.id {
Some(transaction_id) => transaction_id,
None => panic!("transaction id must exist"),
};
let service = crate::TradeAggregationService::new(database.clone());
let record_result =
service.record_transaction_by_signature("sig-trade-aggregation-failed-1").await;
let results = match record_result {
Ok(results) => results,
Err(error) => panic!("failed transaction aggregation must not fail: {}", error),
};
assert_eq!(results.len(), 0);
let trade_events_result =
crate::query_trade_events_list_by_transaction_id(database.as_ref(), transaction_id)
.await;
let trade_events = match trade_events_result {
Ok(trade_events) => trade_events,
Err(error) => panic!("trade event list must succeed: {}", error),
};
assert_eq!(trade_events.len(), 0);
}
}