Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2. change(state): Run AwaitUtxo read requests without shared mutable chain state #5107

Merged
merged 16 commits into from
Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion zebra-rpc/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ where
data: None,
})?;
let utxos = match response {
zebra_state::ReadResponse::Utxos(utxos) => utxos,
zebra_state::ReadResponse::AddressUtxos(utxos) => utxos,
_ => unreachable!("unmatched response to a UtxosByAddresses request"),
};

Expand Down
34 changes: 29 additions & 5 deletions zebra-state/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,11 @@ pub enum Request {
/// [`block::Height`] using `.into()`.
Block(HashOrHeight),

/// Request a UTXO identified by the given
/// [`OutPoint`](transparent::OutPoint), waiting until it becomes available
/// if it is unknown.
/// Request a UTXO identified by the given [`OutPoint`](transparent::OutPoint),
/// waiting until it becomes available if it is unknown.
///
/// Checks the finalized chain, all non-finalized chains, queued unverified blocks,
/// and any blocks that arrive at the state after the request future has been created.
///
/// This request is purely informational, and there are no guarantees about
/// whether the UTXO remains unspent or is on the best chain, or any chain.
Expand All @@ -458,6 +460,8 @@ pub enum Request {
/// UTXO requests should be wrapped in a timeout, so that
/// out-of-order and invalid requests do not hang indefinitely. See the [`crate`]
/// documentation for details.
///
/// Outdated requests are pruned on a regular basis.
AwaitUtxo(transparent::OutPoint),

/// Finds the first hash that's in the peer's `known_blocks` and the local best chain.
Expand Down Expand Up @@ -542,6 +546,24 @@ pub enum ReadRequest {
/// * [`ReadResponse::Transaction(None)`](ReadResponse::Transaction) otherwise.
Transaction(transaction::Hash),

/// Looks up a UTXO identified by the given [`OutPoint`](transparent::OutPoint),
/// returning `None` immediately if it is unknown.
///
/// Checks verified blocks in the finalized chain and the _best_ non-finalized chain.
///
/// This request is purely informational, there is no guarantee that
/// the UTXO remains unspent in the best chain.
BestChainUtxo(transparent::OutPoint),

/// Looks up a UTXO identified by the given [`OutPoint`](transparent::OutPoint),
/// returning `None` immediately if it is unknown.
///
/// Checks verified blocks in the finalized chain and _all_ non-finalized chains.
///
/// This request is purely informational, there is no guarantee that
/// the UTXO remains unspent in the best chain.
AnyChainUtxo(transparent::OutPoint),

/// Computes a block locator object based on the current best chain.
///
/// Returns [`ReadResponse::BlockLocator`] with hashes starting
Expand Down Expand Up @@ -662,8 +684,6 @@ impl TryFrom<Request> for ReadRequest {
Request::Block(hash_or_height) => Ok(ReadRequest::Block(hash_or_height)),
Request::Transaction(tx_hash) => Ok(ReadRequest::Transaction(tx_hash)),

Request::AwaitUtxo(_) => unimplemented!("use StoredUtxo here"),

Request::BlockLocator => Ok(ReadRequest::BlockLocator),
Request::FindBlockHashes { known_blocks, stop } => {
Ok(ReadRequest::FindBlockHashes { known_blocks, stop })
Expand All @@ -675,6 +695,10 @@ impl TryFrom<Request> for ReadRequest {
Request::CommitBlock(_) | Request::CommitFinalizedBlock(_) => {
Err("ReadService does not write blocks")
}

Request::AwaitUtxo(_) => Err("ReadService does not track pending UTXOs. \
Manually convert the request to ReadRequest::AnyChainUtxo, \
and handle pending UTXOs"),
}
}
}
37 changes: 28 additions & 9 deletions zebra-state/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ pub enum Response {
/// Response to [`Request::Block`] with the specified block.
Block(Option<Arc<Block>>),

/// The response to a `AwaitUtxo` request.
/// The response to a `AwaitUtxo` request, from any non-finalized chains, finalized chain,
/// pending unverified blocks, or blocks received after the request was sent.
Utxo(transparent::Utxo),

/// The response to a `FindBlockHashes` request.
Expand Down Expand Up @@ -75,6 +76,20 @@ pub enum ReadResponse {
/// The response to a `FindBlockHeaders` request.
BlockHeaders(Vec<block::CountedHeader>),

/// The response to a `BestChainUtxo` request, from verified blocks in the
/// _best_ non-finalized chain, or the finalized chain.
///
/// This response is purely informational, there is no guarantee that
/// the UTXO remains unspent in the best chain.
BestChainUtxo(Option<transparent::Utxo>),

/// The response to an `AnyChainUtxo` request, from verified blocks in
/// _any_ non-finalized chain, or the finalized chain.
///
/// This response is purely informational, there is no guarantee that
/// the UTXO remains unspent in the best chain.
AnyChainUtxo(Option<transparent::Utxo>),

/// Response to [`ReadRequest::SaplingTree`] with the specified Sapling note commitment tree.
SaplingTree(Option<Arc<sapling::tree::NoteCommitmentTree>>),

Expand All @@ -89,7 +104,7 @@ pub enum ReadResponse {
AddressesTransactionIds(BTreeMap<TransactionLocation, transaction::Hash>),

/// Response to [`ReadRequest::UtxosByAddresses`] with found utxos and transaction data.
Utxos(AddressUtxos),
AddressUtxos(AddressUtxos),
}

/// Conversion from read-only [`ReadResponse`]s to read-write [`Response`]s.
Expand All @@ -108,17 +123,21 @@ impl TryFrom<ReadResponse> for Response {
Ok(Response::Transaction(tx_and_height.map(|(tx, _height)| tx)))
}

ReadResponse::AnyChainUtxo(_) => Err("ReadService does not track pending UTXOs. \
Manually unwrap the response, and handle pending UTXOs."),

ReadResponse::BlockLocator(hashes) => Ok(Response::BlockLocator(hashes)),
ReadResponse::BlockHashes(hashes) => Ok(Response::BlockHashes(hashes)),
ReadResponse::BlockHeaders(headers) => Ok(Response::BlockHeaders(headers)),

ReadResponse::SaplingTree(_) => unimplemented!(),
ReadResponse::OrchardTree(_) => unimplemented!(),

ReadResponse::AddressBalance(_) => unimplemented!(),
ReadResponse::AddressesTransactionIds(_) => unimplemented!(),
// TODO: Rename to AddressUtxos
ReadResponse::Utxos(_) => unimplemented!(),
ReadResponse::BestChainUtxo(_)
| ReadResponse::SaplingTree(_)
| ReadResponse::OrchardTree(_)
| ReadResponse::AddressBalance(_)
| ReadResponse::AddressesTransactionIds(_)
| ReadResponse::AddressUtxos(_) => {
Err("there is no corresponding Response for this ReadResponse")
}
}
}
}
Loading