zebra_rpc/methods/types/
default_roots.rs1use std::iter;
4
5use derive_getters::Getters;
6use derive_new::new;
7use zebra_chain::{
8 amount::NegativeOrZero,
9 block::{
10 self,
11 merkle::{self, AuthDataRoot, AUTH_DIGEST_PLACEHOLDER},
12 ChainHistoryBlockTxAuthCommitmentHash, ChainHistoryMmrRootHash, Height,
13 },
14 parameters::{Network, NetworkUpgrade},
15 transaction::VerifiedUnminedTx,
16};
17
18use crate::client::TransactionTemplate;
19
20#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, Getters, new)]
25pub struct DefaultRoots {
26 #[serde(rename = "merkleroot")]
29 #[serde(with = "hex")]
30 #[getter(copy)]
31 pub(crate) merkle_root: merkle::Root,
32
33 #[serde(rename = "chainhistoryroot")]
36 #[serde(with = "hex")]
37 #[getter(copy)]
38 pub(crate) chain_history_root: ChainHistoryMmrRootHash,
39
40 #[serde(rename = "authdataroot")]
42 #[serde(with = "hex")]
43 #[getter(copy)]
44 pub(crate) auth_data_root: AuthDataRoot,
45
46 #[serde(rename = "blockcommitmentshash")]
51 #[serde(with = "hex")]
52 #[getter(copy)]
53 pub(crate) block_commitments_hash: ChainHistoryBlockTxAuthCommitmentHash,
54}
55
56impl DefaultRoots {
57 pub fn from_coinbase(
59 net: &Network,
60 height: Height,
61 coinbase: &TransactionTemplate<NegativeOrZero>,
62 chain_history_root: Option<ChainHistoryMmrRootHash>,
63 mempool_txs: &[VerifiedUnminedTx],
64 ) -> Self {
65 let chain_history_root = chain_history_root
66 .or_else(|| {
67 (NetworkUpgrade::Heartwood.activation_height(net) == Some(height))
68 .then_some(block::CHAIN_HISTORY_ACTIVATION_RESERVED.into())
69 })
70 .expect("history root is required for block templates");
71
72 let auth_data_root = iter::once(coinbase.auth_digest)
77 .chain(mempool_txs.iter().map(|tx| {
78 tx.transaction
79 .id
80 .auth_digest()
81 .unwrap_or(AUTH_DIGEST_PLACEHOLDER)
82 }))
83 .collect();
84
85 Self {
86 merkle_root: iter::once(coinbase.hash)
87 .chain(mempool_txs.iter().map(|tx| tx.transaction.id.mined_id()))
88 .collect(),
89 chain_history_root,
90 auth_data_root,
91 block_commitments_hash: if NetworkUpgrade::current(net, height)
92 == NetworkUpgrade::Heartwood
93 && chain_history_root == block::CHAIN_HISTORY_ACTIVATION_RESERVED.into()
94 {
95 block::CHAIN_HISTORY_ACTIVATION_RESERVED.into()
96 } else {
97 ChainHistoryBlockTxAuthCommitmentHash::from_commitments(
98 &chain_history_root,
99 &auth_data_root,
100 )
101 },
102 }
103 }
104}