From 97ea7de13d1ed08166a9f0757c49622498463f59 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli Date: Wed, 22 Jan 2025 17:11:18 +0100 Subject: [PATCH] added migration, added notes parsing --- .../down.sql | 3 + .../up.sql | 3 + orm/src/gas.rs | 4 ++ orm/src/schema.rs | 18 ++++++ shared/src/block_result.rs | 64 ++++++++++++++++++- shared/src/gas.rs | 24 +++---- shared/src/transaction.rs | 32 +++++++++- transactions/src/services/tx.rs | 25 ++++++-- 8 files changed, 149 insertions(+), 24 deletions(-) create mode 100644 orm/migrations/2025-01-27-130323_gas_estimation_ibc/down.sql create mode 100644 orm/migrations/2025-01-27-130323_gas_estimation_ibc/up.sql diff --git a/orm/migrations/2025-01-27-130323_gas_estimation_ibc/down.sql b/orm/migrations/2025-01-27-130323_gas_estimation_ibc/down.sql new file mode 100644 index 00000000..f368ee9d --- /dev/null +++ b/orm/migrations/2025-01-27-130323_gas_estimation_ibc/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE gas_estimations DROP COLUMN ibc_unshielding_transfer; +ALTER TABLE gas_estimations DROP COLUMN ibc_shielding_transfer; \ No newline at end of file diff --git a/orm/migrations/2025-01-27-130323_gas_estimation_ibc/up.sql b/orm/migrations/2025-01-27-130323_gas_estimation_ibc/up.sql new file mode 100644 index 00000000..a3bc6459 --- /dev/null +++ b/orm/migrations/2025-01-27-130323_gas_estimation_ibc/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here +ALTER TABLE gas_estimations ADD COLUMN ibc_unshielding_transfer INT NOT NULL; +ALTER TABLE gas_estimations ADD COLUMN ibc_shielding_transfer INT NOT NULL; \ No newline at end of file diff --git a/orm/src/gas.rs b/orm/src/gas.rs index a32257a3..37438790 100644 --- a/orm/src/gas.rs +++ b/orm/src/gas.rs @@ -42,6 +42,8 @@ pub struct GasEstimationDb { pub shielded_transfer: i32, pub shielding_transfer: i32, pub unshielding_transfer: i32, + pub ibc_unshielding_transfer: i32, + pub ibc_shielding_transfer: i32, pub ibc_msg_transfer: i32, pub bond: i32, pub redelegation: i32, @@ -65,6 +67,8 @@ impl From for GasEstimationInsertDb { shielding_transfer: value.shielding_transfer as i32, unshielding_transfer: value.unshielding_transfer as i32, ibc_msg_transfer: value.ibc_msg_transfer as i32, + ibc_unshielding_transfer: value.ibc_unshielding_transfer as i32, + ibc_shielding_transfer: value.ibc_shielding_transfer as i32, bond: value.bond as i32, redelegation: value.redelegation as i32, unbond: value.unbond as i32, diff --git a/orm/src/schema.rs b/orm/src/schema.rs index 672b7e4b..c0062557 100644 --- a/orm/src/schema.rs +++ b/orm/src/schema.rs @@ -49,6 +49,22 @@ pub mod sql_types { #[diesel(postgres_type(name = "ibc_status"))] pub struct IbcStatus; + #[derive( + diesel::query_builder::QueryId, + std::fmt::Debug, + diesel::sql_types::SqlType, + )] + #[diesel(postgres_type(name = "payment_kind"))] + pub struct PaymentKind; + + #[derive( + diesel::query_builder::QueryId, + std::fmt::Debug, + diesel::sql_types::SqlType, + )] + #[diesel(postgres_type(name = "payment_recurrence"))] + pub struct PaymentRecurrence; + #[derive( diesel::query_builder::QueryId, std::fmt::Debug, @@ -186,6 +202,8 @@ diesel::table! { reveal_pk -> Int4, tx_size -> Int4, signatures -> Int4, + ibc_unshielding_transfer -> Int4, + ibc_shielding_transfer -> Int4, } } diff --git a/shared/src/block_result.rs b/shared/src/block_result.rs index 42d47989..6dcb8d40 100644 --- a/shared/src/block_result.rs +++ b/shared/src/block_result.rs @@ -1,6 +1,8 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; +use std::fmt; use std::str::FromStr; +use namada_sdk::events::extend::{IndexedMaspData, MaspTxRef}; use namada_tx::data::TxResult; use tendermint_rpc::endpoint::block_results::Response as TendermintBlockResultResponse; @@ -108,7 +110,7 @@ impl BatchResults { } } -#[derive(Debug, Clone, Default)] +#[derive(Clone)] pub struct TxApplied { pub code: TxEventStatusCode, pub gas: u64, @@ -116,6 +118,27 @@ pub struct TxApplied { pub height: u64, pub batch: BatchResults, pub info: String, + pub masp_refs: HashMap>, +} + +impl fmt::Debug for TxApplied { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TxApplied") + .field("code", &self.code) + .field("gas", &self.gas) + .field("hash", &self.hash) + .field("height", &self.height) + .field("batch", &self.batch) + .field("info", &self.info) + .field("masp_refs_len", &self.masp_refs.len()) + .finish() + } +} + +#[derive(Debug, Clone)] +pub enum MaspRef { + Native(String), + Ibc(String), } #[derive(Debug, Clone, Default)] @@ -189,6 +212,24 @@ impl TxAttributesType { .map(|height| u64::from_str(height).unwrap()) .unwrap() .to_owned(), + masp_refs: attributes + .get("masp_data_refs") + .map(|data| { + if let Ok(data) = + serde_json::from_str::(data) + { + let refs = data + .masp_refs + .0 + .iter() + .map(|masp_ref| masp_ref.clone()) + .collect(); + HashMap::from_iter([(data.tx_index.0 as u64, refs)]) + } else { + HashMap::default() + } + }) + .unwrap_or_default(), batch: attributes .get("batch") .map(|batch_result| { @@ -323,4 +364,23 @@ impl BlockResult { }); exit_status.unwrap_or(TransactionExitStatus::Rejected) } + + pub fn masp_refs(&self, wrapper_hash: &Id, index: u64) -> Vec { + self.end_events + .iter() + .filter_map(|event| { + if let Some(TxAttributesType::TxApplied(data)) = + &event.attributes + { + Some(data.clone()) + } else { + None + } + }) + .find(|attributes| attributes.hash.eq(wrapper_hash)) + .map(|event| { + event.masp_refs.get(&index).cloned().unwrap_or_default() + }) + .unwrap_or_default() + } } diff --git a/shared/src/gas.rs b/shared/src/gas.rs index 6399b683..61719f80 100644 --- a/shared/src/gas.rs +++ b/shared/src/gas.rs @@ -57,28 +57,28 @@ impl GasEstimation { self.transparent_transfer += 1 } - pub fn increase_shielded_transfer(&mut self) { - self.shielded_transfer += 1 + pub fn increase_shielded_transfer(&mut self, notes: u64) { + self.shielded_transfer += notes } - pub fn increase_shielding_transfer(&mut self) { - self.shielding_transfer += 1 + pub fn increase_shielding_transfer(&mut self, notes: u64) { + self.shielding_transfer += notes } - pub fn increase_unshielding_transfer(&mut self) { - self.unshielding_transfer += 1 + pub fn increase_unshielding_transfer(&mut self, notes: u64) { + self.unshielding_transfer += notes } - pub fn increase_mixed_transfer(&mut self) { - self.mixed_transfer += 1 + pub fn increase_mixed_transfer(&mut self, notes: u64) { + self.mixed_transfer += notes } - pub fn increase_ibc_shielding_transfer(&mut self) { - self.ibc_shielding_transfer += 1 + pub fn increase_ibc_shielding_transfer(&mut self, notes: u64) { + self.ibc_shielding_transfer += notes } - pub fn increase_ibc_unshielding_transfer(&mut self) { - self.ibc_unshielding_transfer += 1 + pub fn increase_ibc_unshielding_transfer(&mut self, notes: u64) { + self.ibc_unshielding_transfer += notes } pub fn increase_ibc_msg_transfer(&mut self) { diff --git a/shared/src/transaction.rs b/shared/src/transaction.rs index a6360f10..e614a257 100644 --- a/shared/src/transaction.rs +++ b/shared/src/transaction.rs @@ -4,6 +4,7 @@ use std::fmt::Display; use namada_governance::{InitProposalData, VoteProposalData}; use namada_sdk::address::Address; use namada_sdk::borsh::BorshDeserialize; +use namada_sdk::events::extend::MaspTxRef; use namada_sdk::key::common::PublicKey; use namada_sdk::token::Transfer; use namada_sdk::uint::Uint; @@ -274,9 +275,8 @@ pub struct Transaction { } #[derive(Debug, Clone)] -pub struct Transaction2 { - pub wrapper: WrapperTransaction, - pub inners: InnerTransaction, +pub struct MaspSectionData { + pub total_notes: u64, } #[derive(Debug, Clone)] @@ -300,6 +300,7 @@ pub struct InnerTransaction { pub memo: Option, pub data: Option, pub extra_sections: HashMap>, + pub notes: u64, pub exit_code: TransactionExitStatus, } @@ -359,6 +360,8 @@ impl Transaction { let gas_used = block_results .gas_used(&wrapper_tx_id) .map(|gas| gas.parse::().unwrap()); + let masp_refs = + block_results.masp_refs(&wrapper_tx_id, index as u64); let fee = Fee { gas: Uint::from(wrapper.gas_limit).to_string(), @@ -459,6 +462,28 @@ impl Transaction { acc }); + let notes = masp_refs.clone().into_iter().map(|masp_ref| { + match masp_ref { + MaspTxRef::MaspSection(masp_tx_id) => { + transaction + .get_masp_section(&masp_tx_id) + .map(|bundle| bundle.clone().into_data().sapling_bundle().map(|bundle| bundle.shielded_spends.len() + bundle.shielded_outputs.len()).unwrap_or_default()).unwrap_or_default() as u64 + }, + MaspTxRef::IbcData(hash) => { + transaction.get_data_section(&hash).map(|section| match namada_sdk::ibc::decode_message::(§ion) { + Ok(namada_ibc::IbcMessage::Envelope(msg_envelope)) => { + if let Some(bundle) = namada_sdk::ibc::extract_masp_tx_from_envelope(&msg_envelope) { + bundle.clone().into_data().sapling_bundle().map(|bundle| bundle.shielded_spends.len() + bundle.shielded_outputs.len()).unwrap_or_default() as u64 + } else { + 0 + } + }, + _ => 0, + }).unwrap_or_default() + }, + } + }).sum::(); + let inner_tx = InnerTransaction { tx_id: inner_tx_id, index, @@ -466,6 +491,7 @@ impl Transaction { memo, data: encoded_tx_data, extra_sections, + notes, exit_code: inner_tx_status, kind: tx_kind, }; diff --git a/transactions/src/services/tx.rs b/transactions/src/services/tx.rs index 2c534a2d..0efb28eb 100644 --- a/transactions/src/services/tx.rs +++ b/transactions/src/services/tx.rs @@ -128,9 +128,12 @@ pub fn get_gas_estimates( && inner_tx.wrapper_id.eq(&wrapper_tx.tx_id) }) .for_each(|tx| match tx.kind { - TransactionKind::TransparentTransfer(_) - | TransactionKind::MixedTransfer(_) => { - gas_estimate.increase_mixed_transfer() + TransactionKind::TransparentTransfer(_) => { + gas_estimate.increase_transparent_transfer(); + } + TransactionKind::MixedTransfer(_) => { + let notes = tx.notes; + gas_estimate.increase_mixed_transfer(notes) } TransactionKind::IbcMsgTransfer(_) => { gas_estimate.increase_ibc_msg_transfer() @@ -155,16 +158,24 @@ pub fn get_gas_estimates( gas_estimate.increase_reveal_pk() } TransactionKind::ShieldedTransfer(_) => { - gas_estimate.increase_shielded_transfer() + let notes = tx.notes; + gas_estimate.increase_shielded_transfer(notes); } TransactionKind::ShieldingTransfer(_) => { - gas_estimate.increase_shielding_transfer() + let notes = tx.notes; + gas_estimate.increase_shielding_transfer(notes) } TransactionKind::UnshieldingTransfer(_) => { - gas_estimate.increase_ibc_unshielding_transfer() + let notes = tx.notes; + gas_estimate.increase_unshielding_transfer(notes) } TransactionKind::IbcShieldingTransfer(_) => { - gas_estimate.increase_ibc_shielding_transfer() + let notes = tx.notes; + gas_estimate.increase_ibc_shielding_transfer(notes) + } + TransactionKind::IbcUnshieldingTransfer(_) => { + let notes = tx.notes; + gas_estimate.increase_ibc_unshielding_transfer(notes) } _ => (), });