fix(concurrency): Use Arc::into_inner() to avoid potential concurrency issues, needs Rust 1.70 (#7032)

* Use Arc::into_inner() to avoid potential concurrency issues

* Remove some outdated clippy lint workarounds (fixed in Rust 1.66)

* Update the required Rust version to 1.70
This commit is contained in:
teor 2023-06-22 06:44:53 +10:00 committed by GitHub
parent 006c2ae42b
commit 3d2c5ef290
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 12 additions and 18 deletions

View File

@ -269,9 +269,6 @@ impl ZcashDeserialize for Flags {
// Consensus rule: "In a version 5 transaction,
// the reserved bits 2..7 of the flagsOrchard field MUST be zero."
// https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus
//
// Clippy 1.64 is wrong here, this lazy evaluation is necessary, constructors are functions. This is fixed in 1.66.
#[allow(clippy::unnecessary_lazy_evaluations)]
Flags::from_bits(reader.read_u8()?)
.ok_or_else(|| SerializationError::Parse("invalid reserved orchard flags"))
}

View File

@ -884,9 +884,6 @@ impl ZcashDeserialize for Transaction {
}
// Denoted as `nConsensusBranchId` in the spec.
// Convert it to a NetworkUpgrade
//
// Clippy 1.64 is wrong here, this lazy evaluation is necessary, constructors are functions. This is fixed in 1.66.
#[allow(clippy::unnecessary_lazy_evaluations)]
let network_upgrade =
NetworkUpgrade::from_branch_id(limited_reader.read_u32::<LittleEndian>()?)
.ok_or_else(|| {

View File

@ -280,7 +280,7 @@ where
check::miner_fees_are_valid(&block, network, block_miner_fees)?;
// Finally, submit the block for contextual verification.
let new_outputs = Arc::try_unwrap(known_utxos)
let new_outputs = Arc::into_inner(known_utxos)
.expect("all verification tasks using known_utxos are complete");
let prepared_block = zs::SemanticallyVerifiedBlock {

View File

@ -500,8 +500,6 @@ impl Codec {
/// Note: zcashd only requires fields up to `address_recv`, but everything up to `relay` is required in Zebra.
/// see <https://github.com/zcash/zcash/blob/11d563904933e889a11d9685c3b249f1536cfbe7/src/main.cpp#L6490-L6507>
fn read_version<R: Read>(&self, mut reader: R) -> Result<Message, Error> {
// Clippy 1.64 is wrong here, this lazy evaluation is necessary, constructors are functions. This is fixed in 1.66.
#[allow(clippy::unnecessary_lazy_evaluations)]
Ok(VersionMessage {
version: Version(reader.read_u32::<LittleEndian>()?),
// Use from_bits_truncate to discard unknown service bits.

View File

@ -269,7 +269,7 @@ impl Drop for ReadStateService {
// so dropping it should check if we can shut down.
if let Some(block_write_task) = self.block_write_task.take() {
if let Ok(block_write_task_handle) = Arc::try_unwrap(block_write_task) {
if let Some(block_write_task_handle) = Arc::into_inner(block_write_task) {
// We're the last database user, so we can tell it to shut down (blocking):
// - flushes the database to disk, and
// - drops the database, which cleans up any database tasks correctly.
@ -1165,15 +1165,11 @@ impl Service<ReadRequest> for ReadStateService {
if let Some(block_write_task) = block_write_task {
if block_write_task.is_finished() {
match Arc::try_unwrap(block_write_task) {
if let Some(block_write_task) = Arc::into_inner(block_write_task) {
// We are the last state with a reference to this task, so we can propagate any panics
Ok(block_write_task_handle) => {
if let Err(thread_panic) = block_write_task_handle.join() {
std::panic::resume_unwind(thread_panic);
}
if let Err(thread_panic) = block_write_task.join() {
std::panic::resume_unwind(thread_panic);
}
// We're not the last state, so we need to put it back
Err(arc_block_write_task) => self.block_write_task = Some(arc_block_write_task),
}
} else {
// It hasn't finished, so we need to put it back

View File

@ -399,6 +399,8 @@ impl NonFinalizedState {
// Pushing a block onto a Chain can launch additional parallel batches.
// TODO: should we pass _scope into Chain::push()?
scope.spawn_fifo(|_scope| {
// TODO: Replace with Arc::unwrap_or_clone() when it stabilises:
// https://github.com/rust-lang/rust/issues/93610
let new_chain = Arc::try_unwrap(new_chain)
.unwrap_or_else(|shared_chain| (*shared_chain).clone());
chain_push_result = Some(new_chain.push(contextual).map(Arc::new));

View File

@ -15,6 +15,10 @@ keywords = ["zebra", "zcash"]
# Must be one of <https://crates.io/category_slugs>
categories = ["command-line-utilities", "cryptography::cryptocurrencies"]
# Zebra is only supported on the latest stable Rust version. See the README for details.
# Any Zebra release can break compatibility with older Rust versions.
rust-version = "1.70"
[[bin]]
name = "zebra-checkpoints"
# this setting is required for Zebra's Docker build caches

View File

@ -19,7 +19,7 @@ edition = "2021"
# Zebra is only supported on the latest stable Rust version. See the README for details.
# Any Zebra release can break compatibility with older Rust versions.
rust-version = "1.66"
rust-version = "1.70"
# Settings that impact runtime behaviour