From 8596adb836d92c7e91cc1206313b8ca923cb103f Mon Sep 17 00:00:00 2001 From: Neotamandua <107320179+Neotamandua@users.noreply.github.com> Date: Fri, 20 Dec 2024 19:27:12 +0200 Subject: [PATCH] rusk: adjust moonlight endpoints to contain ledger tx data --- .../lib/http/chain/graphql/archive/data.rs | 61 ++++++++++++++++++- .../http/chain/graphql/archive/moonlight.rs | 26 +++++++- rusk/src/lib/http/chain/graphql/data.rs | 5 ++ rusk/src/lib/http/chain/graphql/tx.rs | 12 ++++ 4 files changed, 99 insertions(+), 5 deletions(-) diff --git a/rusk/src/lib/http/chain/graphql/archive/data.rs b/rusk/src/lib/http/chain/graphql/archive/data.rs index 3eeb6143d..abbe4da76 100644 --- a/rusk/src/lib/http/chain/graphql/archive/data.rs +++ b/rusk/src/lib/http/chain/graphql/archive/data.rs @@ -8,8 +8,65 @@ use async_graphql::Object; use dusk_bytes::Serializable; use dusk_core::signatures::bls::PublicKey as AccountPublicKey; use node::archive::MoonlightGroup; +use serde::Serialize; +use tracing::error; -pub struct MoonlightTransfers(pub Vec); +use crate::http::chain::graphql::data::SpentTransaction; + +/// Struct containing all information about a Moonlight transfer. +/// +/// # Private Fields +/// +/// - `moonlight_group`: A `MoonlightGroup` of events that belong to the same +/// Moonlight transaction. +/// - `spent_transaction`: The `SpentTransaction` of the Moonlight transaction. +pub struct MoonlightTransfers { + moonlight_group: Vec, + spent_transaction: Vec, +} + +impl MoonlightTransfers { + /// Create a new `MoonlightTransfers` instance. + /// + /// # Arguments + /// + /// - `moonlight_group`: A group of events that belong to the same Moonlight + /// transaction. + /// - `spent_transaction`: The payload of the Moonlight transaction. + /// + /// # Note + /// + /// Both fields are expected to correspond to each other i.e., the first + /// element of `moonlight_group` corresponds to the first element of + /// `spent_transaction`. + /// + /// That means that the n-th element of `moonlight_group` belongs to the + /// same transaction as the n-th element of `spent_transaction`. + pub(crate) fn new( + moonlight_group: Vec, + spent_transaction: Vec, + ) -> Self { + Self { + moonlight_group, + spent_transaction, + } + } +} + +impl Serialize for MoonlightTransfers { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let zipped = &self + .moonlight_group + .iter() + .zip(&self.spent_transaction) + .collect::>(); + + zipped.serialize(serializer) + } +} pub struct ContractEvents(pub(super) serde_json::Value); @@ -34,7 +91,7 @@ impl TryInto for String { #[Object] impl MoonlightTransfers { pub async fn json(&self) -> serde_json::Value { - serde_json::to_value(&self.0).unwrap_or_default() + serde_json::to_value(self).unwrap_or_default() } } diff --git a/rusk/src/lib/http/chain/graphql/archive/moonlight.rs b/rusk/src/lib/http/chain/graphql/archive/moonlight.rs index 3d752bedc..8a18ec9ab 100644 --- a/rusk/src/lib/http/chain/graphql/archive/moonlight.rs +++ b/rusk/src/lib/http/chain/graphql/archive/moonlight.rs @@ -20,7 +20,7 @@ use async_graphql::{Context, FieldError}; use super::data::deserialized_archive_data::*; use super::data::{MoonlightTransfers, NewAccountPublicKey}; -use crate::http::chain::graphql::{DBContext, OptResult}; +use crate::http::chain::graphql::{tx, DBContext, OptResult}; pub async fn full_moonlight_history( ctx: &Context<'_>, @@ -95,7 +95,7 @@ pub async fn fetch_moonlight_history( if let Some(moonlight_events) = archive.fetch_moonlight_history( sender, receiver, from_block, to_block, max_count, page_count, )? { - Ok(Some(MoonlightTransfers(moonlight_events))) + aggregate_moonlight_transfers(ctx, moonlight_events).await } else { Ok(None) } @@ -110,8 +110,28 @@ pub async fn moonlight_tx_by_memo( let moonlight_events = archive.moonlight_txs_by_memo(memo)?; if let Some(moonlight_events) = moonlight_events { - Ok(Some(MoonlightTransfers(moonlight_events))) + aggregate_moonlight_transfers(ctx, moonlight_events).await } else { Ok(None) } } + +async fn aggregate_moonlight_transfers( + ctx: &Context<'_>, + moonlight_groups: Vec, +) -> OptResult { + let spent_moonlight_tx = { + let moonlight_origins_by_ref: Vec<&[u8; 32]> = moonlight_groups + .iter() + .map(|event| event.origin()) + .collect::>(); + + // multi get SpentTransaction + tx::txs_by_hashes(ctx, moonlight_origins_by_ref).await? + }; + + Ok(Some(MoonlightTransfers::new( + moonlight_groups, + spent_moonlight_tx, + ))) +} diff --git a/rusk/src/lib/http/chain/graphql/data.rs b/rusk/src/lib/http/chain/graphql/data.rs index f6e9c9a9e..f7bfbe279 100644 --- a/rusk/src/lib/http/chain/graphql/data.rs +++ b/rusk/src/lib/http/chain/graphql/data.rs @@ -46,6 +46,7 @@ impl Block { } pub struct Header<'a>(&'a node_data::ledger::Header); +#[derive(Serialize)] pub struct SpentTransaction(pub node_data::ledger::SpentTransaction); pub struct Transaction<'a>(TransactionData<'a>); @@ -188,6 +189,10 @@ impl Header<'_> { #[Object] impl SpentTransaction { + pub async fn json(&self) -> serde_json::Value { + serde_json::to_value(&self.0).unwrap_or_default() + } + pub async fn tx(&self) -> Transaction { let inner = &self.0.inner; inner.into() diff --git a/rusk/src/lib/http/chain/graphql/tx.rs b/rusk/src/lib/http/chain/graphql/tx.rs index 555f74a36..f0387dfba 100644 --- a/rusk/src/lib/http/chain/graphql/tx.rs +++ b/rusk/src/lib/http/chain/graphql/tx.rs @@ -18,6 +18,18 @@ pub async fn tx_by_hash( Ok(tx.map(SpentTransaction)) } +pub async fn txs_by_hashes( + ctx: &Context<'_>, + hashes: Vec<&[u8; 32]>, +) -> FieldResult> { + let (db, _) = ctx.data::()?; + db.read().await.view(|t| { + let txs = t.ledger_txs(hashes)?; + + Ok(txs.into_iter().map(SpentTransaction).collect::>()) + }) +} + pub async fn last_transactions( ctx: &Context<'_>, count: usize,