Skip to content

Commit 2a72ef1

Browse files
authored
Merge pull request #3316 from Conflux-Chain/pos_reward
fix: check if the pos reward in DB is on pivot for reexecution.
2 parents f23b8e0 + acb8d48 commit 2a72ef1

File tree

2 files changed

+44
-13
lines changed
  • crates/cfxcore/core/src
    • block_data_manager
    • consensus/consensus_inner/consensus_executor

2 files changed

+44
-13
lines changed

crates/cfxcore/core/src/block_data_manager/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,39 @@ impl BlockDataManager {
13441344
}
13451345
let me_height = self.block_height_by_hash(epoch_hash).unwrap();
13461346
if pos_verifier.pos_option().is_some() && me_height != 0 {
1347+
// Check if stored pos reward is on pivot.
1348+
let pivot_block_header = self
1349+
.block_header_by_hash(epoch_hash)
1350+
.expect("header exists");
1351+
let maybe_parent_pos_ref = self
1352+
.block_header_by_hash(&pivot_block_header.parent_hash()) // `None` only for genesis.
1353+
.and_then(|parent| parent.pos_reference().clone());
1354+
if pos_verifier.is_enabled_at_height(me_height)
1355+
&& maybe_parent_pos_ref.is_some()
1356+
&& maybe_parent_pos_ref != *pivot_block_header.pos_reference()
1357+
{
1358+
if let Some((pos_epoch, _)) = pos_verifier
1359+
.get_reward_distribution_event(
1360+
pivot_block_header.pos_reference().as_ref().unwrap(),
1361+
maybe_parent_pos_ref.as_ref().unwrap(),
1362+
)
1363+
.as_ref()
1364+
.and_then(|x| x.first())
1365+
{
1366+
if let Some(pos_reward) =
1367+
self.pos_reward_by_pos_epoch(*pos_epoch)
1368+
{
1369+
if pos_reward.execution_epoch_hash != *epoch_hash {
1370+
// The stored pos reward is executed in another
1371+
// epoch, so we need to
1372+
// reexecute this epoch to restore the pos reward of
1373+
// the current pivot.
1374+
return false;
1375+
}
1376+
}
1377+
}
1378+
}
1379+
13471380
trace!(
13481381
"staking events update: height={}, new={}",
13491382
me_height,

crates/cfxcore/core/src/consensus/consensus_inner/consensus_executor/mod.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,8 @@ impl ConsensusExecutionHandler {
10141014
self.data_man
10151015
.insert_hash_by_block_number(block_number, hash);
10161016
}
1017+
let end_block_number =
1018+
start_block_number + epoch_block_hashes.len() as u64 - 1;
10171019

10181020
let pivot_block_header = self
10191021
.data_man
@@ -1071,13 +1073,10 @@ impl ConsensusExecutionHandler {
10711073
// program may restart by itself.
10721074
.expect("Can not handle db error in consensus, crashing.");
10731075

1074-
let current_block_number =
1075-
start_block_number + epoch_receipts.len() as u64 - 1;
1076-
10771076
if let Some(reward_execution_info) = reward_execution_info {
10781077
let spec = self
10791078
.machine
1080-
.spec(current_block_number, pivot_block.block_header.height());
1079+
.spec(end_block_number, pivot_block.block_header.height());
10811080
// Calculate the block reward for blocks inside the epoch
10821081
// All transaction fees are shared among blocks inside one epoch
10831082
self.process_rewards_and_fees(
@@ -1092,8 +1091,8 @@ impl ConsensusExecutionHandler {
10921091

10931092
self.process_pos_interest(
10941093
&mut state,
1095-
pivot_block,
1096-
current_block_number,
1094+
&pivot_block.block_header,
1095+
end_block_number,
10971096
)
10981097
.expect("db error");
10991098

@@ -1162,23 +1161,22 @@ impl ConsensusExecutionHandler {
11621161
}
11631162

11641163
fn process_pos_interest(
1165-
&self, state: &mut State, pivot_block: &Block,
1164+
&self, state: &mut State, pivot_header: &BlockHeader,
11661165
current_block_number: u64,
11671166
) -> DbResult<()> {
11681167
// TODO(peilun): Specify if we unlock before or after executing the
11691168
// transactions.
11701169
let maybe_parent_pos_ref = self
11711170
.data_man
1172-
.block_header_by_hash(&pivot_block.block_header.parent_hash()) // `None` only for genesis.
1171+
.block_header_by_hash(&pivot_header.parent_hash()) // `None` only for genesis.
11731172
.and_then(|parent| parent.pos_reference().clone());
11741173
if self
11751174
.pos_verifier
1176-
.is_enabled_at_height(pivot_block.block_header.height())
1175+
.is_enabled_at_height(pivot_header.height())
11771176
&& maybe_parent_pos_ref.is_some()
1178-
&& *pivot_block.block_header.pos_reference() != maybe_parent_pos_ref
1177+
&& *pivot_header.pos_reference() != maybe_parent_pos_ref
11791178
{
1180-
let current_pos_ref = pivot_block
1181-
.block_header
1179+
let current_pos_ref = pivot_header
11821180
.pos_reference()
11831181
.as_ref()
11841182
.expect("checked before sync graph insertion");
@@ -1208,7 +1206,7 @@ impl ConsensusExecutionHandler {
12081206
)?;
12091207
self.data_man.insert_pos_reward(
12101208
*pos_epoch,
1211-
&PosRewardInfo::new(account_rewards, pivot_block.hash()),
1209+
&PosRewardInfo::new(account_rewards, pivot_header.hash()),
12121210
)
12131211
}
12141212
}

0 commit comments

Comments
 (0)