0.7.48
This commit is contained in:
@@ -102,7 +102,17 @@ impl NonTradeEventMaterializationService {
|
||||
continue;
|
||||
},
|
||||
};
|
||||
if crate::is_dex_liquidity_event_kind(decoded_event.event_kind.as_str()) {
|
||||
if crate::is_dex_pool_lifecycle_event_kind(decoded_event.event_kind.as_str()) {
|
||||
let cleanup_result =
|
||||
self.delete_stale_pool_admin_event_for_lifecycle(decoded_event).await;
|
||||
match cleanup_result {
|
||||
Ok(_) => {},
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
if crate::is_dex_liquidity_event_kind(decoded_event.event_kind.as_str())
|
||||
&& !decoded_event.event_kind.ends_with(".lp_change_event")
|
||||
{
|
||||
let materialized = self
|
||||
.materialize_liquidity_event(
|
||||
&transaction,
|
||||
@@ -159,7 +169,9 @@ impl NonTradeEventMaterializationService {
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
if crate::is_dex_admin_event_kind(decoded_event.event_kind.as_str()) {
|
||||
if crate::is_dex_admin_event_kind(decoded_event.event_kind.as_str())
|
||||
&& !crate::is_dex_pool_lifecycle_event_kind(decoded_event.event_kind.as_str())
|
||||
{
|
||||
let materialized = self
|
||||
.materialize_pool_admin_event(
|
||||
&transaction,
|
||||
@@ -178,6 +190,36 @@ impl NonTradeEventMaterializationService {
|
||||
}
|
||||
}
|
||||
}
|
||||
for decoded_event in &decoded_events {
|
||||
if !decoded_event.event_kind.ends_with(".lp_change_event") {
|
||||
continue;
|
||||
}
|
||||
let payload_result =
|
||||
serde_json::from_str::<serde_json::Value>(decoded_event.payload_json.as_str());
|
||||
let payload = match payload_result {
|
||||
Ok(payload) => payload,
|
||||
Err(error) => {
|
||||
tracing::warn!(
|
||||
signature = %transaction.signature,
|
||||
event_kind = %decoded_event.event_kind,
|
||||
error = %error,
|
||||
"skipping postponed lp_change_event materialization for invalid decoded payload"
|
||||
);
|
||||
continue;
|
||||
},
|
||||
};
|
||||
let materialized = self
|
||||
.materialize_liquidity_event(&transaction, transaction_id, decoded_event, &payload)
|
||||
.await;
|
||||
match materialized {
|
||||
Ok(was_materialized) => {
|
||||
if was_materialized {
|
||||
result.liquidity_event_count += 1;
|
||||
}
|
||||
},
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@@ -274,6 +316,12 @@ impl NonTradeEventMaterializationService {
|
||||
"fund_fee_amount",
|
||||
"creatorFeeAmount",
|
||||
"creator_fee_amount",
|
||||
"amount0RequestedRaw",
|
||||
"amount_0_requested_raw",
|
||||
"amount1RequestedRaw",
|
||||
"amount_1_requested_raw",
|
||||
"tokenAAmount",
|
||||
"tokenBAmount",
|
||||
"amount",
|
||||
],
|
||||
);
|
||||
@@ -370,6 +418,48 @@ impl NonTradeEventMaterializationService {
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_stale_pool_admin_event_for_lifecycle(
|
||||
&self,
|
||||
decoded_event: &crate::DexDecodedEventDto,
|
||||
) -> Result<(), crate::Error> {
|
||||
let decoded_event_id = match decoded_event.id {
|
||||
Some(decoded_event_id) => decoded_event_id,
|
||||
None => return Ok(()),
|
||||
};
|
||||
match self.database.connection() {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let delete_result = sqlx::query(
|
||||
r#"
|
||||
DELETE FROM k_sol_pool_admin_events
|
||||
WHERE decoded_event_id = ?
|
||||
"#,
|
||||
)
|
||||
.bind(decoded_event_id)
|
||||
.execute(pool)
|
||||
.await;
|
||||
let delete_result = match delete_result {
|
||||
Ok(delete_result) => delete_result,
|
||||
Err(error) => {
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot delete stale k_sol_pool_admin_events for lifecycle decoded_event_id '{}' on sqlite: {}",
|
||||
decoded_event_id, error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let deleted_count = delete_result.rows_affected();
|
||||
if deleted_count > 0 {
|
||||
tracing::debug!(
|
||||
decoded_event_id = decoded_event_id,
|
||||
event_kind = %decoded_event.event_kind,
|
||||
deleted_count = deleted_count,
|
||||
"removed stale pool admin materialization for lifecycle event"
|
||||
);
|
||||
}
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn materialize_pool_admin_event(
|
||||
&self,
|
||||
transaction: &crate::ChainTransactionDto,
|
||||
@@ -437,6 +527,16 @@ impl NonTradeEventMaterializationService {
|
||||
Ok(context) => context,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let context = if context.pool_id.is_some() && context.pair.is_some() {
|
||||
context
|
||||
} else {
|
||||
let ensured_context =
|
||||
self.ensure_liquidity_context_from_decoded_event(decoded_event, context).await;
|
||||
match ensured_context {
|
||||
Ok(ensured_context) => ensured_context,
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
};
|
||||
let dex_id = match context.dex_id {
|
||||
Some(dex_id) => dex_id,
|
||||
None => return Ok(false),
|
||||
@@ -458,6 +558,12 @@ impl NonTradeEventMaterializationService {
|
||||
crate::LiquidityEventKind::PositionOpen
|
||||
} else if crate::is_dex_position_close_event_kind(decoded_event.event_kind.as_str()) {
|
||||
crate::LiquidityEventKind::PositionClose
|
||||
} else if decoded_event.event_kind.ends_with(".lp_change_event") {
|
||||
let change_type = extract_first_u64(payload, &["changeType", "change_type"]);
|
||||
match change_type {
|
||||
Some(1) => crate::LiquidityEventKind::Remove,
|
||||
_ => crate::LiquidityEventKind::Add,
|
||||
}
|
||||
} else if crate::is_dex_liquidity_remove_event_kind(decoded_event.event_kind.as_str()) {
|
||||
crate::LiquidityEventKind::Remove
|
||||
} else {
|
||||
@@ -487,6 +593,10 @@ impl NonTradeEventMaterializationService {
|
||||
"amount_base",
|
||||
"tokenAAmount",
|
||||
"token_a_amount",
|
||||
"token0AmountRaw",
|
||||
"token_0_amount_raw",
|
||||
"amount0RequestedRaw",
|
||||
"amount_0_requested_raw",
|
||||
"amountA",
|
||||
"amount_a",
|
||||
],
|
||||
@@ -502,6 +612,10 @@ impl NonTradeEventMaterializationService {
|
||||
"amount_quote",
|
||||
"tokenBAmount",
|
||||
"token_b_amount",
|
||||
"token1AmountRaw",
|
||||
"token_1_amount_raw",
|
||||
"amount1RequestedRaw",
|
||||
"amount_1_requested_raw",
|
||||
"amountB",
|
||||
"amount_b",
|
||||
],
|
||||
@@ -559,6 +673,54 @@ impl NonTradeEventMaterializationService {
|
||||
}
|
||||
}
|
||||
|
||||
async fn ensure_liquidity_context_from_decoded_event(
|
||||
&self,
|
||||
decoded_event: &crate::DexDecodedEventDto,
|
||||
context: NonTradeDecodedEventContext,
|
||||
) -> Result<NonTradeDecodedEventContext, crate::Error> {
|
||||
let dex_id = match context.dex_id {
|
||||
Some(dex_id) => dex_id,
|
||||
None => return Ok(context),
|
||||
};
|
||||
if context.pool_id.is_some() && context.pair.is_some() {
|
||||
return Ok(context);
|
||||
}
|
||||
if decoded_event.pool_account.is_none()
|
||||
|| decoded_event.token_a_mint.is_none()
|
||||
|| decoded_event.token_b_mint.is_none()
|
||||
{
|
||||
return Ok(context);
|
||||
}
|
||||
let materialization_input_result =
|
||||
crate::dex_pool_materialization::DexPoolMaterializationInput::from_decoded_event(
|
||||
decoded_event,
|
||||
dex_id,
|
||||
crate::PoolKind::Amm,
|
||||
crate::PoolStatus::Active,
|
||||
crate::dex_pool_materialization::DexPoolTokenOrder::AlreadyBaseQuote,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let materialization_input = match materialization_input_result {
|
||||
Ok(materialization_input) => materialization_input,
|
||||
Err(_) => return Ok(context),
|
||||
};
|
||||
let materialization_result = crate::dex_pool_materialization::materialize_dex_pool(
|
||||
self.database.as_ref(),
|
||||
&materialization_input,
|
||||
)
|
||||
.await;
|
||||
if let Err(error) = materialization_result {
|
||||
return Err(error);
|
||||
}
|
||||
let refreshed_context = self.resolve_decoded_event_context(decoded_event).await;
|
||||
match refreshed_context {
|
||||
Ok(refreshed_context) => return Ok(refreshed_context),
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_decoded_event_context(
|
||||
&self,
|
||||
decoded_event: &crate::DexDecodedEventDto,
|
||||
@@ -627,6 +789,29 @@ impl NonTradeEventMaterializationService {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_first_u64(
|
||||
value: &serde_json::Value,
|
||||
candidate_keys: &[&str],
|
||||
) -> std::option::Option<u64> {
|
||||
if let Some(object) = value.as_object() {
|
||||
for candidate_key in candidate_keys {
|
||||
let candidate_value = object.get(*candidate_key);
|
||||
if let Some(candidate_value) = candidate_value {
|
||||
if let Some(number) = candidate_value.as_u64() {
|
||||
return Some(number);
|
||||
}
|
||||
if let Some(text) = candidate_value.as_str() {
|
||||
let parsed = text.parse::<u64>();
|
||||
if let Ok(parsed) = parsed {
|
||||
return Some(parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
fn extract_first_amount_string(
|
||||
value: &serde_json::Value,
|
||||
candidate_keys: &[&str],
|
||||
|
||||
Reference in New Issue
Block a user