fix: deadlock on StaticFileProvider::get_writer (#10069)

Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com>
This commit is contained in:
Federico Gimenez
2024-08-05 16:12:36 +02:00
committed by GitHub
parent cea8b7a9b1
commit 444c7a961e
2 changed files with 21 additions and 11 deletions

View File

@ -290,7 +290,12 @@ mod tests {
persistence_handle.save_blocks(blocks, tx).unwrap();
let actual_hash = rx.await.unwrap().unwrap();
let actual_hash = tokio::time::timeout(std::time::Duration::from_secs(10), rx)
.await
.expect("test timed out")
.expect("channel closed unexpectedly")
.expect("no hash returned");
assert_eq!(block_hash, actual_hash);
}

View File

@ -155,16 +155,6 @@ where
let first_number = first_block.number;
let last_block_number = last_block.number;
// Only write receipts to static files if there is no receipt pruning configured.
let mut state_writer = if self.database().prune_modes_ref().has_receipts_pruning() {
UnifiedStorageWriter::from_database(self.database())
} else {
UnifiedStorageWriter::from(
self.database(),
self.static_file().get_writer(first_block.number, StaticFileSegment::Receipts)?,
)
};
debug!(target: "provider::storage_writer", block_count = %blocks.len(), "Writing blocks and execution data to storage");
// TODO: remove all the clones and do performant / batched writes for each type of object
@ -185,6 +175,21 @@ where
// Write state and changesets to the database.
// Must be written after blocks because of the receipt lookup.
let execution_outcome = block.execution_outcome().clone();
// Only write receipts to static files if there is no receipt pruning configured.
let mut state_writer = if self.database().prune_modes_ref().has_receipts_pruning() {
UnifiedStorageWriter::from_database(self.database())
} else {
// This should be inside the hotloop, because preferably there should only be one
// mutable reference to a static file writer, since there's a 3 in 100 chance that
// another segment shares the same shard as the `Receipts` one. Which would result
// in a deadlock.
UnifiedStorageWriter::from(
self.database(),
self.static_file()
.get_writer(first_block.number, StaticFileSegment::Receipts)?,
)
};
state_writer.write_to_storage(execution_outcome, OriginalValuesKnown::No)?;
// insert hashes and intermediate merkle nodes