Skip to content

Commit

Permalink
refactor decoding of entry functions
Browse files Browse the repository at this point in the history
  • Loading branch information
0o-de-lally committed Dec 4, 2024
1 parent 5f3f2e4 commit e8fd667
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 245 deletions.
1 change: 0 additions & 1 deletion src/analytics/enrich_account_funding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ pub fn replay_transactions(orders: &mut [ExchangeOrder]) -> BalanceTracker {
let mut tracker = BalanceTracker::new();
let sorted_orders = orders;
sorted_orders.sort_by_key(|order| order.created_at);
dbg!(&sorted_orders.len());
for order in sorted_orders {
tracker.process_transaction(order);
}
Expand Down
1 change: 0 additions & 1 deletion src/cypher_templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ use serde_json::Value;
/// Thanks Copilot ;)
pub fn to_cypher_object<T: Serialize>(object: &T) -> Result<String> {
// Serialize the struct to a JSON value

let serialized_value = serde_json::to_value(object).expect("Failed to serialize");
// dbg!(&serialized_value);

Expand Down
172 changes: 172 additions & 0 deletions src/decode_entry_function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use crate::schema_transaction::{EntryFunctionArgs, RelationLabel, UserEventTypes, WarehouseEvent};
use anyhow::bail;
use diem_types::transaction::SignedTransaction;
use libra_backwards_compatibility::sdk::{
v6_libra_framework_sdk_builder::EntryFunctionCall as V6EntryFunctionCall,
v7_libra_framework_sdk_builder::EntryFunctionCall as V7EntryFunctionCall,
};
// use libra_cached_packages::libra_stdlib::EntryFunctionCall as CurrentVersionEntryFunctionCall;

/// test all entry function decoders for the current bytes
pub fn decode_entry_function_all_versions(
user_tx: &SignedTransaction,
events: &[WarehouseEvent],
) -> anyhow::Result<(EntryFunctionArgs, RelationLabel)> {
// TODO: current version encoding

// if let Some((args, relation)) = maybe_get_current_version_relation(user_tx, events) {
// return Ok((args, relation));
// }

if let Some((ef, rel)) = maybe_get_v7_relation(user_tx, events) {
return Ok((ef, rel));
}

if let Some((ef, rel)) = maybe_get_v6_relation(user_tx, events) {
return Ok((ef, rel));
}

bail!("no entry function found")
}

// TODO: the CurrentVersionEntryFunctionCall needs serde derives
// Using HEAD libra-framework code base try to decode transaction
// fn maybe_get_current_version_relation(
// user_tx: &SignedTransaction,
// events: &[WarehouseEvent],
// ) -> Option<(EntryFunctionArgs, RelationLabel)> {
// let ef = CurrentVersionEntryFunctionCall::decode(user_tx.payload());

// let relation = match ef {
// Some(EntryFunctionCall::OlAccountTransfer { to, amount: _ }) => {
// if is_onboarding_event(events) {
// RelationLabel::Onboarding(to)
// } else {
// RelationLabel::Transfer(to)
// }
// }
// Some(EntryFunctionCall::OlAccountCreateAccount { auth_key }) => {
// RelationLabel::Onboarding(auth_key)
// }
// Some(EntryFunctionCall::VouchVouchFor { friend_account }) => {
// RelationLabel::Vouch(friend_account)
// }
// Some(EntryFunctionCall::VouchInsistVouchFor { friend_account }) => {
// RelationLabel::Vouch(friend_account)
// }
// Some(EntryFunctionCall::CoinTransfer { to, .. }) => RelationLabel::Transfer(to),
// Some(EntryFunctionCall::AccountRotateAuthenticationKeyWithRotationCapability {
// rotation_cap_offerer_address,
// ..
// }) => RelationLabel::Transfer(rotation_cap_offerer_address),

// // TODO: get other entry functions with known counter parties
// // if nothing is found try to decipher from events
// _ => return None,
// };

// let args = EntryFunctionArgs::Current(ef.unwrap());

// Some((args, relation))
// }

fn maybe_get_v7_relation(
user_tx: &SignedTransaction,
events: &[WarehouseEvent],
) -> Option<(EntryFunctionArgs, RelationLabel)> {
let ef = V7EntryFunctionCall::decode(user_tx.payload());

let relation = match ef {
Some(V7EntryFunctionCall::OlAccountTransfer { to, amount: _ }) => {
if is_onboarding_event(events) {
RelationLabel::Onboarding(to)
} else {
RelationLabel::Transfer(to)
}
}
Some(V7EntryFunctionCall::OlAccountCreateAccount { auth_key }) => {
RelationLabel::Onboarding(auth_key)
}
Some(V7EntryFunctionCall::VouchVouchFor { friend_account }) => {
RelationLabel::Vouch(friend_account)
}
Some(V7EntryFunctionCall::VouchInsistVouchFor { friend_account }) => {
RelationLabel::Vouch(friend_account)
}
Some(V7EntryFunctionCall::CoinTransfer { to, .. }) => RelationLabel::Transfer(to),
Some(V7EntryFunctionCall::AccountRotateAuthenticationKeyWithRotationCapability {
rotation_cap_offerer_address,
..
}) => RelationLabel::Transfer(rotation_cap_offerer_address),

// TODO: get other entry functions with known counter parties
// if nothing is found try to decipher from events
_ => return None,
};

let args = EntryFunctionArgs::V7(ef.unwrap());

Some((args, relation))
}

fn maybe_get_v6_relation(
user_tx: &SignedTransaction,
events: &[WarehouseEvent],
) -> Option<(EntryFunctionArgs, RelationLabel)> {
let ef = V6EntryFunctionCall::decode(user_tx.payload());
let relation = match ef {
Some(V6EntryFunctionCall::OlAccountTransfer { to, amount: _ }) => {
if is_onboarding_event(events) {
RelationLabel::Onboarding(to)
} else {
RelationLabel::Transfer(to)
}
}
Some(V6EntryFunctionCall::OlAccountCreateAccount { auth_key }) => {
RelationLabel::Onboarding(auth_key)
}
Some(V6EntryFunctionCall::VouchVouchFor { wanna_be_my_friend }) => {
RelationLabel::Vouch(wanna_be_my_friend)
}
Some(V6EntryFunctionCall::VouchInsistVouchFor { wanna_be_my_friend }) => {
RelationLabel::Vouch(wanna_be_my_friend)
}
Some(V6EntryFunctionCall::CoinTransfer { to, .. }) => RelationLabel::Transfer(to),
Some(V6EntryFunctionCall::AccountRotateAuthenticationKeyWithRotationCapability {
rotation_cap_offerer_address,
..
}) => RelationLabel::Transfer(rotation_cap_offerer_address),

// TODO: get other entry functions with known counter parties
// if nothing is found try to decipher from events
_ => return None,
};
let args = EntryFunctionArgs::V6(ef.unwrap());

Some((args, relation))
}

fn is_onboarding_event(events: &[WarehouseEvent]) -> bool {
let withdraw = events.iter().any(|e| {
if let UserEventTypes::Withdraw(_) = e.event {
return true;
}
false
});

let deposit = events.iter().any(|e| {
if let UserEventTypes::Deposit(_) = e.event {
return true;
}
false
});

let onboard = events.iter().any(|e| {
if let UserEventTypes::Onboard(_) = e.event {
return true;
}
false
});

withdraw && deposit && onboard
}
Loading

0 comments on commit e8fd667

Please sign in to comment.