From 8f437c5a4a76c07be2848f4ffb890b6c62c1a327 Mon Sep 17 00:00:00 2001 From: James Hinshelwood Date: Fri, 13 Sep 2024 08:12:45 +0100 Subject: [PATCH] Apply state changes in a database transaction (#1445) I'm hoping this avoids us making incomplete mutations to the state trie, leading to inconsistent data. From my limited local testing, it appears to make the problem go away. --- CHANGELOG.md | 1 + zilliqa/src/db.rs | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 351a2c7a2..ae2b53345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Unreleased changes, in reverse chronological order. New entries are added at the top of this list. +- [#1445](https://github.com/Zilliqa/zq2/pull/1445): Apply state changes from transactions atomically. - [#1448](https://github.com/Zilliqa/zq2/pull/1448): Fail gracefully if we are unable to parse a gossipsub message. - [#1423](https://github.com/Zilliqa/zq2/pull/1423): Fix invalid value returned by calling `_balance` in a scilla transition. diff --git a/zilliqa/src/db.rs b/zilliqa/src/db.rs index f1f0f8b39..84a697737 100644 --- a/zilliqa/src/db.rs +++ b/zilliqa/src/db.rs @@ -18,7 +18,7 @@ use rusqlite::{ Connection, OptionalExtension, Row, ToSql, }; use serde::{Deserialize, Serialize}; -use sled::{Batch, Tree}; +use sled::{transaction::TransactionError, Batch, Tree}; use tracing::warn; use crate::{ @@ -888,7 +888,19 @@ impl eth_trie::DB for TrieStorage { for (key, value) in keys.into_iter().zip(values) { batch.insert(key, value); } - self.db.apply_batch(batch)?; + if let Err(e) = self.db.transaction(|db| { + db.apply_batch(&batch)?; + Ok(()) + }) { + match e { + TransactionError::Abort(()) => { + unreachable!("we don't call `abort` during this transaction") + } + TransactionError::Storage(e) => { + return Err(e); + } + } + } Ok(()) }