From af80f39586f2e9fdfa38eaab0585682981d38f3d Mon Sep 17 00:00:00 2001 From: nelsonksh Date: Sun, 12 Oct 2025 21:29:03 +0530 Subject: [PATCH 1/6] feat(utxorpc): add block to WatchTx --- src/serve/grpc/watch.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index 2a5e8b3f1..ab096a9b3 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -164,8 +164,12 @@ fn block_to_txs( }) .map(|x| u5c::watch::AnyChainTx { chain: Some(u5c::watch::any_chain_tx::Chain::Cardano(x)), - // TODO(p): should it be none? - block: None, + block: Some(u5c::watch::AnyChainBlock { + native_bytes: body.to_vec().into(), + chain: Some(u5c::watch::any_chain_block::Chain::Cardano( + mapper.map_block_cbor(body), + )), + }), }) .collect() } From 2469b0672fceb5d5939b967b7941c8b722936fad Mon Sep 17 00:00:00 2001 From: nelsonksh <150728524+nelsonksh@users.noreply.github.com> Date: Tue, 14 Oct 2025 03:22:55 +0530 Subject: [PATCH 2/6] Add block body reference in watch.rs --- src/serve/grpc/watch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index ab096a9b3..b8b903fa5 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -151,6 +151,7 @@ fn block_to_txs( mapper: &interop::Mapper, request: &u5c::watch::WatchTxRequest, ) -> Vec { + let body: &BlockBody = █ let block = MultiEraBlock::decode(block).unwrap(); let txs = block.txs(); From 93b333f76dcc5d7d4d6602235413eec0516594d4 Mon Sep 17 00:00:00 2001 From: nelsonksh Date: Tue, 3 Mar 2026 06:59:48 +0000 Subject: [PATCH 3/6] feat(utxorpc): optionally embed block in WatchTx based on field_mask --- src/serve/grpc/watch.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index 083c07601..254626828 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -147,12 +147,16 @@ fn apply_predicate(predicate: &u5c::watch::TxPredicate, tx: &u5c::cardano::Tx) - } fn block_to_txs( - block: &RawBlock, + raw_block: &RawBlock, mapper: &interop::Mapper, request: &u5c::watch::WatchTxRequest, ) -> Vec { - let body: &BlockBody = █ - let block = MultiEraBlock::decode(block).unwrap(); + let include_block = request.field_mask.as_ref().map_or(false, |mask| { + mask.paths.iter().any(|p| p.contains("block")) + }); + + let body: &BlockBody = &raw_block; + let block = MultiEraBlock::decode(raw_block).unwrap(); let txs = block.txs(); txs.iter() @@ -165,12 +169,16 @@ fn block_to_txs( }) .map(|x| u5c::watch::AnyChainTx { chain: Some(u5c::watch::any_chain_tx::Chain::Cardano(x)), - block: Some(u5c::watch::AnyChainBlock { - native_bytes: body.to_vec().into(), - chain: Some(u5c::watch::any_chain_block::Chain::Cardano( - mapper.map_block_cbor(body), - )), - }), + block: if include_block { + Some(u5c::watch::AnyChainBlock { + native_bytes: body.to_vec().into(), + chain: Some(u5c::watch::any_chain_block::Chain::Cardano( + mapper.map_block_cbor(body), + )), + }) + } else { + None + }, }) .collect() } From e031952022301bf0bbde3f8b597da618f1d3dc36 Mon Sep 17 00:00:00 2001 From: nelsonksh Date: Tue, 3 Mar 2026 07:19:42 +0000 Subject: [PATCH 4/6] refactor(utxorpc): address coderabbit review on WatchTx field mask --- src/serve/grpc/watch.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index 254626828..13fb88adc 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -152,11 +152,19 @@ fn block_to_txs( request: &u5c::watch::WatchTxRequest, ) -> Vec { let include_block = request.field_mask.as_ref().map_or(false, |mask| { - mask.paths.iter().any(|p| p.contains("block")) + mask.paths.iter().any(|p| p == "block" || p.starts_with("block.")) }); let body: &BlockBody = &raw_block; let block = MultiEraBlock::decode(raw_block).unwrap(); + + let mapped_block = include_block.then(|| u5c::watch::AnyChainBlock { + native_bytes: body.to_vec().into(), + chain: Some(u5c::watch::any_chain_block::Chain::Cardano( + mapper.map_block_cbor(body), + )), + }); + let txs = block.txs(); txs.iter() @@ -169,16 +177,7 @@ fn block_to_txs( }) .map(|x| u5c::watch::AnyChainTx { chain: Some(u5c::watch::any_chain_tx::Chain::Cardano(x)), - block: if include_block { - Some(u5c::watch::AnyChainBlock { - native_bytes: body.to_vec().into(), - chain: Some(u5c::watch::any_chain_block::Chain::Cardano( - mapper.map_block_cbor(body), - )), - }) - } else { - None - }, + block: mapped_block.clone(), }) .collect() } From eb4356b134b8b46cfbf325cb09c507dda443a970 Mon Sep 17 00:00:00 2001 From: nelsonksh Date: Tue, 3 Mar 2026 07:50:46 +0000 Subject: [PATCH 5/6] fix(utxorpc): avoid panic on block decode in WatchTx --- src/serve/grpc/watch.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index 13fb88adc..c1da3bc56 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -156,7 +156,13 @@ fn block_to_txs( }); let body: &BlockBody = &raw_block; - let block = MultiEraBlock::decode(raw_block).unwrap(); + let block = match MultiEraBlock::decode(raw_block) { + Ok(b) => b, + Err(e) => { + tracing::warn!(error = %e, "Failed to decode block in WatchTx"); + return vec![]; + } + }; let mapped_block = include_block.then(|| u5c::watch::AnyChainBlock { native_bytes: body.to_vec().into(), From 4a87268acb81af271600d0262acefd0781538605 Mon Sep 17 00:00:00 2001 From: nelsonksh Date: Tue, 3 Mar 2026 08:20:34 +0000 Subject: [PATCH 6/6] style(utxorpc): resolve clippy warnings for WatchTx field mask --- src/serve/grpc/watch.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/serve/grpc/watch.rs b/src/serve/grpc/watch.rs index c1da3bc56..96e1768e5 100644 --- a/src/serve/grpc/watch.rs +++ b/src/serve/grpc/watch.rs @@ -151,11 +151,11 @@ fn block_to_txs( mapper: &interop::Mapper, request: &u5c::watch::WatchTxRequest, ) -> Vec { - let include_block = request.field_mask.as_ref().map_or(false, |mask| { + let include_block = request.field_mask.as_ref().is_some_and(|mask| { mask.paths.iter().any(|p| p == "block" || p.starts_with("block.")) }); - let body: &BlockBody = &raw_block; + let body: &BlockBody = raw_block; let block = match MultiEraBlock::decode(raw_block) { Ok(b) => b, Err(e) => {