diff --git a/Cargo.lock b/Cargo.lock index 68b48ccf8..40088ac66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4158,6 +4158,7 @@ dependencies = [ "logos-blockchain-wallet-service", "multiaddr", "overwatch", + "serde", "serde_json", "serde_yaml", "tempfile", diff --git a/c-bindings/Cargo.toml b/c-bindings/Cargo.toml index 315d9f445..c65707167 100644 --- a/c-bindings/Cargo.toml +++ b/c-bindings/Cargo.toml @@ -22,6 +22,7 @@ lb-utils = { workspace = true } lb-wallet-service = { workspace = true } multiaddr = { workspace = true } overwatch = { workspace = true } +serde = { features = ["derive"], workspace = true } serde_json = { workspace = true } tempfile = { workspace = true } tokio = { features = ["rt-multi-thread"], workspace = true } diff --git a/c-bindings/src/api/subscriptions.rs b/c-bindings/src/api/subscriptions.rs index dfc6f2b4d..b0e2f0c80 100644 --- a/c-bindings/src/api/subscriptions.rs +++ b/c-bindings/src/api/subscriptions.rs @@ -2,11 +2,15 @@ use std::ffi::c_char; use lb_api_service::http::storage::StorageAdapter as _; use lb_chain_service::api::CryptarchiaServiceApi; -use lb_core::block::Block as CoreBlock; +use lb_core::{ + block::Block as CoreBlock, + mantle::{StorageSize, Transaction, TransactionHasher, TxHash}, +}; use lb_node::{ ApiStorageAdapter, RuntimeServiceId, SignedMantleTx, StorageService, generic_services::CryptarchiaService, }; +use serde::Serialize; use crate::{ LogosBlockchainNode, OperationStatus, @@ -15,6 +19,29 @@ use crate::{ logging, return_error_if_null_pointer, }; +#[derive(Serialize)] +#[serde(rename = "SignedMantleTx")] +pub struct TxWithId { + id: TxHash, + #[serde(flatten)] + tx: SignedMantleTx, +} + +impl Transaction for TxWithId { + const HASHER: TransactionHasher = |tx| ::HASHER(&tx.tx); + type Hash = ::Hash; + + fn as_signing(&self) -> Vec { + self.tx.as_signing() + } +} + +impl StorageSize for TxWithId { + fn storage_size(&self) -> usize { + self.tx.storage_size() + } +} + pub fn subscribe_to_new_blocks_sync( node: &LogosBlockchainNode, mut callback_per_block: BoxedCallback<*const c_char>, @@ -52,6 +79,19 @@ pub fn subscribe_to_new_blocks_sync( ApiStorageAdapter::::get_block(relay, event.block_id) .await; if let Ok(Some(block)) = res { + let txs_with_id: Vec = block + .transactions() + .map(|tx| TxWithId { + id: tx.hash(), + tx: tx.clone(), + }) + .collect(); + let block: CoreBlock = CoreBlock::reconstruct( + block.header().clone(), + txs_with_id, + *block.signature(), + ) + .expect("Block should always build from valid block"); callback_per_block(Block::from(block).as_ptr()); } else { logging::error!( diff --git a/c-bindings/src/api/types/block.rs b/c-bindings/src/api/types/block.rs index d9f266d60..3a8505313 100644 --- a/c-bindings/src/api/types/block.rs +++ b/c-bindings/src/api/types/block.rs @@ -1,6 +1,8 @@ use std::ffi::{CString, c_char}; -use lb_core::{block::Block as CoreBlock, mantle::SignedMantleTx}; +use lb_core::block::Block as CoreBlock; + +use crate::api::subscriptions::TxWithId; #[repr(C)] pub struct Block(CString); // JSON representation of a block @@ -11,8 +13,8 @@ impl Block { } } -impl From> for Block { - fn from(value: CoreBlock) -> Self { +impl From> for Block { + fn from(value: CoreBlock) -> Self { Self( CString::new( serde_json::to_string(&value)