From 960e82fc67891373e1dc044f7dd518550747bea3 Mon Sep 17 00:00:00 2001 From: gaoxin Date: Tue, 26 Nov 2024 17:23:45 +0800 Subject: [PATCH] fix: a transaction may visit miner account but don't update it --- src/partition.rs | 11 +++++++++++ src/scheduler.rs | 19 +++++++++++++------ src/storage.rs | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/partition.rs b/src/partition.rs index 7fd73c4..da9a3ae 100644 --- a/src/partition.rs +++ b/src/partition.rs @@ -104,6 +104,7 @@ where pub(crate) fn execute(&mut self) { let start = Instant::now(); let coinbase = self.env.block.coinbase; + let mut committed_accumulated_rewards = 0; let mut evm = EvmBuilder::default() .with_db(&mut self.partition_db) .with_spec_id(self.spec_id) @@ -173,6 +174,16 @@ where read_set.iter().all(|l| tx_states[txid].read_set.contains_key(l.0)); skip_validation &= write_set.iter().all(|l| tx_states[txid].write_set.contains(l)); + if let Some(accumulator) = self.rewards_accumulators.get(&txid) { + let contains_miner = + write_set.contains(&LocationAndType::Basic(coinbase)); + accumulator.rewards_committed.store(contains_miner, Ordering::Release); + if contains_miner { + committed_accumulated_rewards = evm.db().accumulated_rewards; + } else { + evm.db_mut().accumulated_rewards = committed_accumulated_rewards; + } + } // temporary commit to cache_db, to make use the remaining txs can read the // updated data diff --git a/src/scheduler.rs b/src/scheduler.rs index 06b9f72..d566fe4 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -21,7 +21,10 @@ use revm::{ use std::{ collections::{BTreeMap, BTreeSet}, ops::DerefMut, - sync::{atomic::AtomicUsize, Arc, RwLock}, + sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, RwLock, + }, time::{Duration, Instant}, }; use tokio::sync::Notify; @@ -137,6 +140,7 @@ pub(crate) struct RewardsAccumulator { pub accumulate_counter: AtomicUsize, pub accumulate_rewards: Atomic, pub notifier: Arc, + pub rewards_committed: AtomicBool, } impl RewardsAccumulator { @@ -146,6 +150,7 @@ impl RewardsAccumulator { accumulate_counter: AtomicUsize::new(0), accumulate_rewards: Atomic::::new(0), notifier: Arc::new(Notify::new()), + rewards_committed: AtomicBool::new(false), } } } @@ -556,11 +561,13 @@ where let span = Span::enter_with_local_parent("database commit transitions"); let mut rewards = 0; - let rewards_start_txid = - match self.rewards_accumulators.range(..self.num_finality_txs).next_back() { - Some((txid, _)) => *txid, - None => start_txid, - }; + let mut rewards_start_txid = start_txid; + for (txid, accumulator) in self.rewards_accumulators.range(..self.num_finality_txs).rev() { + if accumulator.rewards_committed.load(Ordering::Acquire) { + rewards_start_txid = *txid; + break; + } + } for txid in start_txid..self.num_finality_txs { if txid >= rewards_start_txid { rewards += tx_states[txid].execute_result.rewards; diff --git a/src/storage.rs b/src/storage.rs index 80c54f3..f5ae12b 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -419,7 +419,7 @@ pub(crate) struct PartitionDB { pub current_txid: TxId, pub raw_transfer: bool, rewards_accumulators: Arc, - accumulated_rewards: u128, + pub accumulated_rewards: u128, } impl PartitionDB {