sorts mempool_txs before generating merkle root (#5953)
This commit is contained in:
parent
7b7569c904
commit
a8bfb1b8dc
|
|
@ -27,7 +27,7 @@ use crate::methods::{
|
||||||
},
|
},
|
||||||
get_block_template::{
|
get_block_template::{
|
||||||
check_miner_address, check_synced_to_tip, fetch_mempool_transactions,
|
check_miner_address, check_synced_to_tip, fetch_mempool_transactions,
|
||||||
fetch_state_tip_and_local_time, generate_coinbase_and_roots, validate_block_proposal,
|
fetch_state_tip_and_local_time, validate_block_proposal,
|
||||||
},
|
},
|
||||||
types::{
|
types::{
|
||||||
get_block_template::GetBlockTemplate, get_mining_info, hex_data::HexData,
|
get_block_template::GetBlockTemplate, get_mining_info, hex_data::HexData,
|
||||||
|
|
@ -566,24 +566,12 @@ where
|
||||||
|
|
||||||
// - After this point, the template only depends on the previously fetched data.
|
// - After this point, the template only depends on the previously fetched data.
|
||||||
|
|
||||||
// Generate the coinbase transaction and default roots
|
|
||||||
//
|
|
||||||
// TODO: move expensive root, hash, and tree cryptography to a rayon thread?
|
|
||||||
let (coinbase_txn, default_roots) = generate_coinbase_and_roots(
|
|
||||||
network,
|
|
||||||
next_block_height,
|
|
||||||
miner_address,
|
|
||||||
&mempool_txs,
|
|
||||||
chain_tip_and_local_time.history_tree.clone(),
|
|
||||||
COINBASE_LIKE_ZCASHD,
|
|
||||||
);
|
|
||||||
|
|
||||||
let response = GetBlockTemplate::new(
|
let response = GetBlockTemplate::new(
|
||||||
|
network,
|
||||||
|
miner_address,
|
||||||
&chain_tip_and_local_time,
|
&chain_tip_and_local_time,
|
||||||
server_long_poll_id,
|
server_long_poll_id,
|
||||||
coinbase_txn,
|
mempool_txs,
|
||||||
&mempool_txs,
|
|
||||||
default_roots,
|
|
||||||
submit_old,
|
submit_old,
|
||||||
COINBASE_LIKE_ZCASHD,
|
COINBASE_LIKE_ZCASHD,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@
|
||||||
use zebra_chain::{
|
use zebra_chain::{
|
||||||
amount,
|
amount,
|
||||||
block::{ChainHistoryBlockTxAuthCommitmentHash, MAX_BLOCK_BYTES, ZCASH_BLOCK_VERSION},
|
block::{ChainHistoryBlockTxAuthCommitmentHash, MAX_BLOCK_BYTES, ZCASH_BLOCK_VERSION},
|
||||||
|
parameters::Network,
|
||||||
serialization::DateTime32,
|
serialization::DateTime32,
|
||||||
transaction::VerifiedUnminedTx,
|
transaction::VerifiedUnminedTx,
|
||||||
|
transparent,
|
||||||
work::difficulty::{CompactDifficulty, ExpandedDifficulty},
|
work::difficulty::{CompactDifficulty, ExpandedDifficulty},
|
||||||
};
|
};
|
||||||
use zebra_consensus::MAX_BLOCK_SIGOPS;
|
use zebra_consensus::MAX_BLOCK_SIGOPS;
|
||||||
|
|
@ -16,6 +18,7 @@ use crate::methods::{
|
||||||
GET_BLOCK_TEMPLATE_CAPABILITIES_FIELD, GET_BLOCK_TEMPLATE_MUTABLE_FIELD,
|
GET_BLOCK_TEMPLATE_CAPABILITIES_FIELD, GET_BLOCK_TEMPLATE_MUTABLE_FIELD,
|
||||||
GET_BLOCK_TEMPLATE_NONCE_RANGE_FIELD,
|
GET_BLOCK_TEMPLATE_NONCE_RANGE_FIELD,
|
||||||
},
|
},
|
||||||
|
get_block_template::generate_coinbase_and_roots,
|
||||||
types::{
|
types::{
|
||||||
default_roots::DefaultRoots, long_poll::LongPollId, transaction::TransactionTemplate,
|
default_roots::DefaultRoots, long_poll::LongPollId, transaction::TransactionTemplate,
|
||||||
},
|
},
|
||||||
|
|
@ -177,11 +180,11 @@ impl GetBlockTemplate {
|
||||||
/// If `like_zcashd` is true, try to match the coinbase transactions generated by `zcashd`
|
/// If `like_zcashd` is true, try to match the coinbase transactions generated by `zcashd`
|
||||||
/// in the `getblocktemplate` RPC.
|
/// in the `getblocktemplate` RPC.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
network: Network,
|
||||||
|
miner_address: transparent::Address,
|
||||||
chain_tip_and_local_time: &GetBlockTemplateChainInfo,
|
chain_tip_and_local_time: &GetBlockTemplateChainInfo,
|
||||||
long_poll_id: LongPollId,
|
long_poll_id: LongPollId,
|
||||||
coinbase_txn: TransactionTemplate<amount::NegativeOrZero>,
|
mempool_txs: Vec<VerifiedUnminedTx>,
|
||||||
mempool_txs: &[VerifiedUnminedTx],
|
|
||||||
default_roots: DefaultRoots,
|
|
||||||
submit_old: Option<bool>,
|
submit_old: Option<bool>,
|
||||||
like_zcashd: bool,
|
like_zcashd: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -190,20 +193,41 @@ impl GetBlockTemplate {
|
||||||
(chain_tip_and_local_time.tip_height + 1).expect("tip is far below Height::MAX");
|
(chain_tip_and_local_time.tip_height + 1).expect("tip is far below Height::MAX");
|
||||||
|
|
||||||
// Convert transactions into TransactionTemplates
|
// Convert transactions into TransactionTemplates
|
||||||
let mut mempool_txs: Vec<TransactionTemplate<amount::NonNegative>> =
|
let mut mempool_txs_with_templates: Vec<(
|
||||||
mempool_txs.iter().map(Into::into).collect();
|
TransactionTemplate<amount::NonNegative>,
|
||||||
|
VerifiedUnminedTx,
|
||||||
|
)> = mempool_txs
|
||||||
|
.into_iter()
|
||||||
|
.map(|tx| ((&tx).into(), tx))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Transaction selection returns transactions in an arbitrary order,
|
// Transaction selection returns transactions in an arbitrary order,
|
||||||
// but Zebra's snapshot tests expect the same order every time.
|
// but Zebra's snapshot tests expect the same order every time.
|
||||||
if like_zcashd {
|
if like_zcashd {
|
||||||
// Sort in serialized data order, excluding the length byte.
|
// Sort in serialized data order, excluding the length byte.
|
||||||
// `zcashd` sometimes seems to do this, but other times the order is arbitrary.
|
// `zcashd` sometimes seems to do this, but other times the order is arbitrary.
|
||||||
mempool_txs.sort_by_key(|tx| tx.data.clone());
|
mempool_txs_with_templates.sort_by_key(|(tx_template, _tx)| tx_template.data.clone());
|
||||||
} else {
|
} else {
|
||||||
// Sort by hash, this is faster.
|
// Sort by hash, this is faster.
|
||||||
mempool_txs.sort_by_key(|tx| tx.hash.bytes_in_display_order());
|
mempool_txs_with_templates
|
||||||
|
.sort_by_key(|(tx_template, _tx)| tx_template.hash.bytes_in_display_order());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (mempool_tx_templates, mempool_txs): (Vec<_>, Vec<_>) =
|
||||||
|
mempool_txs_with_templates.into_iter().unzip();
|
||||||
|
|
||||||
|
// Generate the coinbase transaction and default roots
|
||||||
|
//
|
||||||
|
// TODO: move expensive root, hash, and tree cryptography to a rayon thread?
|
||||||
|
let (coinbase_txn, default_roots) = generate_coinbase_and_roots(
|
||||||
|
network,
|
||||||
|
next_block_height,
|
||||||
|
miner_address,
|
||||||
|
&mempool_txs,
|
||||||
|
chain_tip_and_local_time.history_tree.clone(),
|
||||||
|
like_zcashd,
|
||||||
|
);
|
||||||
|
|
||||||
// Convert difficulty
|
// Convert difficulty
|
||||||
let target = chain_tip_and_local_time
|
let target = chain_tip_and_local_time
|
||||||
.expected_difficulty
|
.expected_difficulty
|
||||||
|
|
@ -228,7 +252,7 @@ impl GetBlockTemplate {
|
||||||
final_sapling_root_hash: default_roots.block_commitments_hash,
|
final_sapling_root_hash: default_roots.block_commitments_hash,
|
||||||
default_roots,
|
default_roots,
|
||||||
|
|
||||||
transactions: mempool_txs,
|
transactions: mempool_tx_templates,
|
||||||
|
|
||||||
coinbase_txn,
|
coinbase_txn,
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue