From fe35d9b7439f5843962b66a503842ddde23085e0 Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 9 Dec 2022 13:45:59 +1000 Subject: [PATCH] Split default root calculation into a separate function --- .../src/methods/get_block_template_rpcs.rs | 48 +++++++------------ .../get_block_template.rs | 33 +++++++++++-- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/zebra-rpc/src/methods/get_block_template_rpcs.rs b/zebra-rpc/src/methods/get_block_template_rpcs.rs index ad2d3e42cb3..da4efa7c8b6 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs.rs @@ -8,10 +8,7 @@ use jsonrpc_derive::rpc; use tower::{buffer::Buffer, Service, ServiceExt}; use zebra_chain::{ - block::{ - self, Block, ChainHistoryBlockTxAuthCommitmentHash, Height, MAX_BLOCK_BYTES, - ZCASH_BLOCK_VERSION, - }, + block::{self, Block, Height, MAX_BLOCK_BYTES, ZCASH_BLOCK_VERSION}, chain_sync_status::ChainSyncStatus, chain_tip::ChainTip, parameters::Network, @@ -30,14 +27,13 @@ use crate::methods::{ GET_BLOCK_TEMPLATE_MUTABLE_FIELD, GET_BLOCK_TEMPLATE_NONCE_RANGE_FIELD, }, get_block_template::{ - calculate_miner_fee, calculate_transaction_roots, check_address, + calculate_default_root_hashes, calculate_miner_fee, check_address, check_block_template_parameters, check_synced_to_tip, fetch_mempool_transactions, fetch_state_tip_and_local_time, generate_coinbase_transaction, }, types::{ - default_roots::DefaultRoots, get_block_template::GetBlockTemplate, get_mining_info, - hex_data::HexData, long_poll::LongPollInput, submit_block, - transaction::TransactionTemplate, + get_block_template::GetBlockTemplate, get_mining_info, hex_data::HexData, + long_poll::LongPollInput, submit_block, transaction::TransactionTemplate, }, }, height_from_signed_int, GetBlockHash, MISSING_BLOCK_ERROR_CODE, @@ -375,6 +371,7 @@ where // // Apart from random weighted transaction selection, // the template only depends on the previously fetched data. + // This processing never fails. // Calculate the next block height. let next_block_height = @@ -396,25 +393,19 @@ where let coinbase_tx = generate_coinbase_transaction(network, next_block_height, miner_address, miner_fee); - // TODO: move into a new block_roots() - + // Calculate block default roots + // // TODO: move expensive root, hash, and tree cryptography to a rayon thread? - let (merkle_root, auth_data_root) = - calculate_transaction_roots(&coinbase_tx, &mempool_txs); - - let history_tree = chain_tip_and_local_time.history_tree; - let chain_history_root = history_tree.hash().expect("history tree can't be empty"); - - let block_commitments_hash = ChainHistoryBlockTxAuthCommitmentHash::from_commitments( - &chain_history_root, - &auth_data_root, + let default_roots = calculate_default_root_hashes( + &coinbase_tx, + &mempool_txs, + chain_tip_and_local_time.history_tree, ); - // Convert into TransactionTemplates + // Convert transactions into TransactionTemplates let mempool_txs = mempool_txs.iter().map(Into::into).collect(); - // TODO: make these serialize without this complex code? - + // TODO: move this conversion into a separate function? let capabilities: Vec = GET_BLOCK_TEMPLATE_CAPABILITIES_FIELD .iter() .map(ToString::to_string) @@ -430,15 +421,10 @@ where version: ZCASH_BLOCK_VERSION, previous_block_hash: GetBlockHash(chain_tip_and_local_time.tip_hash), - block_commitments_hash, - light_client_root_hash: block_commitments_hash, - final_sapling_root_hash: block_commitments_hash, - default_roots: DefaultRoots { - merkle_root, - chain_history_root, - auth_data_root, - block_commitments_hash, - }, + block_commitments_hash: default_roots.block_commitments_hash, + light_client_root_hash: default_roots.block_commitments_hash, + final_sapling_root_hash: default_roots.block_commitments_hash, + default_roots, transactions: mempool_txs, diff --git a/zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs b/zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs index e29650e6db4..b771c43f96a 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs @@ -1,6 +1,6 @@ //! Support functions for the `get_block_template()` RPC. -use std::iter; +use std::{iter, sync::Arc}; use jsonrpc_core::{Error, ErrorCode, Result}; use tower::{Service, ServiceExt}; @@ -9,7 +9,7 @@ use zebra_chain::{ amount::{self, Amount, NonNegative}, block::{ merkle::{self, AuthDataRoot}, - Height, + ChainHistoryBlockTxAuthCommitmentHash, Height, }, chain_sync_status::ChainSyncStatus, chain_tip::ChainTip, @@ -23,7 +23,7 @@ use zebra_state::GetBlockTemplateChainInfo; use crate::methods::get_block_template_rpcs::{ constants::{MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP, NOT_SYNCED_ERROR_CODE}, - types::get_block_template, + types::{default_roots::DefaultRoots, get_block_template}, }; pub use crate::methods::get_block_template_rpcs::types::get_block_template::*; @@ -234,6 +234,33 @@ pub fn standard_coinbase_outputs( // - Transaction roots processing +/// Returns the default block roots for the supplied coinbase and mempool transactions, +/// and the supplied history tree. +/// +/// This function runs expensive cryptographic operations. +pub fn calculate_default_root_hashes( + coinbase_tx: &UnminedTx, + mempool_txs: &[VerifiedUnminedTx], + history_tree: Arc, +) -> DefaultRoots { + let (merkle_root, auth_data_root) = calculate_transaction_roots(coinbase_tx, mempool_txs); + + let history_tree = history_tree; + let chain_history_root = history_tree.hash().expect("history tree can't be empty"); + + let block_commitments_hash = ChainHistoryBlockTxAuthCommitmentHash::from_commitments( + &chain_history_root, + &auth_data_root, + ); + + DefaultRoots { + merkle_root, + chain_history_root, + auth_data_root, + block_commitments_hash, + } +} + /// Returns the transaction effecting and authorizing roots /// for `coinbase_tx` and `mempool_txs`, which are used in the block header. //