From 0e9261c481fab712086ec7e93f15f6a5ea168bdc Mon Sep 17 00:00:00 2001 From: Marek Date: Wed, 6 Sep 2023 09:15:18 +0200 Subject: [PATCH] change(state): Refactor docs for `z_getsubtreesbyindex` RPC state requests (#7462) * Refactor some comments for subtrees * Update docs about single subtree APIs * Fix method rename in tree.rs --------- Co-authored-by: teor --- zebra-state/src/request.rs | 14 ++++---- zebra-state/src/service/read/tree.rs | 50 +++++++++++++--------------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/zebra-state/src/request.rs b/zebra-state/src/request.rs index 81bb07d9a..700814ae1 100644 --- a/zebra-state/src/request.rs +++ b/zebra-state/src/request.rs @@ -849,14 +849,13 @@ pub enum ReadRequest { /// * [`ReadResponse::OrchardTree(None)`](crate::ReadResponse::OrchardTree) otherwise. OrchardTree(HashOrHeight), - /// Returns a list of Sapling note commitment subtrees by their indexes, - /// starting at `start_index`, and returning up to `limit` subtrees. + /// Returns a list of Sapling note commitment subtrees by their indexes, starting at + /// `start_index`, and returning up to `limit` subtrees. /// /// Returns /// /// * [`ReadResponse::SaplingSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::SaplingSubtrees) - /// - /// If there is no subtree at `start_index`, returns an empty list. + /// * An empty list if there is no subtree at `start_index`. SaplingSubtrees { /// The index of the first 2^16-leaf subtree to return. start_index: NoteCommitmentSubtreeIndex, @@ -864,14 +863,13 @@ pub enum ReadRequest { limit: Option, }, - /// Returns a list of Orchard note commitment subtrees by their indexes, - /// starting at `start_index`, and returning up to `limit` subtrees. + /// Returns a list of Orchard note commitment subtrees by their indexes, starting at + /// `start_index`, and returning up to `limit` subtrees. /// /// Returns /// /// * [`ReadResponse::OrchardSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::OrchardSubtrees) - /// - /// If there is no subtree at `start_index`, returns an empty list. + /// * An empty list if there is no subtree at `start_index`. OrchardSubtrees { /// The index of the first 2^16-leaf subtree to return. start_index: NoteCommitmentSubtreeIndex, diff --git a/zebra-state/src/service/read/tree.rs b/zebra-state/src/service/read/tree.rs index 759952496..3be272477 100644 --- a/zebra-state/src/service/read/tree.rs +++ b/zebra-state/src/service/read/tree.rs @@ -49,12 +49,19 @@ where } /// Returns a list of Sapling [`NoteCommitmentSubtree`]s starting at `start_index`. -/// If `limit` is provided, the list is limited to `limit` entries. /// -/// If there is no subtree at `start_index` in the non-finalized `chain` or finalized `db`, -/// the returned list is empty. Otherwise, subtrees are continuous and consistent up to the tip. +/// If `limit` is provided, the list is limited to `limit` entries. If there is no subtree at +/// `start_index` in the non-finalized `chain` or finalized `db`, the returned list is empty. /// -/// There is no API for retrieving single subtrees, because it can accidentally be used to create +/// # Correctness +/// +/// 1. After `chain` was cloned, the StateService can commit additional blocks to the finalized +/// state `db`. Usually, the subtrees of these blocks are consistent. But if the `chain` is a +/// different fork to `db`, then the trees can be inconsistent. In that case, we ignore all the +/// trees in `chain` after the first inconsistent tree, because we know they will be inconsistent as +/// well. (It is cryptographically impossible for tree roots to be equal once the leaves have +/// diverged.) +/// 2. APIs that return single subtrees can't be used here, because they can create /// an inconsistent list of subtrees after concurrent non-finalized and finalized updates. pub fn sapling_subtrees( chain: Option, @@ -65,15 +72,6 @@ pub fn sapling_subtrees( where C: AsRef, { - // # Correctness - // - // After `chain` was cloned, the StateService can commit additional blocks to the finalized - // state `db`. Usually, the subtrees of these blocks are consistent. But if the `chain` is - // a different fork to `db`, then the trees can be inconsistent. - // - // In that case, we ignore all the trees in `chain` after the first inconsistent tree, - // because we know they will be inconsistent as well. (It is cryptographically impossible - // for tree roots to be equal once the leaves have diverged.) let mut db_list = db.sapling_subtree_list_by_index_for_rpc(start_index, limit); // If there's no chain, then we have the complete list. @@ -137,13 +135,20 @@ where } /// Returns a list of Orchard [`NoteCommitmentSubtree`]s starting at `start_index`. -/// If `limit` is provided, the list is limited to `limit` entries. /// -/// If there is no subtree at `start_index` in the non-finalized `chain` or finalized `db`, -/// the returned list is empty. Otherwise, subtrees are continuous and consistent up to the tip. +/// If `limit` is provided, the list is limited to `limit` entries. If there is no subtree at +/// `start_index` in the non-finalized `chain` or finalized `db`, the returned list is empty. /// -/// There is no API for retrieving single subtrees, because it can accidentally be used to create -/// an inconsistent list of subtrees. +/// # Correctness +/// +/// 1. After `chain` was cloned, the StateService can commit additional blocks to the finalized +/// state `db`. Usually, the subtrees of these blocks are consistent. But if the `chain` is a +/// different fork to `db`, then the trees can be inconsistent. In that case, we ignore all the +/// trees in `chain` after the first inconsistent tree, because we know they will be inconsistent as +/// well. (It is cryptographically impossible for tree roots to be equal once the leaves have +/// diverged.) +/// 2. APIs that return single subtrees can't be used here, because they can create +/// an inconsistent list of subtrees after concurrent non-finalized and finalized updates. pub fn orchard_subtrees( chain: Option, db: &ZebraDb, @@ -153,15 +158,6 @@ pub fn orchard_subtrees( where C: AsRef, { - // # Correctness - // - // After `chain` was cloned, the StateService can commit additional blocks to the finalized - // state `db`. Usually, the subtrees of these blocks are consistent. But if the `chain` is - // a different fork to `db`, then the trees can be inconsistent. - // - // In that case, we ignore all the trees in `chain` after the first inconsistent tree, - // because we know they will be inconsistent as well. (It is cryptographically impossible - // for tree roots to be equal once the leaves have diverged.) let mut db_list = db.orchard_subtree_list_by_index_for_rpc(start_index, limit); // If there's no chain, then we have the complete list.