Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rpc): fill size field in getblock with verbosity=2 #9327

Merged
merged 2 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 31 additions & 30 deletions zebra-rpc/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,7 @@ pub trait Rpc {
///
/// # Notes
///
/// Zebra previously partially supported verbosity=1 by returning only the
/// fields required by lightwalletd ([`lightwalletd` only reads the `tx`
/// field of the result](https://github.com/zcash/lightwalletd/blob/dfac02093d85fb31fb9a8475b884dd6abca966c7/common/common.go#L152)).
/// That verbosity level was migrated to "3"; so while lightwalletd will
/// still work by using verbosity=1, it will sync faster if it is changed to
/// use verbosity=3.
/// The `size` field is only returned with verbosity=2.
///
/// The undocumented `chainwork` field is not returned.
#[method(name = "getblock")]
Expand Down Expand Up @@ -887,7 +882,7 @@ where

let transactions_request = match verbosity {
1 => zebra_state::ReadRequest::TransactionIdsForBlock(hash_or_height),
2 => zebra_state::ReadRequest::Block(hash_or_height),
2 => zebra_state::ReadRequest::BlockAndSize(hash_or_height),
_other => panic!("get_block_header_fut should be none"),
};

Expand Down Expand Up @@ -916,28 +911,34 @@ where
}

let tx_ids_response = futs.next().await.expect("`futs` should not be empty");
let tx: Vec<_> = match tx_ids_response.map_misc_error()? {
zebra_state::ReadResponse::TransactionIdsForBlock(tx_ids) => tx_ids
.ok_or_misc_error("block not found")?
.iter()
.map(|tx_id| GetBlockTransaction::Hash(*tx_id))
.collect(),
zebra_state::ReadResponse::Block(block) => block
.ok_or_misc_error("Block not found")?
.transactions
.iter()
.map(|tx| {
GetBlockTransaction::Object(TransactionObject::from_transaction(
tx.clone(),
Some(height),
Some(
confirmations
.try_into()
.expect("should be less than max block height, i32::MAX"),
),
))
})
.collect(),
let (tx, size): (Vec<_>, Option<usize>) = match tx_ids_response.map_misc_error()? {
zebra_state::ReadResponse::TransactionIdsForBlock(tx_ids) => (
tx_ids
.ok_or_misc_error("block not found")?
.iter()
.map(|tx_id| GetBlockTransaction::Hash(*tx_id))
.collect(),
None,
),
zebra_state::ReadResponse::BlockAndSize(block_and_size) => {
let (block, size) = block_and_size.ok_or_misc_error("Block not found")?;
let transactions = block
.transactions
.iter()
.map(|tx| {
GetBlockTransaction::Object(TransactionObject::from_transaction(
tx.clone(),
Some(height),
Some(
confirmations
.try_into()
.expect("should be less than max block height, i32::MAX"),
),
))
})
.collect();
(transactions, Some(size))
}
_ => unreachable!("unmatched response to a transaction_ids_for_block request"),
};

Expand Down Expand Up @@ -984,7 +985,7 @@ where
difficulty: Some(difficulty),
tx,
trees,
size: None,
size: size.map(|size| size as i64),
block_commitments: Some(block_commitments),
final_sapling_root: Some(final_sapling_root),
final_orchard_root,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: block
{
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
"confirmations": 10,
"size": 1617,
"height": 1,
"version": 4,
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: block
{
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
"confirmations": 10,
"size": 1618,
"height": 1,
"version": 4,
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: block
{
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
"confirmations": 10,
"size": 1617,
"height": 1,
"version": 4,
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: block
{
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
"confirmations": 10,
"size": 1618,
"height": 1,
"version": 4,
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
Expand Down
4 changes: 2 additions & 2 deletions zebra-rpc/src/methods/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ async fn rpc_getblock() {
}))
.collect(),
trees,
size: None,
size: Some(block.zcash_serialize_to_vec().unwrap().len() as i64),
version: Some(block.header.version),
merkle_root: Some(block.header.merkle_root),
block_commitments: Some(expected_block_commitments),
Expand Down Expand Up @@ -364,7 +364,7 @@ async fn rpc_getblock() {
}))
.collect(),
trees,
size: None,
size: Some(block.zcash_serialize_to_vec().unwrap().len() as i64),
version: Some(block.header.version),
merkle_root: Some(block.header.merkle_root),
block_commitments: Some(expected_block_commitments),
Expand Down
4 changes: 3 additions & 1 deletion zebra-state/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ pub use request::Spend;
pub use response::{GetBlockTemplateChainInfo, KnownBlock, MinedTx, ReadResponse, Response};
pub use service::{
chain_tip::{ChainTipBlock, ChainTipChange, ChainTipSender, LatestChainTip, TipAction},
check, init, init_read_only,
check,
finalized_state::FinalizedState,
init, init_read_only,
non_finalized_state::NonFinalizedState,
spawn_init, spawn_init_read_only,
watch_receiver::WatchReceiver,
Expand Down
19 changes: 19 additions & 0 deletions zebra-state/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,14 @@ pub enum Request {
/// [`block::Height`] using `.into()`.
Block(HashOrHeight),

//// Same as Block, but also returns serialized block size.
////
/// Returns
///
/// * [`ReadResponse::BlockAndSize(Some((Arc<Block>, usize)))`](ReadResponse::BlockAndSize) if the block is in the best chain;
/// * [`ReadResponse::BlockAndSize(None)`](ReadResponse::BlockAndSize) otherwise.
BlockAndSize(HashOrHeight),

/// Looks up a block header by hash or height in the current best chain.
///
/// Returns
Expand Down Expand Up @@ -837,6 +845,7 @@ impl Request {
Request::Transaction(_) => "transaction",
Request::UnspentBestChainUtxo { .. } => "unspent_best_chain_utxo",
Request::Block(_) => "block",
Request::BlockAndSize(_) => "block_and_size",
Request::BlockHeader(_) => "block_header",
Request::FindBlockHashes { .. } => "find_block_hashes",
Request::FindBlockHeaders { .. } => "find_block_headers",
Expand Down Expand Up @@ -897,6 +906,14 @@ pub enum ReadRequest {
/// [`block::Height`] using `.into()`.
Block(HashOrHeight),

//// Same as Block, but also returns serialized block size.
////
/// Returns
///
/// * [`ReadResponse::BlockAndSize(Some((Arc<Block>, usize)))`](ReadResponse::BlockAndSize) if the block is in the best chain;
/// * [`ReadResponse::BlockAndSize(None)`](ReadResponse::BlockAndSize) otherwise.
BlockAndSize(HashOrHeight),

/// Looks up a block header by hash or height in the current best chain.
///
/// Returns
Expand Down Expand Up @@ -1143,6 +1160,7 @@ impl ReadRequest {
ReadRequest::TipPoolValues => "tip_pool_values",
ReadRequest::Depth(_) => "depth",
ReadRequest::Block(_) => "block",
ReadRequest::BlockAndSize(_) => "block_and_size",
ReadRequest::BlockHeader(_) => "block_header",
ReadRequest::Transaction(_) => "transaction",
ReadRequest::TransactionIdsForBlock(_) => "transaction_ids_for_block",
Expand Down Expand Up @@ -1200,6 +1218,7 @@ impl TryFrom<Request> for ReadRequest {
Request::BestChainBlockHash(hash) => Ok(ReadRequest::BestChainBlockHash(hash)),

Request::Block(hash_or_height) => Ok(ReadRequest::Block(hash_or_height)),
Request::BlockAndSize(hash_or_height) => Ok(ReadRequest::BlockAndSize(hash_or_height)),
Request::BlockHeader(hash_or_height) => Ok(ReadRequest::BlockHeader(hash_or_height)),
Request::Transaction(tx_hash) => Ok(ReadRequest::Transaction(tx_hash)),
Request::UnspentBestChainUtxo(outpoint) => {
Expand Down
8 changes: 8 additions & 0 deletions zebra-state/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ pub enum Response {
/// Response to [`Request::Block`] with the specified block.
Block(Option<Arc<Block>>),

/// Response to [`Request::BlockAndSize`] with the specified block and size.
BlockAndSize(Option<(Arc<Block>, usize)>),

/// The response to a `BlockHeader` request.
BlockHeader {
/// The header of the requested block
Expand Down Expand Up @@ -157,6 +160,10 @@ pub enum ReadResponse {
/// Response to [`ReadRequest::Block`] with the specified block.
Block(Option<Arc<Block>>),

/// Response to [`ReadRequest::BlockAndSize`] with the specified block and
/// serialized size.
BlockAndSize(Option<(Arc<Block>, usize)>),

/// The response to a `BlockHeader` request.
BlockHeader {
/// The header of the requested block
Expand Down Expand Up @@ -311,6 +318,7 @@ impl TryFrom<ReadResponse> for Response {
ReadResponse::BlockHash(hash) => Ok(Response::BlockHash(hash)),

ReadResponse::Block(block) => Ok(Response::Block(block)),
ReadResponse::BlockAndSize(block) => Ok(Response::BlockAndSize(block)),
ReadResponse::BlockHeader {
header,
hash,
Expand Down
26 changes: 26 additions & 0 deletions zebra-state/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,7 @@ impl Service<Request> for StateService {
| Request::Transaction(_)
| Request::UnspentBestChainUtxo(_)
| Request::Block(_)
| Request::BlockAndSize(_)
| Request::BlockHeader(_)
| Request::FindBlockHashes { .. }
| Request::FindBlockHeaders { .. }
Expand Down Expand Up @@ -1311,6 +1312,31 @@ impl Service<ReadRequest> for ReadStateService {
.wait_for_panics()
}

// Used by the get_block (raw) RPC and the StateService.
ReadRequest::BlockAndSize(hash_or_height) => {
let state = self.clone();

tokio::task::spawn_blocking(move || {
span.in_scope(move || {
let block_and_size = state.non_finalized_state_receiver.with_watch_data(
|non_finalized_state| {
read::block_and_size(
non_finalized_state.best_chain(),
&state.db,
hash_or_height,
)
},
);

// The work is done in the future.
timer.finish(module_path!(), line!(), "ReadRequest::BlockAndSize");

Ok(ReadResponse::BlockAndSize(block_and_size))
})
})
.wait_for_panics()
}

// Used by the get_block (verbose) RPC and the StateService.
ReadRequest::BlockHeader(hash_or_height) => {
let state = self.clone();
Expand Down
Loading
Loading