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 <teor@riseup.net>
This commit is contained in:
Marek 2023-09-06 09:15:18 +02:00 committed by GitHub
parent 0f704b8417
commit 0e9261c481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 35 deletions

View File

@ -849,14 +849,13 @@ pub enum ReadRequest {
/// * [`ReadResponse::OrchardTree(None)`](crate::ReadResponse::OrchardTree) otherwise. /// * [`ReadResponse::OrchardTree(None)`](crate::ReadResponse::OrchardTree) otherwise.
OrchardTree(HashOrHeight), OrchardTree(HashOrHeight),
/// Returns a list of Sapling note commitment subtrees by their indexes, /// Returns a list of Sapling note commitment subtrees by their indexes, starting at
/// starting at `start_index`, and returning up to `limit` subtrees. /// `start_index`, and returning up to `limit` subtrees.
/// ///
/// Returns /// Returns
/// ///
/// * [`ReadResponse::SaplingSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::SaplingSubtrees) /// * [`ReadResponse::SaplingSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::SaplingSubtrees)
/// /// * An empty list if there is no subtree at `start_index`.
/// If there is no subtree at `start_index`, returns an empty list.
SaplingSubtrees { SaplingSubtrees {
/// The index of the first 2^16-leaf subtree to return. /// The index of the first 2^16-leaf subtree to return.
start_index: NoteCommitmentSubtreeIndex, start_index: NoteCommitmentSubtreeIndex,
@ -864,14 +863,13 @@ pub enum ReadRequest {
limit: Option<NoteCommitmentSubtreeIndex>, limit: Option<NoteCommitmentSubtreeIndex>,
}, },
/// Returns a list of Orchard note commitment subtrees by their indexes, /// Returns a list of Orchard note commitment subtrees by their indexes, starting at
/// starting at `start_index`, and returning up to `limit` subtrees. /// `start_index`, and returning up to `limit` subtrees.
/// ///
/// Returns /// Returns
/// ///
/// * [`ReadResponse::OrchardSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::OrchardSubtrees) /// * [`ReadResponse::OrchardSubtree(BTreeMap<_, NoteCommitmentSubtreeData<_>>))`](crate::ReadResponse::OrchardSubtrees)
/// /// * An empty list if there is no subtree at `start_index`.
/// If there is no subtree at `start_index`, returns an empty list.
OrchardSubtrees { OrchardSubtrees {
/// The index of the first 2^16-leaf subtree to return. /// The index of the first 2^16-leaf subtree to return.
start_index: NoteCommitmentSubtreeIndex, start_index: NoteCommitmentSubtreeIndex,

View File

@ -49,12 +49,19 @@ where
} }
/// Returns a list of Sapling [`NoteCommitmentSubtree`]s starting at `start_index`. /// 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`, /// If `limit` is provided, the list is limited to `limit` entries. If there is no subtree at
/// the returned list is empty. Otherwise, subtrees are continuous and consistent up to the tip. /// `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. /// an inconsistent list of subtrees after concurrent non-finalized and finalized updates.
pub fn sapling_subtrees<C>( pub fn sapling_subtrees<C>(
chain: Option<C>, chain: Option<C>,
@ -65,15 +72,6 @@ pub fn sapling_subtrees<C>(
where where
C: AsRef<Chain>, C: AsRef<Chain>,
{ {
// # 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); 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. // 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`. /// 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`, /// If `limit` is provided, the list is limited to `limit` entries. If there is no subtree at
/// the returned list is empty. Otherwise, subtrees are continuous and consistent up to the tip. /// `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
/// an inconsistent list of subtrees. ///
/// 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<C>( pub fn orchard_subtrees<C>(
chain: Option<C>, chain: Option<C>,
db: &ZebraDb, db: &ZebraDb,
@ -153,15 +158,6 @@ pub fn orchard_subtrees<C>(
where where
C: AsRef<Chain>, C: AsRef<Chain>,
{ {
// # 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); 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. // If there's no chain, then we have the complete list.