0.7.45
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
//! deterministic local pipeline over their signatures.
|
||||
|
||||
const LOCAL_PIPELINE_DEX_DECODER_SCOPE: &str = "dex_decode.local_pipeline";
|
||||
const LOCAL_PIPELINE_DEX_DECODER_VERSION: &str = "dex_decode.v0.7.44.ledger1";
|
||||
const LOCAL_PIPELINE_DEX_DECODER_VERSION: &str =
|
||||
"dex_decode.v0.7.45.dlmm_add_liquidity_strategies1";
|
||||
|
||||
fn default_skip_certified_dex_decode() -> bool {
|
||||
return true;
|
||||
@@ -193,9 +194,11 @@ impl LocalPipelineReplayService {
|
||||
signature = %signature,
|
||||
"replaying local pipeline for persisted transaction"
|
||||
);
|
||||
let transaction_result =
|
||||
crate::query_chain_transactions_get_by_signature(self.database.as_ref(), signature.as_str())
|
||||
.await;
|
||||
let transaction_result = crate::query_chain_transactions_get_by_signature(
|
||||
self.database.as_ref(),
|
||||
signature.as_str(),
|
||||
)
|
||||
.await;
|
||||
let transaction = match transaction_result {
|
||||
Ok(Some(transaction)) => transaction,
|
||||
Ok(None) => {
|
||||
@@ -260,9 +263,8 @@ impl LocalPipelineReplayService {
|
||||
);
|
||||
},
|
||||
None => {
|
||||
let decode_result = dex_decode
|
||||
.decode_transaction_by_signature(signature.as_str())
|
||||
.await;
|
||||
let decode_result =
|
||||
dex_decode.decode_transaction_by_signature(signature.as_str()).await;
|
||||
match decode_result {
|
||||
Ok(decoded_events) => {
|
||||
result.decoded_event_count += decoded_events.len();
|
||||
@@ -542,11 +544,8 @@ impl LocalPipelineReplayService {
|
||||
signature: &str,
|
||||
decoded_events: &[crate::DexDecodedEventDto],
|
||||
) -> Result<crate::DexDecodeReplayLedgerDto, crate::Error> {
|
||||
let ledger_result = build_success_dex_decode_replay_ledger(
|
||||
transaction_id,
|
||||
signature,
|
||||
decoded_events,
|
||||
);
|
||||
let ledger_result =
|
||||
build_success_dex_decode_replay_ledger(transaction_id, signature, decoded_events);
|
||||
let ledger = match ledger_result {
|
||||
Ok(ledger) => ledger,
|
||||
Err(error) => return Err(error),
|
||||
@@ -597,10 +596,23 @@ fn build_success_dex_decode_replay_ledger(
|
||||
Err(error) => {
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert decoded event count '{}' to i64: {}",
|
||||
decoded_events.len(), error
|
||||
decoded_events.len(),
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let effective_event_count_usize = count_effective_decoded_events(decoded_events);
|
||||
let effective_event_count_result = i64::try_from(effective_event_count_usize);
|
||||
let effective_event_count = match effective_event_count_result {
|
||||
Ok(effective_event_count) => effective_event_count,
|
||||
Err(error) => {
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot convert effective decoded event count '{}' to i64: {}",
|
||||
effective_event_count_usize, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let instruction_audit_count = event_count - effective_event_count;
|
||||
let distinct_token_mint_count_usize = count_distinct_decoded_event_token_mints(decoded_events);
|
||||
let distinct_token_mint_count_result = i64::try_from(distinct_token_mint_count_usize);
|
||||
let distinct_token_mint_count = match distinct_token_mint_count_result {
|
||||
@@ -612,7 +624,7 @@ fn build_success_dex_decode_replay_ledger(
|
||||
)));
|
||||
},
|
||||
};
|
||||
let force_replay_required = event_count > 1 || distinct_token_mint_count > 2;
|
||||
let force_replay_required = effective_event_count > 1 || distinct_token_mint_count > 2;
|
||||
let decode_status = if event_count == 0 {
|
||||
crate::DexDecodeReplayLedgerDto::STATUS_NO_EVENTS.to_string()
|
||||
} else {
|
||||
@@ -625,6 +637,8 @@ fn build_success_dex_decode_replay_ledger(
|
||||
};
|
||||
let status_reason = build_dex_decode_replay_ledger_status_reason(
|
||||
event_count,
|
||||
effective_event_count,
|
||||
instruction_audit_count,
|
||||
distinct_token_mint_count,
|
||||
force_replay_required,
|
||||
);
|
||||
@@ -642,9 +656,22 @@ fn build_success_dex_decode_replay_ledger(
|
||||
));
|
||||
}
|
||||
|
||||
fn count_distinct_decoded_event_token_mints(
|
||||
decoded_events: &[crate::DexDecodedEventDto],
|
||||
) -> usize {
|
||||
fn count_effective_decoded_events(decoded_events: &[crate::DexDecodedEventDto]) -> usize {
|
||||
let mut count = 0_usize;
|
||||
for event in decoded_events {
|
||||
if is_instruction_audit_event(event) {
|
||||
continue;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
fn is_instruction_audit_event(event: &crate::DexDecodedEventDto) -> bool {
|
||||
return event.event_kind.ends_with(".instruction_audit");
|
||||
}
|
||||
|
||||
fn count_distinct_decoded_event_token_mints(decoded_events: &[crate::DexDecodedEventDto]) -> usize {
|
||||
let mut mints = std::collections::BTreeSet::<std::string::String>::new();
|
||||
for event in decoded_events {
|
||||
insert_optional_mint(&mut mints, &event.lp_mint);
|
||||
@@ -668,6 +695,8 @@ fn insert_optional_mint(
|
||||
|
||||
fn build_dex_decode_replay_ledger_status_reason(
|
||||
event_count: i64,
|
||||
effective_event_count: i64,
|
||||
instruction_audit_count: i64,
|
||||
distinct_token_mint_count: i64,
|
||||
force_replay_required: bool,
|
||||
) -> std::string::String {
|
||||
@@ -676,11 +705,11 @@ fn build_dex_decode_replay_ledger_status_reason(
|
||||
}
|
||||
if force_replay_required {
|
||||
return format!(
|
||||
"decode completed but remains unsafe for skip: event_count={event_count}, distinct_token_mint_count={distinct_token_mint_count}"
|
||||
"decode completed but remains unsafe for skip: event_count={event_count}, effective_event_count={effective_event_count}, instruction_audit_count={instruction_audit_count}, distinct_token_mint_count={distinct_token_mint_count}"
|
||||
);
|
||||
}
|
||||
return format!(
|
||||
"decode completed and certified for skip: event_count={event_count}, distinct_token_mint_count={distinct_token_mint_count}"
|
||||
"decode completed and certified for skip: event_count={event_count}, effective_event_count={effective_event_count}, instruction_audit_count={instruction_audit_count}, distinct_token_mint_count={distinct_token_mint_count}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -692,3 +721,57 @@ pub async fn replay_local_pipeline(
|
||||
let service = crate::LocalPipelineReplayService::new(database);
|
||||
return service.replay_local_pipeline(config).await;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
fn make_decoded_event(
|
||||
event_kind: &str,
|
||||
token_a_mint: std::option::Option<&str>,
|
||||
token_b_mint: std::option::Option<&str>,
|
||||
) -> crate::DexDecodedEventDto {
|
||||
return crate::DexDecodedEventDto::new(
|
||||
1,
|
||||
Some(10),
|
||||
"meteora_dlmm".to_string(),
|
||||
crate::METEORA_DLMM_PROGRAM_ID.to_string(),
|
||||
event_kind.to_string(),
|
||||
Some("pool".to_string()),
|
||||
None,
|
||||
token_a_mint.map(|value| return value.to_string()),
|
||||
token_b_mint.map(|value| return value.to_string()),
|
||||
None,
|
||||
"{}".to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ledger_certifies_one_effective_event_with_instruction_audits() {
|
||||
let events = vec![
|
||||
make_decoded_event("meteora_dlmm.swap", Some("mint-a"), Some("mint-b")),
|
||||
make_decoded_event("meteora_dlmm.instruction_audit", None, None),
|
||||
make_decoded_event("meteora_dlmm.instruction_audit", None, None),
|
||||
];
|
||||
let ledger = super::build_success_dex_decode_replay_ledger(1, "sig", events.as_slice())
|
||||
.expect("ledger must build");
|
||||
assert_eq!(ledger.event_count, 3);
|
||||
assert_eq!(ledger.distinct_token_mint_count, 2);
|
||||
assert!(!ledger.force_replay_required);
|
||||
assert_eq!(ledger.certainty, crate::DexDecodeReplayLedgerDto::CERTAINTY_SURE);
|
||||
assert!(ledger.can_skip_decode());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ledger_keeps_multiple_effective_events_unsafe() {
|
||||
let events = vec![
|
||||
make_decoded_event("meteora_dlmm.swap", Some("mint-a"), Some("mint-b")),
|
||||
make_decoded_event("meteora_dlmm.swap", Some("mint-a"), Some("mint-b")),
|
||||
make_decoded_event("meteora_dlmm.instruction_audit", None, None),
|
||||
];
|
||||
let ledger = super::build_success_dex_decode_replay_ledger(1, "sig", events.as_slice())
|
||||
.expect("ledger must build");
|
||||
assert_eq!(ledger.event_count, 3);
|
||||
assert!(ledger.force_replay_required);
|
||||
assert_eq!(ledger.certainty, crate::DexDecodeReplayLedgerDto::CERTAINTY_UNSAFE);
|
||||
assert!(!ledger.can_skip_decode());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user